Introduction
The MEDCoupling module is presented under the form of a library libmedcoupling and interfaces. This module MEDCoupling represents the DataStructure designed to be exchanged by processors as well in parallel case in SPMD paradigm ( ParaMEDMEM ), as in distributed paradigm using CORBA. This DataStructure is fully deconnected from MEDMEM. This DataStructure is light in order to minimize as much as possible the number of prerequisites needed to use it. The idea is that as this DataStructure is intended to be linked with all of code candidate for coupling ; the number of prerequisites of medcoupling has to be threfore tiny. MEDCoupling has been developped to comply with ICOCO API, conservative interpolators and VTK visualization DataStructure. The MEDCoupling DataStructures have been developped to be compatible with HPC constraints (compact structures, limitation of copies and launching of CPU consuming algorithms only when absolutely needed ).
Basics
One of the most basic concept mainly used all over MEDCoupling is MEDCoupling array. This concept is used all over MEDCoupling/ParaMEDMEM/MEDLoader modules so it should be correctly handled to play well with Meshes and Fields.
There are two types of arrays :
To learn more about arrays click here for arrays documentation.
Main Concepts
Building unstructured mesh from scratch
All of exemples given here make the assumption that the ParaMEDMEM
namespace is visible ( by calling for example using
namespace
ParaMEDMEM
; ).
Here we will create a mesh with spacedim==2 and meshdim==2 too with 5 cells and 9 nodes.
You can notice that it is possible to mix cell types as long as the dimension of cell is exactly equal to meshDim to respect this rule.
double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 };
int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4};
MEDCouplingUMesh *mesh=MEDCouplingUMesh::New();
mesh->setName("My2DMesh");
mesh->setMeshDimension(2);
mesh->allocateCells(5);
mesh->finishInsertingCells();
DataArrayDouble *myCoords=DataArrayDouble::New();
myCoords->alloc(9,2);
std::copy(coords,coords+18,myCoords->getPointer());
mesh->setCoords(myCoords);
myCoords->decrRef();
...
mesh->decrRef();
Building a field from scratch
All of exemples given here make the assumption that the ParaMEDMEM
namespace is visible ( by calling for example using
namespace
ParaMEDMEM
; ).
Here we will make the assumption that an instance of MEDCouplingMesh
called mesh
has been created.
- create a tensor field with 9 components on cells with no time step
MEDCouplingFieldDouble* fieldOnCells=MEDCouplingFieldDouble::New(
ON_CELLS,
NO_TIME);
fieldOnCells->setName("MyTensorFieldOnCellNoTime");
fieldOnCells->setMesh(mesh);
DataArrayDouble *array=DataArrayDouble::New();
array->alloc(mesh->getNumberOfCells(),9);
fieldOnCells->setArray(array);
tmp=array->getPointer();
std::fill(tmp,tmp+9*mesh->getNumberOfCells(),7.);
array->declareAsNew();
array->decrRef();
...
fieldOnCells->decrRef();
- create a scalar field on nodes with no time step
MEDCouplingFieldDouble* fieldOnNodes=MEDCouplingFieldDouble::New(
ON_NODES,
NO_TIME);
fieldOnNodes->setName("MyScalarFieldOnNodeNoTime");
fieldOnNodes->setMesh(mesh);
DataArrayDouble *array=DataArrayDouble::New();
array->alloc(mesh->getNumberOfNodes(),1);
fieldOnNodes->setArray(array);
tmp=array->getPointer();
std::fill(tmp,tmp+mesh->getNumberOfNodes(),7.);
array->declareAsNew();
array->decrRef();
...
fieldOnNodes->decrRef();
- create a 2 components-vector field on cells with one time step and no interval
MEDCouplingFieldDouble* fieldOnCells=MEDCouplingFieldDouble::New(
ON_CELLS,
ONE_TIME);
fieldOnCells->setName("MyVecFieldOnCellWithTime");
fieldOnCells->setMesh(mesh);
fieldOnCells->setTime(4.22,2,-1);
DataArrayDouble *array=DataArrayDouble::New();
array->alloc(mesh->getNumberOfCells(),2);
fieldOnCells->setArray(array);
tmp=array->getPointer();
std::fill(tmp,tmp+2*mesh->getNumberOfCells(),7.);
array->declareAsNew();
array->decrRef();
...
fieldOnCells->decrRef();
- create a 3 components-vector field on nodes with a time interval where hied is constant
fieldOnNodes->setName("MyVecFieldOnNodeWithConstTime");
fieldOnNodes->setMesh(mesh);
fieldOnNodes->setStartTime(4.22,2,-1);
fieldOnNodes->setEndTime(6.44,4,-1);
DataArrayDouble *array=DataArrayDouble::New();
array->alloc(mesh->getNumberOfNodes(),3);
fieldOnNodes->setArray(array);
tmp=array->getPointer();
std::fill(tmp,tmp+3*mesh->getNumberOfNodes(),7.);
array->declareAsNew();
array->decrRef();
...
fieldOnNodes->decrRef();
Operations on Fields
Here we will make the assumption that an instance of MEDCouplingMesh called mesh
has been created with spaceDim==2. Here some exemple of more advanced use of MEDCouplingFieldDouble.
MEDCouplingFieldDouble *f1=mesh->fillFromAnalytic(
ON_NODES,1,
"x*x+y*y*3+2.*x");
MEDCouplingFieldDouble *f2=mesh->fillFromAnalytic(
ON_NODES,1,
"cos(x+y/x)");
MEDCouplingFieldDouble *f2bis=mesh->fillFromAnalytic(
ON_NODES,2,
"x*x*IVec+3*y*JVec");
MEDCouplingFieldDouble *f3=(*f1)+(*f2);
MEDCouplingFieldDouble *f4=(*f3)/(*f2);
f2bis->applyFunc(1,"sqrt(x*x+y*y)");
MEDCouplingFieldDouble *f5=(*f2bis)*(*f4);
const double pos1[2]={0.25,0.};
double res;
f4->getValueOn(pos1,&res);
...
f1->decrRef();
f2->decrRef();
f2bis->decrRef();
f3->decrRef();
f4->decrRef();
f5->decrRef();