How to import and export between FEniCS and MATLAB?

Here is the problem:

  1. In MATLAB (version R2019a), I have a function that spits out 100 (x,y) tuples. I need to import these 100 (x,y) values to FEniCS.

  2. In FEniCS, as I refine my mesh, I want to export the mesh coordinates to MATLAB for some calculations on those coordinates.

In general, I am wondering if there is a way for FEniCS to communicate with MATLAB dynamically, i.e., if I have a for loop in FEniCS that is refining the mesh in each loop, how to export the refined mesh coordinates to MATLAB, do calculations in MATLAB, and import the results to FEniCS for each loop?

Any help with this will be great.

I tried my best to explain the situation. In case it is not clear, please let me know.

I would like some more information about your use-case:

  1. How does the 100 (x, y) tuples relate to a mesh, i.e. these are 100 cordinates, but what set of coordinates makes up each cell?
  2. To export the mesh, you can simply access mesh.coordinates(), and mesh.cells() to get the geometry and topology of the mesh. You can then choose to export it however you would like to.

Hi @dokken ,

My apologies for not explaining it further. Here is what I mean:

I am not sure what you mean by “but what set of coordinates makes up each cell?”.

  1. Suppose I mesh an annulus with 1000 nodes. For each of these nodes, MATLAB will return a vector, for which first I need to export the mesh coordinates to MATLAB, find the vectors corresponding to each of the nodes in MATLAB, import them back to FEniCS for some further calculations.

  2. To complicate matter, let’s suppose I have a for loop of length 100 and for each of these loops, I am refining the mesh. Suppose the original mesh has 1000 nodes, on the first refinement it has 2000 nodes (this is not exact, on refinement the number of nodes will be much more than 2000), on the second refinement, it becomes 3000 and so on for 100 steps. For each of these refinements, I need to export the mesh coordinates to MATLAB, find vector corresponding to each of these nodes in MATLAB, import them back to FEniCS. Now this cannot be done manually for 100 times. So I need a strategy to do it within the for loop.

Please let me know if this explains.

A mesh consists of two things:

  • The geometry: That is the set of coordinates making up the nodes (vertices) in the mesh.
  • The topology: That is an array of size (number_of_cells times number_of_vertices) that tells you which nodes in the geometry makes up every cell.

Consider the following toy problem:

from dolfin import UnitSquareMesh
mesh = UnitSquareMesh(1, 1)
print(f"Geometry: {mesh.coordinates()}")
print(f"Topology: {mesh.cells()}")

This gives you the following output:

Geometry: [[ 0.  0.]
 [ 1.  0.]
 [ 0.  1.]
 [ 1.  1.]]
Topology: [[0 1 3]
 [0 2 3]]

Which tells you the the mesh has in total four vertices, where the i-th row of the geometry corresponds to the i-th vertex. It also tells you that the first cell in the mesh is defined by the 0th, 1st and 3rd coordinate in the geometry, while the second one is defined by the 0th, 2nd and 3rd coordinate in the geometry.

With your current description, it is not clear which nodes makes up the different cells in dolfin, and thus it is unclear how you can use it for refining.

I would suggest you make a toy problem (say 2 x 2) unit square, present what you want as input and what you expect as output. Without this information, it is very tricky to give you any further guidance.

1 Like

Hi @dokken ,

Here is a toy problem:

import matplotlib.pyplot as plt
from fenics import *
from dolfin import UnitSquareMesh
mesh = UnitSquareMesh(1, 1)
plot(mesh)
plt.show()
print(f"Geometry: {mesh.coordinates()}")
print(f"Topology: {mesh.cells()}")

C = as_matrix([[2.0,1.0],[3.0,4.0]]) 

for i in range(0,len(mesh.coordinates())):
  mesh1=refine(mesh)
  plot(mesh1)
  plt.show()
  print(f"Geometry: {mesh1.coordinates()}")  # This is the list I need to export to MATLAB for each iteration of the loop.
  print(f"Topology: {mesh1.cells()}")
  b = mesh1.coordinates()[i]                  # This b is calculated in MATLAB; this is not how b is calculated. It's just for the example.
                                              # But this b will be calculated from the mesh coordinates of the mesh.
                                              # For each of the mesh coordinates, there will be a b associated to it.
  b_vector = (b.T)*C 
  mesh = mesh1
  
  
# The desired output is b_vector which is from MATLAB. For that I need to export the 
# mesh coodinates after each refinement to MATLAB, calculate my b, and import
# it back to FEniCS to get the b_vector.

Let me know if you need any other info.

As you have identified what you Need to communicate between the two softwares (i.e. the coordinates and the vector b, i would suggest having a look at: Using MATLAB with Python - MATLAB & Simulink

Thank you for the link. I will give it a try.

I will get back to you in case there is any problem.