Importing/Exporting data structures¶
PyFreeFEM automates conversion and exchange of FreeFEM and python data structures. The data structures that are supported are listed in the following correspondence table:
python |
FreeFEM |
|---|---|
float number |
real number |
numpy.array |
real[int] array complex[int] array |
integer numpy.array (dtype=int) |
int[int] array |
scipy.sparse matrices (csc, csr, lil types…) |
sparse matrix matrix<complex> |
numpy.ndarray (two dimensional array) |
real[int,int] array complex[int,int] array |
pymedit.Mesh |
mesh |
pymedit.Mesh3D |
mesh3 |
These data are automatically converted when exported or imported from one language to the other with automated reading and writing operations in temporary files.
Mesh data structures
Meshes are exported from FreeFEM into python with the Mesh and Mesh3D objects implemented in the pymedit library. pymedit enables to manipulate triangular/tetrahedral meshes and solution data following the INRIA mesh format.
Exporting FreeFEM data into Python¶
Exporting FreeFEM data is done from the .edp script
by using the macros exportVar, exportArray, exportIntArray,
exportComplexArray,
export2DArray, exportComplex2DArray,
exportMatrix, exportComplexMatrix,
exportMesh and exportMesh3D implemented in
pyfreefem/edp/io.edp.
These macros still require the special preprocessing instruction
IMPORT "io.edp" at the beginning of the .edp script.
IMPORT "io.edp"
real var = pi;
real[int] arr = [1,2,3,4];
mesh Th = square(10,10);
fespace Fh1(Th,P1);
varf laplace(u,v) = int2d(Th)(u*v+dx(u)*dx(v)+dy(u)*dy(v));
varf rhs(u,v) = int1d(Th,1)(v);
matrix A = laplace(Fh1,Fh1);
real[int] f= rhs(0,Fh1);
real[int] u=A^-1*f;
complex[int] arrCpx = [1+1i,2+1i,3];
real[int,int] B = [[1,2,3],[4,5,6]];
complex[int,int] Bcpx = [[1+1i,2+2i,3],[4,5,6+1i]];
dispVar(var);
exportVar(var);
export2DArray(B);
exportMesh(Th);
exportArray(arr);
export2DArray(B);
exportArray(f);
exportArray(u);
exportMatrix(A);
exportComplexMatrix(Acpx);
exportComplexArray(arrCpx);
exportComplex2DArray(Bcpx);
The execute() method returns a dictionary containing the exported data
structures.
from pyfreefem import FreeFemRunner
exports = FreeFemRunner("ex10_io_export.edp").execute()
exports['Th'].plot(title="mesh Th",bcEdgeLabels=True)
print('var='+str(exports['var']))
print('A=',exports['A'])
print('f=',exports['f'])
print('arr='+str(exports['arr']))
print('arrCpx=',exports['arrCpx'])
print('B=',exports['B'])
print('Bcpx=',exports['Bcpx'])
print('f=',exports['f'])
Running this script should show the following output and figure:
$ python ex10_io_export.py
var=3.141592653589793
arr=[1. 2. 3. 4.]
arrCpx= [1.+1.j 2.+1.j 3.+0.j]
A= <Compressed Sparse Column sparse matrix of dtype 'float64'
with 761 stored elements and shape (121, 121)>
Coords Values
(0, 0) 1.0016666666666667
(1, 0) -0.49958333333333327
(11, 0) -0.49958333333333327
(12, 0) 0.0008333333333333339
(0, 1) -0.49958333333333327
(1, 1) 2.0025
(2, 1) -0.49958333333333327
(12, 1) -0.9991666666666665
: :
(108, 120) 0.0008333333333333331
(109, 120) -0.49958333333333343
(119, 120) -0.49958333333333343
(120, 120) 1.001666666666667
Acpx= <Compressed Sparse Column sparse matrix of dtype 'complex128'
with 761 stored elements and shape (121, 121)>
Coords Values
(0, 0) (0.9983333333333333-0.06666666666666668j)
(1, 0) (-0.5004166666666666-0.016666666666666666j)
(11, 0) (-0.5004166666666666-0.016666666666666666j)
(12, 0) (-0.0008333333333333339+0j)
: :
(109, 120) (-0.5004166666666667-0.016666666666666663j)
(119, 120) (-0.5004166666666667-0.016666666666666663j)
(120, 120) (0.9983333333333336-0.06666666666666665j)
B= [[1. 2. 3.]
[4. 5. 6.]]
Bcpx= [[1.+1.j 2.+2.j 3.+0.j]
[4.+0.j 5.+0.j 6.+1.j]]
f= [0.05 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.05 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
: :
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. ]
Importing python data into FreeFEM¶
The data that are listed in the above table can be imported in a .edp script
by using the macros importVar, importArray, importComplexArray,
importIntArray,
import2DArray,
importComplex2DArray,
importMatrix,
importComplexMatrix,
importMesh3D implemented in
pyfreefem/edp/io.edp.
These macros can be used by inserting the special preprocessing instruction
IMPORT "io.edp" at the beginning of the .edp script.
pyfreefem/edp/io.edp also include the macros
dispVar,dispArray,dispMatrixfor conveniently displaying the values of corresponding variables.
IMPORT "io.edp"
mesh Th=importMesh("Th");
plot(Th,cmm="Th");
real x = importVar("x");
dispVar(x);
real[int] arr = importArray("arr");
dispArray(arr);
complex[int] arrCpx = importComplexArray("arr_cpx");
dispArray(arrCpx);
matrix A = importMatrix("A");
dispMatrix(A);
real[int,int] B = import2DArray("B");
disp2DArray(B);
complex[int,int] Bcpx = importComplex2DArray("Bcpx");
disp2DArray(Bcpx);
In this example, Th, x, arr, arrCpx, A, Acpx, B, Bcpx, refer to
python data structures that must be imported before
executing the script by using
the method import_variables() of the
FreeFemRunner class:
from pyfreefem import FreeFemRunner
import numpy as np
from pymedit import square
import scipy.sparse as sp
x = np.pi
arr = np.asarray([1,2,3])
arr_cpx = np.asarray([1+1j,2+1j,3])
B = np.asarray([[1,2,3],[4,5,6]],dtype=float)
Bcpx = np.asarray([[1+1j,2+2j,3],[4,5,6+1j]])
Th = square(10,10) # a pymedit.Mesh square mesh
A = sp.diags([1,2,3,4])
Acpx = sp.diags([1+1j,2,3+3j,4+1j])
runner = FreeFemRunner("ex11_io_import.edp")
runner.import_variables(x, arr, arr_cpx, Th, A, Acpx, B, Bcpx)
runner.execute(verbosity=0, plot=True)
Running this script should show the following output and figure:
$ python ex11_io_import.py
x=3.14159
arr=3
1 2 3
arrCpx=3
(1,1) (2,1) (3,0)
build matrix 4x4 nnz =4 bin = 1 fname = run/ffimport/matrix_A
A=# HashMatrix Matrix (COO) 0x5cb5144944b0
# n m nnz half fortran state
4 4 4 0 0 0 0
0 0 1
1 1 2
2 2 3
3 3 4
build matrix 4x4 nnz =4 bin = 1 fname = run/ffimport/matrixComplex_Acpx
Acpx=# HashMatrix Matrix (COO) 0x5cb5144945e0
# n m nnz half fortran state
4 4 4 0 0 0 0
0 0 (1,1)
1 1 (2,0)
2 2 (3,3)
3 3 (4,1)
B=2 3
1 2 3
4 5 6
Bcpx=2 3
(1,1) (2,2) (3,0)
(4,0) (5,0) (6,1)
Manual imports and exports¶
Alternatively, you can read and write FreeFEM data structures using
the following functions from the module pyfreefem.io:
readFFArray()andreadFFMatrix()for reading matrices and arrays saved in FreeFEM with ofstream.writeFFArray()andwriteFFMatrix()for saving numpy.array and scipy sparse matrices to files readable by FreeFEM with ifstream.
Floating variables can be directly stored in text files, while pymedit mesh objects can be saved into
.mesh files readable by FreeFEM with the method pymedit.Mesh.save().