Version: 8.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MEDCoupling Python examples

Be sure to take a look at the page A word on the Python API before proceeding.

Fields

Create

Standard build of a tensor field on cells with no time attached

1  fieldOnCells=MEDCouplingFieldDouble(ON_CELLS,NO_TIME)
2  fieldOnCells.setName("MyTensorFieldOnCellNoTime")
3  fieldOnCells.setMesh(mesh)
4  array=DataArrayDouble()
5  array.alloc(fieldOnCells.getMesh().getNumberOfCells(),9) # Implicitely fieldOnCells will be a 9 components field.
6  array.fillWithValue(7.)
7  fieldOnCells.setArray(array)
8  # fieldOnCells is now usable
9  # ...

Standard build of a scalar field on nodes with no time attached

1  fieldOnNodes=MEDCouplingFieldDouble(ON_NODES,NO_TIME)
2  fieldOnNodes.setName("MyScalarFieldOnNodeNoTime")
3  fieldOnNodes.setMesh(mesh)
4  array=DataArrayDouble()
5  array.alloc(fieldOnNodes.getMesh().getNumberOfNodes(),1) # Implicitely fieldOnNodes will be a 1 component field.
6  array.fillWithValue(7.)
7  fieldOnNodes.setArray(array)
8  # fieldOnNodes is now usable
9  # ...

Standard build of a vector field on cells with one time attached and no time interval

1  fieldOnCells=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME)
2  fieldOnCells.setName("MyTensorFieldOnCellNoTime")
3  fieldOnCells.setTimeUnit("ms") # Time unit is ms.
4  fieldOnCells.setTime(4.22,2,-1) # Time attached is 4.22 ms, iteration id is 2 and order id (or sub iteration id) is -1
5  fieldOnCells.setMesh(mesh)
6  array=DataArrayDouble()
7  array.alloc(fieldOnCells.getMesh().getNumberOfCells(),2) # Implicitely fieldOnCells will be a 2 components field.
8  array.fillWithValue(7.)
9  fieldOnCells.setArray(array)
10  # fieldOnCells is now usable
11  # ...

Standard build of a vector field on nodes defined on a time interval with a constant value during this interval

1  fieldOnNodes=MEDCouplingFieldDouble(ON_NODES,CONST_ON_TIME_INTERVAL)
2  fieldOnNodes.setName("MyVecFieldOnNodeWithConstTime")
3  fieldOnNodes.setTimeUnit("ms") # Time unit is ms.
4  fieldOnNodes.setStartTime(4.22,2,-1)
5  fieldOnNodes.setEndTime(6.44,4,-1)# fieldOnNodes is defined in interval [4.22 ms,6.44 ms]
6  fieldOnNodes.setMesh(mesh)
7  array=DataArrayDouble()
8  array.alloc(fieldOnNodes.getMesh().getNumberOfNodes(),3) # Implicitely fieldOnNodes will be a 3 components field.
9  array.fillWithValue(7.)
10  fieldOnNodes.setArray(array)
11  # fieldOnNodes is now usable
12  # ...

Getting maximal and minimal fields

In this example we

  • create two fields with two tuples per two components,
  • use MaxFields() to get a field holding maximal values of the two fields.
  • use MinFields() to get a field holding minimal values of the two fields.
1  vals1 = [0.,2., 4.,6.] # for field 1
2  vals2 = [2.,0., 6.,4.] # for field 2
3  valsMax = [2.,2., 6.,6.] # expected max field
4  valsMin = [0.,0., 4.,4.] # expected min field
5 
6  # field 1
7  valsArr1=DataArrayDouble(vals1,2,2) # 2 tuples per 2 components
8  field1 = MEDCouplingFieldDouble( ON_NODES )
9  field1.setArray( valsArr1 )
10 
11  # field 2
12  valsArr2=DataArrayDouble(vals2,2,2) # 2 tuples per 2 components
13  field2 = MEDCouplingFieldDouble( ON_NODES )
14  field2.setArray( valsArr2 )
15 
16  # max field
17  fieldMax = MEDCouplingFieldDouble.MaxFields( field1, field2 )
18  self.assertTrue( fieldMax.getArray().getValues() == valsMax )
19 
20  # min field
21  fieldMin = MEDCouplingFieldDouble.MinFields( field1, field2 )
22  self.assertTrue( fieldMin.getArray().getValues() == valsMin )

Concatenating fields

In this example we

  • create an 1D mesh and a field on it,
  • make a deep copy of the mesh and the field,
  • translate the mesh and the field,
  • use two variants of MergeFields() to create one field from the two by concatenating them and their meshes.
1  # mesh 1
2  coords = [0.,2.,4.]
3  coordsArr=DataArrayDouble(coords,3,1)
4  mesh1=MEDCouplingCMesh()
5  mesh1.setCoords(coordsArr)
6  # field 1
7  field1 = mesh1.fillFromAnalytic( ON_CELLS, 1, "x")
8 
9  # mesh 2 and field 2
10  field2 = field1.cloneWithMesh( True )
11  vec = [5.]
12  field2.getMesh().translate(vec) # translate mesh2
13  field2.applyFunc("x + 5") # "translate" field2
14 
15  # concatenate field1 and field2
16  field3 = MEDCouplingFieldDouble.MergeFields( field1, field2 )
17  field4 = MEDCouplingFieldDouble.MergeFields( [ field1, field2] )

The result field is twice "longer" than field1.

Getting a field copy with different time discretization

First, we create a supporting 2D mesh and a field on it got using fillFromAnalytic(). Time discretization of this field is ONE_TIME.

1  coords = [0.,2.,4.]
2  coordsArr=DataArrayDouble(coords,3,1)
3  mesh=MEDCouplingCMesh()
4  mesh.setCoords(coordsArr,coordsArr)
5  field1 = mesh.fillFromAnalytic(ON_NODES,1,"x+y")
6  self.assertTrue( field1.getTimeDiscretization() == ONE_TIME )

Now we use buildNewTimeReprFromThis() to get a copy of field1 whose time discretization is NO_TIME.

1  field2 = field1.buildNewTimeReprFromThis(NO_TIME,False)
2  self.assertTrue( field2.getTimeDiscretization() == NO_TIME )

Creating a field using an expression

First, we create a 2D Cartesian mesh constituted by 2 cells.

1  coords = [0.,2.,4.,6.] # 6. is not used
2  x=DataArrayDouble(coords[:3],3,1)
3  y=DataArrayDouble(coords[:2],2,1)
4  mesh=MEDCouplingCMesh()
5  mesh.setCoords(x,y)

Now we use fillFromAnalytic3() to get a MEDCouplingFieldDouble on cells filled with values computed using an expression func. This expression is applied to coordinates of each point (barycenter) for which the field value is computed. We want to get the field on cells, with 3 components computed as follows. (In func, we refer to the first component of a point using the variable "a", and to the second component, using the variable "b").

  • Component #0 = the second coordinate of the point hence "IVec * b" in func.
  • Component #1 = the first coordinate of the point hence "JVec * a".
  • Component #2 = distance between the point and SC origin (0.,0.) hence "KVec * sqrt( a*a + b*b )".

In addition we want to add 10.0 to each component computed as described above, hence "10" in func.

1  func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
2  varNames=["a","b"] # names used to refer to X and Y coord components
3  field=mesh.fillFromAnalyticNamedCompo(ON_CELLS,3,varNames,func)

Now we ascertain that the result field is as we expect. We check the second tuple of the field. We get barycenter of the cell #1 and checks that values of the second tuple are computed as we want.

1  vals1 = field.getArray().getTuple(1) # values of the cell #1
2  assert len( vals1 ) == 3 # 3 components in the field
3  #
4  bc = mesh.computeCellCenterOfMass() # func is applied to barycenters of cells
5  bc1 = bc.getTuple(1) # coordinates of the second point
6  #
7  dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )"
8  self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b"
9  self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a"
10  self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )"

Creating a field using an expression

First, we create a 2D Cartesian mesh constituted by 2 cells. Note that we set names to coordinates arrays ("a" and "b" ) which will be used to refer to corresponding coordinates within a function.

1  coords = [0.,2.,4.,6.] # 6. is not used
2  x=DataArrayDouble(coords[:3],3,1)
3  y=DataArrayDouble(coords[:2],2,1)
4  x.setInfoOnComponent(0,"a") # name used to refer to X coordinate within a function
5  y.setInfoOnComponent(0,"b") # name used to refer to Y coordinate within a function
6  mesh=MEDCouplingCMesh()
7  mesh.setCoords(x,y)

Now we use fillFromAnalytic2() to get a MEDCouplingFieldDouble on cells filled with values computed using an expression func. This expression is applied to coordinates of each point (barycenter) for which the field value is computed. We want to get the field on cells, with 3 components computed as follows. (In func, we refer to the first component of a point using the variable "a", and to the second component, using the variable "b").

  • Component #0 = the second coordinate of the point hence "IVec * b" in func.
  • Component #1 = the first coordinate of the point hence "JVec * a".
  • Component #2 = distance between the point and SC origin (0.,0.) hence "KVec * sqrt( a*a + b*b )".

In addition we want to add 10.0 to each component computed as described above, hence "10" in func.

1  func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
2  field=mesh.fillFromAnalyticCompo(ON_CELLS,3,func)

Now we ascertain that the result field is as we expect. We check the second tuple of the field. We get barycenter of the cell #1 and checks that values of the second tuple are computed as we want.

1  vals1 = field.getArray().getTuple(1) # values of the cell #1
2  assert len( vals1 ) == 3 # 3 components in the field
3  #
4  bc = mesh.computeCellCenterOfMass() # func is applied to barycenters of cells
5  bc1 = bc.getTuple(1) # coordinates of the second point
6  #
7  dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )"
8  self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b"
9  self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a"
10  self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )"

Creating a field using an expression

First, we create a 2D Cartesian mesh constituted by 2 cells.

1  coords = [0.,2.,4.,6.] # 6. is not used
2  x=DataArrayDouble(coords[:3],3,1)
3  y=DataArrayDouble(coords[:2],2,1)
4  mesh=MEDCouplingCMesh()
5  mesh.setCoords(x,y)

Now we use fillFromAnalytic() to get a MEDCouplingFieldDouble on cells filled with values computed using an expression func. This expression is applied to coordinates of each point (barycenter) for which the field value is computed. We want to get the field on cells, with 3 components computed as follows. (In func, we refer to the first component of a point using the variable "a", and to the second component, using the variable "b").

  • Component #0 = the second coordinate of the point hence "IVec * b" in func.
  • Component #1 = the first coordinate of the point hence "JVec * a".
  • Component #2 = distance between the point and SC origin (0.,0.) hence "KVec * sqrt( a*a + b*b )".

In addition we want to add 10.0 to each component computed as described above, hence "10" in func.

1  func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
2  field=mesh.fillFromAnalytic(ON_CELLS,3,func)

Now we ascertain that the result field is as we expect. We check the second tuple of the field. We get barycenter of the cell #1 and checks that values of the second tuple are computed as we want.

1  vals1 = field.getArray().getTuple(1) # values of the cell #1
2  assert len( vals1 ) == 3 # 3 components in the field
3  #
4  bc = mesh.computeCellCenterOfMass() # func is applied to barycenters of cells
5  bc1 = bc.getTuple(1) # coordinates of the second point
6  #
7  dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )"
8  self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b"
9  self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a"
10  self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )"

Creation of a sub part of a field


Creation of a sub part of a field on cells

1  mesh1=MEDCouplingDataForTest.build2DTargetMesh_1()
2  f1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME)
3  f1.setTime(2.3,5,6)
4  f1.setMesh(mesh1)
5  arr1=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.]
6  array=DataArrayDouble(arr1,mesh1.getNumberOfCells(),2)
7  f1.setArray(array)

The field on cells f1 lies on a mesh containing 5 cells and 9 nodes. So this field f1 contains 5 tuples of 2 components each (10 values). Now let's create a subfield on cells f2 from f1.

1  part1=[2,1,4]
2  f2=f1.buildSubPart(part1)

f1 is a field on cells, buildSubPart method performs an extraction on cells too.

So the array part1 lists ids on cells.

  • cell #0 of f2 is the same cell of cell #2 of f1
  • cell #1 of f2 is the same cell of cell #1 of f1
  • cell #2 of f2 is the same cell of cell #4 of f1

So f2 contains 3 tuples with 2 components.

The underlying mesh of f2 contains a newly created mesh with 3 cells (not as mesh1 in f1) and 9 nodes (as mesh1 in f1).
For fields on cells the number of tuples of the returned field is always equal to the number of ids given in input (here part1).
Only fields on cells have this particular behaviour.


Creation of a sub part of a field on nodes

1  f1=MEDCouplingFieldDouble(ON_NODES,ONE_TIME)
2  f1.setTime(2.3,5,6)
3  f1.setMesh(mesh1)
4  arr2=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.]
5  array=DataArrayDouble(arr2,mesh1.getNumberOfNodes(),2)
6  f1.setArray(array)

The field on nodes f1 lies on a mesh containing 5 cells and 9 nodes. So this field f1 contains 9 tuples of 2 components each (18 values). Now let's create a subfield on nodes f2 from f1.

1  part2=[1,2]
2  f2=f1.buildSubPart(part2)

f1 is a field on nodes, but buildSubPart method performs an extraction on cells.

After the call of buildSubPart on node field f1, f1 will be reduced on a submesh of mesh1 containing cells whose ids are in part2. So here the number of cells of f2 is 2 and the number of nodes is 4.
So contrary to fields on cells, it is normal for fields on nodes that number of tuples of the returned field of buildSubPart method does not match the size of the input array (here part2).

Modify

Subtracting field on different meshes

We make two meshes in 1D space with no cells and 4 nodes. Nodes #0 and #2 are swapped in the two meshes.
And we make two fields on these meshes, so that fields values to equal to node coordinates of the underlying meshes.

1  coords1=[0.,1.,2.,3.]
2  coords2=[2.,1.,0.,3.] #0 <==> #2
3  # mesh 1
4  mesh1=MEDCouplingUMesh()
5  coordsArr=DataArrayDouble(coords1, 4, 1)
6  mesh1.setCoords(coordsArr)
7  mesh1.setMeshDimension(0)
8  mesh1.allocateCells(0)
9  mesh1.finishInsertingCells()
10  # mesh 2
11  mesh2=mesh1.deepCopy()
12  mesh2.getCoords().setValues(coords2, 4, 1)

We are going to subtract field2 from field1, though they are on different meshes. substractInPlaceDM() allows us doing this. We use a mesh comparison level levOfCheck = 10 that allows subtracting fields on meshes with different node arrays.

1  field1 = mesh1.fillFromAnalytic(ON_NODES,1,"x") # field1 values == coords1
2  field2 = mesh2.fillFromAnalytic(ON_NODES,1,"x") # field2 values == coords2
3  levOfCheck = 10 # nodes can be permuted
4  field1.substractInPlaceDM( field2, levOfCheck, 1e-13, 0 ) # values #0 and #2 must swap

After applying substractInPlaceDM() the both fields lie on mesh2. As substractInPlaceDM() permutes values of field1 before value subtraction, and thus field1 becomes equal to field2, hence their subtraction results in a zero field.

1  field2.applyFunc( 1, 0.0 ) # all field2 values == 0.0
2  self.assertTrue( field1.isEqual( field2, 1e-13, 1e-13 )) # field1 == field2 == 0.0

Changing the underlying mesh

We make two meshes in 1D space with no cells and 4 nodes. Nodes #0 and #2 are swapped in the two meshes.

1  coords1=[0.,1.,2.,3.]
2  coords2=[2.,1.,0.,3.] #0 <==> #2
3  # mesh 1
4  mesh1=MEDCouplingUMesh()
5  coordsArr=DataArrayDouble(coords1, 4, 1)
6  mesh1.setCoords(coordsArr)
7  mesh1.setMeshDimension(0)
8  mesh1.allocateCells(0)
9  mesh1.finishInsertingCells()
10  # mesh 2
11  mesh2=mesh1.deepCopy()
12  mesh2.getCoords().setValues(coords2, 4, 1)

We are going to use changeUnderlyingMesh() to set mesh2 instead of mesh1 as a support of a field.
We use fillFromAnalytic() to make a field on nodes of mesh1, so that its values to equal to node coordinates. Then we use changeUnderlyingMesh() to change the underlying mesh of the field. (We use a mesh comparison level levOfCheck = 10 that allows substituting meshes with different node arrays.) As a result, we expect that values of the field are also permuted same as nodes of the two meshes, and thus its values become equal to the array coords2.

1  field = mesh1.fillFromAnalytic(ON_NODES,1,"x") # field values == coords1
2  levOfCheck = 10 # nodes can be permuted
3  field.changeUnderlyingMesh( mesh2, levOfCheck, 1e-13, 0 ) # values #0 and #2 must swap
4  self.assertTrue( field.getArray().getValues() == coords2 )

Changing a field using an expression

We create a 2D vector field with 2 tuples and we want to transform this field using an expression using applyFunc(). The expression func is applied to each atomic value of the field. We want to change the field as follows. (In func, we use the variable "v" to refer to an atomic field value).

  • Component #0 = component #0 (remains the same) hence "IVec * v" in func.
  • Component #1 = component #1 ^ 2 hence "JVec * v*v".

In addition we want to add 10.0 to each component computed as described above, hence "10" in func.

1  v = [1.,2., 3.,4.]
2  array = DataArrayDouble( v, 2, 2 ) # 2 tuples per 2 components
3  field = MEDCouplingFieldDouble( ON_CELLS )
4  field.setArray( array )
5  func = "IVec * v + JVec * w*w + 10"
6  field.applyFunc( 2, func )
7  self.assertTrue( field.getNumberOfComponents() == 2 ) # 2 components remains

Now we ascertain that the result field is as we expect.

1  v2 = field.getArray().getValues()
2  self.assertAlmostEqual( v2[0], 10 + v[0], 13 ) # "10 + IVec * v"
3  self.assertAlmostEqual( v2[1], 10 + v[1]*v[1], 13 ) # "10 + JVec * v*v"
4  self.assertAlmostEqual( v2[2], 10 + v[2], 13 ) # "10 + IVec * v"
5  self.assertAlmostEqual( v2[3], 10 + v[3]*v[3], 13 ) # "10 + JVec * v*v"

Changing a field using an expression

We create a 2D vector field with 2 values (vectors) and then we transform this field into a 3D vector field by applying an expression to values of the 2D field using applyFunc3(). The expression func is applied to components of each vector of the field. We want the field to have 3 components computed as follows. (In func, we refer to the first component of a field value using the variable "a", and to the second component, using the variable "b", as we define it by varNamesVec).

  • Component #0 = the second vector component hence "IVec * b" in func.
  • Component #1 = the first vector component hence "JVec * a".
  • Component #2 = a vector magnitude hence "KVec * sqrt( a*a + b*b )".

In addition we want to add 10.0 to each component computed as described above, hence "10" in func.

1  # create a 2D vector field
2  values = [1.,1., 2.,1.]
3  array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components
4  field = MEDCouplingFieldDouble( ON_CELLS )
5  field.setArray( array )
6  # transform the field to a 3D vector field
7  func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
8  varNames=["a","b"] # names used to refer to X and Y components
9  field.applyFuncNamedCompo( 3, varNames, func ) # require 3 components
10  self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required

Now we ascertain that the result field is as we expect. We check the second vector of the field.

1  vec1 = field.getArray().getTuple(1) # vector #1
2  a,b = values[2], values[3] # initial components of the vector #1
3  self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b"
4  self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a"
5  self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )"

Changing a field using an expression

We create a 2D vector field with 2 values (vectors) and then we transform this field into a 3D vector field by applying an expression to values of the 2D field using applyFunc2(). Note that we set component info the array ("a" and "b" ) which will be used to refer to corresponding components within a function. The expression func is applied to components of each vector of the field. We want the field to have 3 components computed as follows. (In func, we refer to the first component of a field value using the variable "a", and to the second component, using the variable "b").

  • Component #0 = the second vector component hence "IVec * b" in func.
  • Component #1 = the first vector component hence "JVec * a".
  • Component #2 = a vector magnitude hence "KVec * sqrt( a*a + b*b )".

In addition we want to add 10.0 to each component computed as described above, hence "10" in func.

1  # create a 2D vector field
2  values = [1.,1., 2.,1.]
3  array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components
4  array.setInfoOnComponent(0,"a") # name used to refer to X component within a function
5  array.setInfoOnComponent(1,"b") # name used to refer to Y component within a function
6  field = MEDCouplingFieldDouble( ON_CELLS )
7  field.setArray( array )
8  # transform the field to a 3D vector field
9  func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
10  field.applyFuncCompo( 3, func ) # require 3 components
11  self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required

Now we ascertain that the result field is as we expect. We check the second vector of the field.

1  vec1 = field.getArray().getTuple(1) # vector #1
2  a,b = values[2], values[3] # initial components of the vector #1
3  self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b"
4  self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a"
5  self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )"

Changing a field using an expression

We create a 2D vector field with 2 values (vectors) and then we transform this field into a 3D vector field by applying an expression to values of the 2D field using applyFunc(). The expression func is applied to components of each vector of the field. We want the field to have 3 components computed as follows. (In func, we refer to the first component of a field value using the variable "a", and to the second component, using the variable "b").

  • Component #0 = the second vector component hence "IVec * b" in func.
  • Component #1 = the first vector component hence "JVec * a".
  • Component #2 = a vector magnitude hence "KVec * sqrt( a*a + b*b )".

In addition we want to add 10.0 to each component computed as described above, hence "10" in func.

1  # create a 2D vector field
2  values = [1.,1., 2.,1.]
3  array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components
4  field = MEDCouplingFieldDouble( ON_CELLS )
5  field.setArray( array )
6  # transform the field to a 3D vector field
7  func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
8  field.applyFunc( 3, func ) # require 3 components
9  self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required

Now we ascertain that the result field is as we expect. We check the second vector of the field.

1  vec1 = field.getArray().getTuple(1) # vector #1
2  a,b = values[2], values[3] # initial components of the vector #1
3  self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b"
4  self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a"
5  self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )"

Filling a field with a value

We want to transform a 2D vector field to a 3D vector field so that all values to be equal to a certain value. First, we create the 2D mesh and the vector field on it.

1  coords = [0.,2.,4.]
2  coordsArr=DataArrayDouble(coords,3,1)
3  mesh=MEDCouplingCMesh()
4  mesh.setCoords(coordsArr,coordsArr)
5  field = MEDCouplingFieldDouble( ON_CELLS )
6  field.setMesh( mesh )
7  field.fillFromAnalytic(2,"IVec * x + JVec * y") # 2 components

Finally we use applyFunc() to change the number of components and all field values.

1  newValue = 7.
2  field.applyFunc( 3, newValue ) # 3 components are required
3  self.assertTrue( field.getIJ(1,0) == newValue ) # a value is as expected
4  self.assertTrue( field.getNumberOfComponents() == 3 )
5  self.assertTrue( field.getNumberOfTuples() == mesh.getNumberOfCells() )

As a result, number of tuples in the field equals to the number of cells in the mesh, and number of components becomes equal to 3 as required.

Filling a field using an expression

First, we create a 2D Cartesian mesh constituted by 2 cells.

1  coords = [0.,2.,4.,6.] # 6. is not used
2  x=DataArrayDouble(coords[:3],3,1)
3  y=DataArrayDouble(coords[:2],2,1)
4  mesh=MEDCouplingCMesh()
5  mesh.setCoords(x,y)

Now we create a field on cells and use fillFromAnalytic2() to fill it with values computed using an expression func. This expression is applied to coordinates of each point (barycenter) for which the field value is computed. We want the field to have 3 components computed as follows. (In func, we refer to the first component of a point using the variable "a", and to the second component, using the variable "b").

  • Component #0 = the second coordinate of the point hence "IVec * b" in func.
  • Component #1 = the first coordinate of the point hence "JVec * a".
  • Component #2 = distance between the point and SC origin (0.,0.) hence "KVec * sqrt( a*a + b*b )".

In addition we want to add 10.0 to each component computed as described above, hence "10" in func.

1  field = MEDCouplingFieldDouble( ON_CELLS )
2  field.setMesh( mesh )
3  func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
4  varNames=["a","b"] # names used to refer to X and Y coord components
5  field.fillFromAnalyticNamedCompo(3,varNames,func)

Now we ascertain that the result field is as we expect. We check the second tuple of the field. We get barycenter of the cell #1 and checks that values of the second tuple are computed as we want.

1  vals1 = field.getArray().getTuple(1) # values of the cell #1
2  assert len( vals1 ) == 3 # 3 components in the field
3  #
4  bc = mesh.computeCellCenterOfMass() # func is applied to barycenters of cells
5  bc1 = bc.getTuple(1) # coordinates of the second point
6  #
7  dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )"
8  self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b"
9  self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a"
10  self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )"

Filling a field using an expression

First, we create a 2D Cartesian mesh constituted by 2 cells. Note that we set names to coordinates arrays ("a" and "b" ) which will be used to refer to corresponding coordinates within a function.

1  coords = [0.,2.,4.]
2  x=DataArrayDouble(coords[:3],3,1)
3  y=DataArrayDouble(coords[:2],2,1)
4  x.setInfoOnComponent(0,"a") # name used to refer to X coordinate within a function
5  y.setInfoOnComponent(0,"b") # name used to refer to Y coordinate within a function
6  mesh=MEDCouplingCMesh()
7  mesh.setCoords(x,y)

Now we create a field on cells and use fillFromAnalytic2() to fill it with values computed using an expression func. This expression is applied to coordinates of each point (barycenter) for which the field value is computed. We want the field to have 3 components computed as follows. (In func, we refer to the first component of a point using the variable "a", and to the second component, using the variable "b").

  • Component #0 = the second coordinate of the point hence "IVec * b" in func.
  • Component #1 = the first coordinate of the point hence "JVec * a".
  • Component #2 = distance between the point and SC origin (0.,0.) hence "KVec * sqrt( a*a + b*b )".

In addition we want to add 10.0 to each component computed as described above, hence "10" in func.

1  field = MEDCouplingFieldDouble( ON_CELLS )
2  field.setMesh( mesh )
3  func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
4  field.fillFromAnalyticCompo(3,func)

Now we ascertain that the result field is as we expect. We check the second tuple of the field. We get barycenter of the cell #1 and checks that values of the second tuple are computed as we want.

1  vals1 = field.getArray().getTuple(1) # values of the cell #1
2  assert len( vals1 ) == 3 # 3 components in the field
3  #
4  bc = mesh.computeCellCenterOfMass() # func is applied to barycenters of cells
5  bc1 = bc.getTuple(1) # coordinates of the second point
6  #
7  dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )"
8  self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b"
9  self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a"
10  self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )"

Filling a field using an expression

First, we create a 2D Cartesian mesh constituted by 2 cells.

1  coords = [0.,2.,4.]
2  x=DataArrayDouble(coords[:3],3,1)
3  y=DataArrayDouble(coords[:2],2,1)
4  mesh=MEDCouplingCMesh()
5  mesh.setCoords(x,y)

Now we create a field on cells and use fillFromAnalytic() to fill it with values computed using an expression func. This expression is applied to coordinates of each point (barycenter) for which the field value is computed. We want the field to have 3 components computed as follows. (In func, we refer to the first component of a point using the variable "a", and to the second component, using the variable "b").

  • Component #0 = the second coordinate of the point hence "IVec * b" in func.
  • Component #1 = the first coordinate of the point hence "JVec * a".
  • Component #2 = distance between the point and SC origin (0.,0.) hence "KVec * sqrt( a*a + b*b )".

In addition we want to add 10.0 to each component computed as described above, hence "10" in func.

1  field = MEDCouplingFieldDouble( ON_CELLS )
2  field.setMesh( mesh )
3  func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"
4  field.fillFromAnalytic(3,func)

Now we ascertain that the result field is as we expect. We check the second tuple of the field. We get barycenter of the cell #1 to check that values of the second tuple (#1) are computed as we want.

1  vals1 = field.getArray().getTuple(1) # values of the cell #1
2  assert len( vals1 ) == 3 # 3 components in the field
3  #
4  bc = mesh.computeCellCenterOfMass() # func is applied to barycenters of cells
5  bc1 = bc.getTuple(1) # coordinates of the second point
6  #
7  dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )"
8  self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b"
9  self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a"
10  self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )"

Some operations that can be carried out on fields on cells

1  f1=mesh.fillFromAnalytic(ON_CELLS,1,"x*x+y*y*3+2.*x") # f1 is scalar
2  f2=mesh.fillFromAnalytic(ON_CELLS,1,"cos(x+y/x)") # f2 is scalar too
3  f2bis=mesh.fillFromAnalytic(ON_CELLS,2,"x*x*IVec+3*y*JVec") # f2bis is a vectors field
4  f3=f1+f2 # f3 scalar
5  f4=f3/f2 # f4 scalar
6  f2bis.applyFunc(1,"sqrt(x*x+y*y)") # f2bis becomes scalar
7  f5=f2bis*f4 # f5 scalar
8  pos1=[0.48,0.38]
9  res=f4.getValueOn(pos1) # f4 is scalar so the returned value is of size 1.
10  # ...

Permuting a field on nodes

First, we create a supporting 2D mesh constituted by 4 cells. We create a 2x2 Cartesian mesh and then convert it to an unstructured one, since the Cartesian mesh is not suitable for renumberNodes() as its nature does not imply node renumbering.

1  coords = [0.,2.,4.]
2  coordsArr=DataArrayDouble(coords,3,1)
3  mesh=MEDCouplingCMesh()
4  mesh.setCoords(coordsArr,coordsArr)
5  mesh=mesh.buildUnstructured()

Then we create a field on nodes using fillFromAnalytic(), such that its values to coincide with coordinates of field location points that are nodes in our case (as our field is ON_NODES). At last we ascertain that field values are equal to node coordinates.

1  field = mesh.fillFromAnalytic(ON_NODES,2,"IVec*x+JVec*y")
2  values = field.getArray()
3  nodeCoords = mesh.getCoords()
4  self.assertTrue( values.isEqualWithoutConsideringStr( nodeCoords, 1e-13 ))

Now, we are going to reverse order of nodes using renumberNodes().

1  renumber = [8, 7, 6, 5, 4, 3, 2, 1, 0]
2  field.renumberNodes(renumber,False)
3  mesh2 = field.getMesh() # field now refers to another mesh
4  values = field.getArray()
5  nodeCoords = mesh2.getCoords()
6  self.assertTrue( values.isEqualWithoutConsideringStr( nodeCoords, 1e-13 ))

As a result, the underlying mesh of field is changed and its nodes are also renumbered. And the field values are still equal to node coordinates of the renumbered mesh2.

Permuting a field on cells

First, we create a supporting 2D mesh constituted by 4 cells. We create a 2x2 Cartesian mesh and then convert it to an unstructured one, since the Cartesian mesh is not suitable for renumberCells() as its nature does not imply cell renumbering.

1  coords = [0.,2.,4.]
2  coordsArr=DataArrayDouble(coords,3,1)
3  mesh=MEDCouplingCMesh()
4  mesh.setCoords(coordsArr,coordsArr)
5  mesh=mesh.buildUnstructured()

Then we create a field on cells using fillFromAnalytic(), such that its values to coincide with coordinates of field location points that are cell barycenters in our case (as our field is ON_CELLS). At last we ascertain that field values are equal to cell barycenters.

1  field = mesh.fillFromAnalytic(ON_CELLS,2,"IVec*x+JVec*y")
2  values = field.getArray()
3  bc = mesh.computeCellCenterOfMass()
4  self.assertTrue( values.isEqualWithoutConsideringStr( bc, 1e-13 ))

Now, we are going to reverse order of cells using renumberCells().

1  renumber = [ 3, 2, 1, 0 ]
2  field.renumberCells(renumber,False)
3  mesh2 = field.getMesh() # field now refers to another mesh
4  values = field.getArray()
5  bc = mesh2.computeCellCenterOfMass()
6  self.assertTrue( values.isEqualWithoutConsideringStr( bc, 1e-13 ))

As a result, the underlying mesh of field is changed and its cells are also renumbered. And the field values are still equal to cell barycenters of the renumbered mesh2.

Access

Getting a field value at some point at certain time

First, we create a supporting structured mesh. We create a 2x2 Cartesian mesh constituted by 4 cells.

1  coords = [0.,2.,4.]
2  coordsArr=DataArrayDouble(coords,3,1)
3  mesh=MEDCouplingCMesh()
4  mesh.setCoords(coordsArr,coordsArr)

Then we create a scalar field on cells, whose values vary linearly in time. We set all field values at a start time to be equal 10.0 using fillFromAnalytic(). And we set all field values at an end time to be equal 20.0 by doubling the start time array.

1  field = MEDCouplingFieldDouble( ON_CELLS, LINEAR_TIME )
2  field.setMesh( mesh )
3  field.fillFromAnalytic(1,"10") # all values == 10.
4  field.setEndArray( field.getArray() + field.getArray() ) # all values == 20.
5  time1, time2 = 1.1, 22.
6  field.setStartTime( time1, 0, 0 )
7  field.setEndTime ( time2, 0, 0 )

Now, we want to get a field value at a point [0,0] at a middle time between the start and end times. We expect the returned value to be equal to an average of 10. and 20.

1  pos = [ 1., 1. ] # we are in 2D space
2  value = field.getValueOn( pos, 0.5*( time1 + time2 ))
3  self.assertTrue( value[0] == 0.5*( 10. + 20.))

Getting field values at some points

First, we create a supporting structured mesh. We create a 2x2 Cartesian mesh constituted by 4 cells. Then we create a scalar field on cells using fillFromAnalytic().

1  coords = [0.,2.,4.]
2  coordsArr=DataArrayDouble(coords,3,1)
3  mesh=MEDCouplingCMesh()
4  mesh.setCoords(coordsArr,coordsArr)
5  field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y")

Now, we want to retrieve all field values using getValueOnMulti(). The field values relate to cells, hence we will use cell barycenters as a parameter of getValueOnMulti(). We expect that the double array returned getValueOnMulti() is equal to that stored by field.

1  bc = mesh.computeCellCenterOfMass() # field values are located at cell barycenters
2  valArray = field.getValueOnMulti( bc )
3  self.assertTrue( valArray.isEqual( field.getArray(), 1e-13 ))

Getting a field value at a point

First, we create a supporting structured mesh. We create a 2x2 Cartesian mesh constituted by 4 cells. Then we create a scalar field on cells using fillFromAnalytic().

1  coords = [0.,2.,4.]
2  coordsArr=DataArrayDouble(coords,3,1)
3  mesh=MEDCouplingCMesh()
4  mesh.setCoords(coordsArr,coordsArr)
5  field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y")

Now, we want to retrieve all field values using getValueOn(). The field values relate to cells, hence we will use cell barycenters to get a field value at each cell.

1  bc = mesh.computeCellCenterOfMass() # field values are located at cell barycenters
2  vals = [] # array to collect values returned by getValueOn()
3  for i,tupl in enumerate( bc ):
4  vals.extend( field.getValueOn( tupl ) )
5  self.assertTrue( vals == field.getArray().getValues() )

We collected all values returned by getValueOn() in an array, so that we can ascertain that the array of returned values is same as that stored by field.

Getting a value of field lying on a structured mesh

First, we create a supporting structured mesh. We create a 2x2 Cartesian mesh constituted by 4 cells. Then we create a scalar field on cells using fillFromAnalytic().

1  coords = [0.,2.,4.]
2  coordsArr=DataArrayDouble(coords,3,1)
3  mesh=MEDCouplingCMesh()
4  mesh.setCoords(coordsArr,coordsArr)
5  field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y")

Now, we retrieve a field value relating to the cell #3 (this cell has a structured indexed (1,1)). For that we use getValueOnPos() where we pass the structured indexed of the cell: 1,1,-1 (the last index is meaningless as the mesh is 2D).

1  val11 = field.getValueOnPos( 1,1,-1)
2  bc = mesh.computeCellCenterOfMass() # field values are located at cell barycenters
3  self.assertTrue( val11[0] == bc[3,0] + bc[3,1] )

After all we ascertain that the returned value corresponds to the expression used for the field creation. Namely that the value equals to the sum of components of barycenter of cell #3.

Meshes

Create

Standard build of an unstructured mesh from scratch

Firstly retrieve basic data in full interlace mode for coordinates, and nodal connectivity cell per cell.

1  coords=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0.,
2  0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ]
3  nodalConnPerCell=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]

Then create MEDCoupling::MEDCouplingUMesh instance giving its mesh dimension (2 here) and a name.

1  mesh=MEDCouplingUMesh("My2DMesh",2)

Gives an upper bound of the number of cells to be inserted into the unstructured mesh.
Then enter nodal connectivity of all cells, cell per cell using MEDCoupling::MEDCouplingUMesh::insertNextCell method.
When the nodal connectivity cell per cell has been finished, call MEDCoupling::MEDCouplingUMesh::finishInsertingCells method in order to restore mesh instance.

1  mesh.allocateCells(5)#You can put more than 5 if you want but not less.
2  mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[:4])
3  mesh.insertNextCell(NORM_TRI3,nodalConnPerCell[4:7])
4  mesh.insertNextCell(NORM_TRI3,nodalConnPerCell[7:10])
5  mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[10:14])
6  mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[14:])
7  mesh.finishInsertingCells()

At this level the connectivity part of the mesh mesh as been defined. Now let's set the coordinates using array coords defined above.

1  coordsArr=DataArrayDouble(coords,9,3)#here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3.
2  mesh.setCoords(coordsArr)#coordsArr contains 9 tuples, that is to say mesh contains 9 nodes.

At this level mesh is usable. When this mesh is no more needed simply call decrRef to decrement its reference counter.

Advanced build of an unstructured mesh from scratch

Firstly retrieve basic data in full interlace mode for coordinates, and nodal connectivity cell per cell, cell type included (3 for INTERP_KERNEL::NORM_TRI3 and 4 for INTERP_KERNEL::QUAD4).

1  coords=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0.,
2  0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ]
3  nodalConnPerCell=[4,0,3,4,1, 3,1,4,2, 3,4,5,2, 4,6,7,4,3, 4,7,8,5,4]
4  nodalConnPerCellIndex=[0,5,9,13,18,23]

Then create MEDCoupling::MEDCouplingUMesh instance giving its mesh dimension (2 here) and a name.

1  mesh=MEDCouplingUMesh("My2DMesh",2)

Then enter nodal connectivity at once.

1  nodalConn=DataArrayInt(nodalConnPerCell,23,1)
2  nodalConnI=DataArrayInt(nodalConnPerCellIndex,6,1)
3  mesh.setConnectivity(nodalConn,nodalConnI,True)

At this level the connectivity part of the mesh mesh as been defined. Now let's set the coordinates using array coords defined above.

1  coordsArr=DataArrayDouble(coords,9,3)#here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3.
2  mesh.setCoords(coordsArr)#coordsArr contains 9 tuples, that is to say mesh contains 9 nodes.

At this level mesh is usable. When this mesh is no more needed simply call decrRef() to decrement its reference counter.

Standard build of an cartesian mesh from scratch

We are going to build a 2D cartesian mesh, constituted from 9 nodes along X axis, and 7 nodes along Y axis.

Firstly retrieve for each direction the discretization and build a DataArrayDouble instance on the corresponding direction.

1  XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22] # 9 values along X
2  YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007] # 7 values along Y
3  arrX=DataArrayDouble(XCoords)
4  arrX.setInfoOnComponent(0,"X [m]")
5  arrY=DataArrayDouble(YCoords)
6  arrY.setInfoOnComponent(0,"Y [m]")

Then create MEDCoupling::MEDCouplingCMesh instance giving the 2 instances of DataArrayDouble obtained above.

There are 2 techniques to get it.

Either :

1  mesh=MEDCouplingCMesh("My2D_CMesh")
2  mesh.setCoords(arrX,arrY)

Or :

1  mesh.setCoordsAt(0,arrX)
2  mesh.setCoordsAt(1,arrY)

mesh is now available for use :

1  self.assertEqual(8*6,mesh.getNumberOfCells())
2  self.assertEqual(9*7,mesh.getNumberOfNodes())
3  self.assertEqual(2,mesh.getSpaceDimension())
4  self.assertEqual(2,mesh.getMeshDimension())

When this mesh is no more needed simply call decrRef to decrement its reference counter (nothing to be done in Python).

Getting a bounding mesh

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7])
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10])
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14])
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18])
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we use buildBoundaryMesh() to get a mesh of lower dimension bounding mesh.

1  mesh1=mesh.buildBoundaryMesh(True)
2  mesh2=mesh.buildBoundaryMesh(False)
3  assert coordsArr.isEqual( mesh1.getCoords(), 1e-13 ) # same nodes
4  assert not coordsArr.isEqual( mesh2.getCoords(), 1e-13 ) # different nodes

Depending on the value of a parameter, buildBoundaryMesh() creates the mesh sharing the node coordinates array with mesh or not.

Retrieving a lower dimension mesh based on given nodes

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

In the following code we retrieve nodes of the cell #0 an then we call buildFacePartOfMySelfNode() twice with these nodes and with varying last parameter allNodes as input.

1  nodeIds = mesh.getNodeIdsOfCell( 0 )
2  allNodes = True
3  mesh1 = mesh.buildFacePartOfMySelfNode( nodeIds, allNodes )
4  assert mesh1.getNumberOfCells() == 4 # 4 segments bounding QUAD4 #0 only
5  mesh2 = mesh.buildFacePartOfMySelfNode( nodeIds, not allNodes )
6  assert mesh2.getNumberOfCells() > 4 # more segments added


If the last parameter is true buildFacePartOfMySelfNode() looks for segements whose all nodes are given to it, hence it finds segments bounding the cell #0 only.
If the last parameter is false buildFacePartOfMySelfNode() looks for any segment whose nodes are given to it, hence it adds more segments to mesh2.

Copying cells selected by nodes

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

In the following code we retrieve nodes of the cell #0 an then we call buildPartOfMySelfNode() twice with these nodes and with varying last parameter allNodes as input.

1  nodeIds = mesh.getNodeIdsOfCell( 0 )
2  allNodes = True
3  mesh1 = mesh.buildPartOfMySelfNode( nodeIds, allNodes )
4  mesh2 = mesh.buildPartOfMySelfNode( nodeIds, not allNodes )
5  assert mesh1.getNumberOfCells() == 1 # cell #0 is found only
6  assert mesh2.getNumberOfCells() == mesh.getNumberOfCells() # all cells are found


If the last parameter is true buildPartOfMySelfNode() looks for cells whose all nodes are given to it, hence it finds the cell #0 only.
If the last parameter is false buildPartOfMySelfNode() looks for any cell whose nodes are given to it, hence it finds all cells of mesh because all cells share the node #4.

Getting a part of mesh

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we use buildPartOfMySelf() to get a mesh containing only two cells of mesh.

1  cellIds=[1,2]
2  mesh2=mesh.buildPartOfMySelf(cellIds, True)
3  mesh3=mesh.buildPartOfMySelf(cellIds, False)
4  coordsArr2 = mesh2.getCoords()
5  assert coordsArr.isEqual( coordsArr2, 1e-13 ) # same nodes
6  coordsArr3 = mesh3.getCoords()
7  assert not coordsArr.isEqual( coordsArr3, 1e-13 ) # different nodes
8  assert mesh2.getNodeIdsOfCell(0) == mesh.getNodeIdsOfCell( cellIds[0]) # cell #1 was copied
9  assert mesh2.getNodeIdsOfCell(1) == mesh.getNodeIdsOfCell( cellIds[1]) # cell #2 was copied

Modify

Fixing orientation of "extruded" volumes

First, we create a mesh with 2 incorrectly oriented "extruded" volumes.

1  # 2D coordinates of 5 base nodes
2  coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2]
3  coordsArr=DataArrayDouble(coords,5,2)
4  # coordinates of 5 top nodes
5  coordsArr2 = coordsArr.deepCopy()
6  # 3D coordinates of base + top nodes
7  coordsArr = coordsArr.changeNbOfComponents( 3, 0 )
8  coordsArr2 = coordsArr2.changeNbOfComponents( 3, 1 )
9  coordsArr = DataArrayDouble.Aggregate([coordsArr,coordsArr2])
10  # mesh
11  mesh=MEDCouplingUMesh()
12  mesh.setCoords(coordsArr)
13  mesh.setMeshDimension(3)
14  mesh.allocateCells(2)
15  # connectivity of reversed HEXA8 and PENTA6
16  conn=[0,1,4,3, 5,6,9,8, 1,2,4, 6,7,9]
17  mesh.insertNextCell(NORM_HEXA8, 8,conn[0:0+8])
18  mesh.insertNextCell(NORM_PENTA6,6,conn[8:8+6])
19  mesh.finishInsertingCells()

Now we check that findAndCorrectBadOriented3DExtrudedCells() finds and fixes the reversed cells.

1  fixedCells = mesh.findAndCorrectBadOriented3DExtrudedCells()
2  assert len( fixedCells ) == 2 # 2 cells fixed
3  fixedCells = mesh.findAndCorrectBadOriented3DExtrudedCells()
4  assert len( fixedCells ) == 0 # no bad cells

Fixing orientation of polyhedra

First, we create a mesh with 2 polyhedra, one of which is incorrectly oriented. We create two "extruded" polyhedra and then convert them to correctly defined polyhedra.

1  # 2D coordinates of 5 base nodes
2  coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2]
3  coordsArr=DataArrayDouble(coords,5,2)
4  # coordinates of 5 top nodes
5  coordsArr2 = coordsArr.deepCopy()
6  # 3D coordinates of base + top nodes
7  coordsArr = coordsArr.changeNbOfComponents( 3, 0 )
8  coordsArr2 = coordsArr2.changeNbOfComponents( 3, 1 )
9  coordsArr = DataArrayDouble.Aggregate([coordsArr,coordsArr2])
10  # mesh
11  mesh=MEDCouplingUMesh()
12  mesh.setCoords(coordsArr)
13  mesh.setMeshDimension(3)
14  mesh.allocateCells(2)
15  # connectivity of a HEXA8 + a reversed PENTA6
16  conn=[0,3,4,1, 5,8,9,6, 1,2,4, 6,7,9]
17  mesh.insertNextCell(NORM_POLYHED, 8,conn[0:0+8]) # "extruded" polyhedron
18  mesh.insertNextCell(NORM_POLYHED,6,conn[8:8+6])
19  mesh.finishInsertingCells()
20  # fix connectivity of NORM_POLYHED's
21  mesh.convertExtrudedPolyhedra()

Now we check that arePolyhedronsNotCorrectlyOriented() finds one reversed cell. After that we fix it using orientCorrectlyPolyhedrons() and re-check the orientation of polyhedra.

1  badCells = mesh.arePolyhedronsNotCorrectlyOriented()
2  assert len( badCells ) == 1 # one polyhedron is KO
3  # fix invalid rolyherdons
4  mesh.orientCorrectlyPolyhedrons()
5  # re-check the orientation
6  badCells = mesh.arePolyhedronsNotCorrectlyOriented()
7  assert len( badCells ) == 0 # connectivity is OK

Fixing orientation of faces

First, we create a 2D mesh in 3D space with 3 QUAD4 and 2 TRI3 cells. Orientation of the cell #1 is reversed comparing with others.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)
14  mesh.changeSpaceDimension(3)

Now we check that are2DCellsNotCorrectlyOriented() finds one reversed face. After that we fix the incorrectly oriented cell using orientCorrectly2DCells() and re-check the orientation of cells.

1  vec = [0.,0.,-1.]
2  badCellIds=mesh.are2DCellsNotCorrectlyOriented( vec, False )
3  assert len( badCellIds ) == 1 # one cell is reversed
4  # fix orientation
5  mesh.orientCorrectly2DCells( vec, False )
6  # re-check orientation
7  badCellIds=mesh.are2DCellsNotCorrectlyOriented( vec, False )
8  assert len( badCellIds ) == 0 # the orientation is OK

Renumbering nodes in the connectivity array

First, we create a 2D mesh with 1 QUAD4 cell and with undefined coordinates of nodes.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(1)
4  conn=[4,3,2,1]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])
6  mesh.finishInsertingCells()

Now we use renumberNodesInConn() to get the following nodal connectivity of a sole cell: 0,1,2,3.

1  old2newIds = [-1,3,2,1,0]
2  mesh.renumberNodesInConn( old2newIds )
3  nodes0 = mesh.getNodeIdsOfCell( 0 )
4  assert nodes0 == [0,1,2,3]

old2newIds array defines how node ids are changed:

  • new id of node #0 is -1,
  • new id of node #1 is 3,
  • new id of node #2 is 4,
  • new id of node #3 is 1,
  • new id of node #4 is 0.

Renumbering nodes

First, we create a 2D mesh with 4 nodes and no cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.3]
4  coordsArr=DataArrayDouble(coords,4,2)
5  mesh.setCoords(coordsArr)
6  mesh.allocateCells(0)
7  mesh.finishInsertingCells()

Next, we use renumberNodes() to permute nodes so that

  • old node #0 becomes #2,
  • old node #1 remains #1,
  • old node #2 becomes #0,
  • old node #3 is removed.

Number of nodes becomes 3.

1  mesh.renumberNodes([ 2,1,0,-1 ], 3)
2  coordsArr = mesh.getCoords() # get a shorten array
3  assert coordsArr.getValues() == [0.7,-0.3, 0.2,-0.3, -0.3,-0.3]

Next we compare behavior of renumberNodes() and that of renumberNodes2() which, in contrast to renumberNodes(), moves merged nodes to their barycenter.
We set #2 as new id of old node #3 and expect that renumberNodes2() moves old nodes #0 and #3 to their barycenter (-0.3,0.0) which becomes position of node #2.

1  coordsArr.setValues(coords,4,2) # restore old nodes
2  mesh.renumberNodesCenter([ 2,1,0,2 ], 3)
3  coordsArr = mesh.getCoords() # get a shorten array
4  assert coordsArr.getValues() == [0.7,-0.3, 0.2,-0.3, -0.3,0.0]

Merging equal nodes

First, we create a 2D mesh with 1 QUAD4 and 2 TRI3 cells. The cells are based on 6 nodes of which 2 nodes fully coincide (#3 and #4) and 3 nodes are equal with precision 0.003.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7])
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10])
8  mesh.finishInsertingCells()
9  coords=[0.3,-0.301, # 0
10  0.2,-0.3, # 1
11  0.3,-0.302, # 2 ~~ 0
12  1.1,0.0, # 3
13  1.1,0.0, # 4 == 3
14  0.3,-0.303]# 5 ~~ 0
15  coordsArr=DataArrayDouble(coords,6,2)
16  mesh.setCoords(coordsArr)

Now we merge node duplicates using mergeNodes() and check values it returns.

1  arr,areNodesMerged,newNbOfNodes=mesh.mergeNodes(0.004)
2  assert arr.getValues() == [0, 1, 0, 2, 2, 0]
3  assert areNodesMerged
4  assert newNbOfNodes == 3

Contents of arr shows ids of old nodes after the merging. The nodes considered equal one to the other have the same id in arr.

Next we compare behavior of mergeNodes() and that of mergeNodes2() which, in contrast to mergeNodes(), moves merged nodes to their barycenter.
We expect that mergeNodes2() moves old nodes #0, #2 and #5 to their barycenter equal to position of node #2.
First we check that mergeNodes() does not move nodes coincident with the node #2 to the position of node #2, and then we check that mergeNodes2() does move. (We check only the second (Y) component of node coordinates since the first component of these nodes is exactly same.)

1  baryCoords2 = coords[2*2:] # initial coordinates of node #2
2  coordsArr = mesh.getCoords() # retrieve a new shorten coord array
3  self.assertNotAlmostEqual( baryCoords2[1], coordsArr.getIJ(0,1), 13 ) # Y of node #0 differs from that of baryCoords2
4  # restore coordinates
5  coordsArr = DataArrayDouble(coords,6,2)
6  mesh.setCoords(coordsArr)
7  # call mergeNodesCenter()
8  mesh.mergeNodesCenter(0.004)
9  coordsArr = mesh.getCoords() # retrieve a new shorten coord array
10  self.assertAlmostEqual( baryCoords2[1], coordsArr.getIJ(0,1), 13 ) # Y of node #0 equals to that of baryCoords2

Removing cell duplicates

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells, so that

  • the cell #2 has the same nodal connectivity as the cell #1 does,
  • the cell #3 has the same nodal connectivity as the cell #0 does,
  • the cell #4 is based on the same nodes as the cell #0 but nodes order is different.
1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 2 == 1
8  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 3 == 0
9  mesh.insertNextCell(NORM_QUAD4,4,conn[2:4]+conn[0:2]) # 4 ~~ 0
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we use zipConnectivityTraducer() to remove duplicate cells. Then we check that two cells, having exactly same nodal connectivity with other cells, have been removed.

1  oldNbCells = mesh.getNumberOfCells()
2  arr = mesh.zipConnectivityTraducer(0)
3  assert mesh.getNumberOfCells() == oldNbCells-2
4  assert arr.getValues() == [0, 1, 1, 0, 2]

Contents of arr shows ids of cells after duplicates removal. If a value (cell id) equals to its index in arr, this means that the cell is not a duplicate of any cell with lower id. Else, the value gives a cell id to which this cell is equal.
Thus, the cells #0 and #1 have no preceding equal cell since arr[i] == i.
The cell #2 equals to the cell #1 (== arr[2] ).
The cell #3 equals to the cell #0 (== arr[3] ).
The cell #4 has no equal cell. This is because the cell comparison technique specified when we called zipConnectivityTraducer() was 0 ("exact"), if we had used the technique 2 ("nodal"), arr[4] would be 0.

Removing unused nodes

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7])
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10])
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14])
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18])
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we create mesh2 including all nodes but only two cells of mesh, and we use zipCoordsTraducer() to remove unused nodes from mesh2. zipCoordsTraducer() returns an array with -1 for unused nodes and new ids for used ones.

1  cellIds=[1,2]
2  mesh2=mesh.buildPartOfMySelf(cellIds,True)
3  arr=mesh2.zipCoordsTraducer()
4  assert mesh2.getNumberOfNodes() == 4 # nb of nodes decreased
5  assert arr.getValues() == [-1,0,1,-1,2,3,-1,-1,-1] # -1 for unused nodes

Retrieving unused nodes

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7])
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10])
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14])
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18])
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we create mesh2 including all nodes but only two cells of mesh, and we use getNodeIdsInUse() to get nodes of mesh2 used in its two cells. getNodeIdsInUse() returns an array with -1 for unused nodes and new ids for used ones.

1  cellIds=[1,2]
2  mesh2=mesh.buildPartOfMySelf(cellIds,True)
3  arr,newNbOfNodes=mesh2.getNodeIdsInUse()
4  assert arr.getValues() == [-1,0,1,-1,2,3,-1,-1,-1]

Now we use newNbOfNodes returned by getNodeIdsInUse() to convert arr to "New to Old" mode.

1  arr2=arr.invertArrayO2N2N2O(newNbOfNodes)
2  assert arr2.getValues() == [1,2,4,5]

Conversion of cells to "poly" types

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we convert cells #1 and #3 to type POLYGON and check the result

1  cells=[1,3]
2  mesh.convertToPolyTypes(cells)
3  assert mesh.getTypeOfCell(0) == NORM_QUAD4
4  assert mesh.getTypeOfCell(1) == NORM_POLYGON, mesh.getTypeOfCell(1)
5  assert mesh.getTypeOfCell(2) == NORM_TRI3
6  assert mesh.getTypeOfCell(3) == NORM_POLYGON

Scaling the mesh

First, we create a 2D mesh with 4 nodes and no cells.

1  coords=[0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0] # 2D coordinates of 4 nodes
2  coordsArr=DataArrayDouble(coords,4,2)
3  mesh=MEDCouplingUMesh()
4  mesh.setCoords(coordsArr)
5  initCoords = coordsArr.deepCopy()

Then we scale it by a factor of 2 with a center (0.,0.).

1  center = [0.,0.]
2  factor = 2.
3  mesh.scale(center,factor)

Finally we check that all node coordinates have changed by more than 0.9.

1  coords2 = mesh.getCoords()
2  assert coords2.isEqualWithoutConsideringStr( initCoords, 1.0 )
3  assert not coords2.isEqualWithoutConsideringStr( initCoords, 0.9 )

Translating the mesh

First, we create a 2D mesh with 4 nodes and no cells.

1  coords=[0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0] # 2D coordinates of 4 nodes
2  coordsArr=DataArrayDouble(coords,4,2)
3  mesh=MEDCouplingUMesh()
4  mesh.setCoords(coordsArr)
5  initCoords = coordsArr.deepCopy()

Then we translate it by a vector (1.,1.).

1  vector = [1.,1.]
2  mesh.translate(vector)

Finally we check that all node coordinates have changed by more than 0.9.

1  coords2 = mesh.getCoords()
2  assert coords2.isEqualWithoutConsideringStr( initCoords, 1 )
3  assert not coords2.isEqualWithoutConsideringStr( initCoords, 0.9 )

Rotating the mesh

First, we create a 2D mesh with 4 nodes and no cells.

1  coords=[0.0,0.0, 0.1,0.0, 0.1,0.1, 0.0,0.1] # 2D coordinates of 4 nodes
2  coordsArr=DataArrayDouble(coords,4,2)
3  mesh=MEDCouplingUMesh()
4  mesh.setCoords(coordsArr)

Then we rotate it around a point (0.,0.) by 90 degrees clockwise.

1  center = [0.,0.]
2  mesh.rotate(center,-pi/2)

Next, we make a 3D mesh from the 2D one and rotate it around the Z axis by 90 degrees counter-clockwise.

1  mesh.changeSpaceDimension(3)
2  center = [0.,0.,0.]
3  vector = [0.,0.,1.]
4  mesh.rotate(center,vector,pi/2)

Finally we transform the mesh back to 2D space and check that all nodes get back to the initial location.

1  mesh.changeSpaceDimension(2)
2  coords2 = mesh.getCoords()
3  for i,c in enumerate( coords ):
4  self.assertAlmostEqual( c, coords2.getIJ(0,i), 13 )

Access

Getting node coordinates along an axis

We create an 1D Cartesian mesh and retrieves node coordinates using getCoordsAt().

1  coords = [1.,2.,4.]
2  x=DataArrayDouble(coords,3,1)
3  mesh=MEDCouplingCMesh()
4  mesh.setCoordsAt(0,x)
5  x2=mesh.getCoordsAt(0)
6  assert coords == x2.getValues()

Getting coordinates of a node

The following code creates a 2D MEDCouplingUMesh with 3 nodes and no cells.

1  coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3]
2  coordsArr=DataArrayDouble(coords,3,2)
3  mesh=MEDCouplingUMesh()
4  mesh.setCoords(coordsArr)

Here we get coordinates of the second node and check its two coordinates.

1  nodeCoords=mesh.getCoordinatesOfNode(1)
2  self.assertAlmostEqual(0.2, nodeCoords[0],13)
3  self.assertAlmostEqual(-0.3,nodeCoords[1],13)

Cells correspondence in two meshes

First, we create a 2D mesh1 with 3 QUAD4 and 2 TRI3 cells.

1  mesh1=MEDCouplingUMesh()
2  mesh1.setMeshDimension(2)
3  mesh1.allocateCells(5)
4  conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh1.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh1.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh1.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh1.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh1.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh1.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh1.setCoords(coordsArr)

Then we create a mesh2 which includes cells #4, #2 and #0 of mesh1. The two meshes share the same node coordinates array.

1  cells2 = [ 4,2,0 ]
2  mesh2 = mesh1.buildPartOfMySelf(cells2, True ) # even cells selected

Now we ascertain that

  • areCellsIncludedIn() detects that all cells of mesh2 are present in mesh1,
  • the correspondence array corr2to1, which gives cell ids of mesh2 within mesh1, is equal to the array cells2 which selected cells from mesh1 for creation of mesh2.
1  compType = 0 # the strongest policy
2  isOk, corr2to1 = mesh1.areCellsIncludedIn( mesh2, compType )
3  assert isOk # a larger mesh1 includes a smaller mesh2
4  assert corr2to1.getValues() == cells2

Now we apply areCellsIncludedIn() in a reverse direction and ascertain that it returns false.

1  isOk, corr1to2 = mesh2.areCellsIncludedIn( mesh1, compType )
2  assert not isOk # the smaller mesh2 does NOT include the larger mesh1
3  assert corr1to2.getValues() == [2, 3, 1, 4, 0]

The contents of the correspondence array corr1to2 [2, 3, 1, 4, 0] means the following.

  • The cell #0 of mesh1 is equal to the cell #2 (== corr1to2[ 0 ]) of mesh2.
  • The cell #1 of mesh1 is missing from mesh2 (as corr1to2[ 1 ] >= mesh2->getNumberOfCells()).
  • The cell #2 of mesh1 is equal to the cell #1 (== corr1to2[ 2 ]) of mesh2.
  • The cell #3 of mesh1 is missing from mesh2 (as corr1to2[ 3 ] >= mesh2->getNumberOfCells()).
  • The cell #4 of mesh1 is equal to the cell #0 (== corr1to2[ 4 ]) of mesh2.

Deep comparison of meshes

First, we create two 2D meshes with two triangles, so that

  • their nodes are almost same but permuted,
  • the first triangle is based exactly on the same nodes (taking the permutation into account),
  • an order of nodes in the second triangle is changed.
1  # mesh 1
2  mesh1=MEDCouplingUMesh()
3  mesh1.setMeshDimension(2)
4  coords=[0.0,0.0, #0
5  1.0,0.0, #1
6  1.0,1.0, #2
7  0.0,1.0] #3
8  coordsArr=DataArrayDouble(coords,4,2)
9  mesh1.setCoords(coordsArr)
10  mesh1.allocateCells(2)
11  mesh1.insertNextCell(NORM_TRI3,3,[0,1,2]) #0
12  mesh1.insertNextCell(NORM_TRI3,3,[1,2,3]) #1
13  mesh1.finishInsertingCells()
14  # mesh 2
15  mesh2=MEDCouplingUMesh()
16  mesh2.setMeshDimension(2)
17  coords=[0.0,1.0, #0 = #3
18  0.0,0.0, #1 = #0
19  1.0,0.0, #2 = #1
20  1.0,1.001] #3 ~ #2
21  coordsArr2=DataArrayDouble(coords,4,2)
22  mesh2.setCoords(coordsArr2)
23  mesh2.allocateCells(2)
24  mesh2.insertNextCell(NORM_TRI3,3,[2,3,0]) #0 = #1
25  mesh2.insertNextCell(NORM_TRI3,3,[3,1,2]) #1 ~ #0
26  mesh2.finishInsertingCells()

Then we check that

  • checkDeepEquivalWith() considers the meshes equal (i.e. it does not throw any exception) if it is called with a cell comparison policy cellCompPol == 1
  • mapping from mesh1 to mesh2 for both nodes and cells is as expected.
1  cellCompPol = 1 # "permuted same orientation" - policy of medium severity
2  cOld2New, nOld2New = mesh1.checkDeepEquivalWith( mesh2, cellCompPol, 0.002 )
3  assert nOld2New.getValues() == [3, 0, 1, 2]
4  assert cOld2New.getValues() == [1, 0]

Next we ascertain that checkDeepEquivalOnSameNodesWith() consider mesh1 and mesh2 different as they do not share the same nodal connectivity array.
After that we make the meshes share the node coordinates array and insert new triangles based on the same nodes but in different order. This is to ascertain that checkDeepEquivalOnSameNodesWith() called with the weakest cell comparison policy considers the meshes equal.

1  self.assertRaises( InterpKernelException, mesh1.checkDeepEquivalOnSameNodesWith, mesh2, cellCompPol, 0.002)
2  mesh2.setCoords(coordsArr) # make meshes share the same coordinates array
3  mesh2.allocateCells(2)
4  mesh2.insertNextCell(NORM_TRI3,3,[1,2,3]) #0 = #1
5  mesh2.insertNextCell(NORM_TRI3,3,[1,0,2]) #1 ~ #0
6  mesh2.finishInsertingCells()
7  cellCompPol = 2 # the weakest policy
8  mesh1.checkDeepEquivalOnSameNodesWith( mesh2, cellCompPol, 0 )

Getting barycenters of cells

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we use getPartBarycenterAndOwner() to get barycenters of all but the first cell.

1  part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted
2  baryCenters = mesh.getPartBarycenterAndOwner( part )
3  assert len( baryCenters ) == len( part )
4  assert baryCenters.getNumberOfComponents() == mesh.getSpaceDimension()

The returned array contains 4 tuples per 2 components.

Finding cells containing a point (multi-point case)

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Then we use getCellsContainingPoints() to get cells in contact with tree points. Two of them are in contact with some cells and one is not.

1  pos = [ 10., 10, # point out of the mesh
2  0.3, 0.3, # point located somewhere inside the mesh
3  coords[2], coords[3]] # point at the node #1
4  eps = 1e-4 # ball radius
5  cells,cellsIndex=mesh.getCellsContainingPoints( pos, 3, eps )
6  assert cells.getValues() == [4, 0, 1]
7  assert cellsIndex.getValues() == [0, 0, 1, 3]

The contents of the result arrays cells ([4, 0, 1]) and cellsIndex ([0, 0, 1, 3]) mean the following.

  • Point #0 is in contact with none (== cellsIndx[1] - cellsIndx[0]) cell.
  • Point #1 is in contact with 1 (== cellsIndx[2] - cellsIndx[1]) cell whose id is #4 (== cells[ cellsIndx[ 1 ]]).
  • Point #2 is in contact with 2 (== cellsIndx[3] - cellsIndx[2]) cells whose ids are #0 (== cells[ cellsIndx[ 2 ]]) and #1 (== cells[ cellsIndx[ 2 ] + 1 ]).

Finding cells containing a point

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7])
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10])
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14])
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18])
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Then we use getCellsContainingPoint() to get cells in contact with a small ball (point with precision) located near the node #4 and shifted from this node by its radius eps.

1  pos4 = coords[ 4*2 : ] # coordinates of the node #4
2  eps = 1e-4 # ball radius
3  pos = [ pos4[0]+eps, pos4[1]-eps ] # ball center
4  cellIds=mesh.getCellsContainingPoint( pos, eps )
5  assert len( cellIds ) == mesh.getNumberOfCells()

Since the node #4 is shared by all cells, size of the vector cellIds must be equal to the number of cells in mesh.

Getting normals of cells

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. Orientation of the cell #1 is reversed.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we use buildPartOrthogonalField() to get normal vectors to the cells.

1  part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted
2  vecField=mesh.buildPartOrthogonalField( part )
3  vecArr = vecField.getArray()
4  assert len( vecArr ) == len( part )
5  assert vecArr.getNumberOfComponents() == 3

Getting volumes of cells

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. Orientation of the cell #1 is reversed.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we use getPartMeasureField() to get volumes of all but the first cell. If we call getPartMeasureField() with isAbs == true, the area of the cell #1 is returned positive, else, negative that reflects its inverse orientation.

1  isAbs = True
2  part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted
3  areaArr=mesh.getPartMeasureField( isAbs, part )
4  assert areaArr[0] > 0 # orientation ignored
5  areaArr=mesh.getPartMeasureField( not isAbs, part )
6  assert areaArr[0] < 0 # orientation considered
7  assert len( areaArr ) == len( part )

Getting cells using the bounding box

First, we create a 2D mesh with 1 TRI3 cell. Bounding box of this cell is [0.,0., 1.,1].

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  coords=[0.,0., 0.,1., 1.,1]
4  coordsArr=DataArrayDouble(coords,3,2)
5  mesh.setCoords(coordsArr)
6  mesh.allocateCells(1)
7  conn=[0,1,2]
8  mesh.insertNextCell(NORM_TRI3,3,conn)
9  mesh.finishInsertingCells()

Now we check how getCellsInBoundingBox() searches for cells using the bounding box. We use a bounding box touching the bounding box of the sole cell at one point (1.,1.).

1  bbox = [1., 1., 1.001,1.001] # xMin, xMax, yMin, yMax
2  cellsInBox = mesh.getCellsInBoundingBox( bbox, 0.0 )
3  assert cellsInBox.getValues() == []
4  cellsInBox = mesh.getCellsInBoundingBox( bbox, 0.1 )
5  assert cellsInBox.getValues() == [0]

If getCellsInBoundingBox() is called with parameter eps == 0.0, the cell is not found because the two bounding boxes (one of the cell and the one passed as parameter) do not overlap.
If getCellsInBoundingBox() is called with parameter eps == 0.1, the cell is found because eps is used to increase the bounding box of the cell and thus the two bounding boxes intersect each other.

Getting boundary nodes

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7])
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10])
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14])
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18])
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we use findBoundaryNodes() to get ids of boundary nodes.

1  nodeIdsArr=mesh.findBoundaryNodes()
2  assert nodeIdsArr.getNumberOfTuples() == mesh.getNumberOfNodes() - 1

findBoundaryNodes() returns all node ids except the node #4 which is in the middle of mesh.

Getting cells by nodes

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

In the following code we retrieve nodes of the cell #0 an then we call getCellIdsLyingOnNodes() twice with these nodes and with varying last parameter allNodes as input.

1  nodeIds = mesh.getNodeIdsOfCell( 0 )
2  allNodes = True
3  cellIdsArr1 = mesh.getCellIdsLyingOnNodes( nodeIds, allNodes )
4  cellIdsArr2 = mesh.getCellIdsLyingOnNodes( nodeIds, not allNodes )
5  assert cellIdsArr1.getNumberOfTuples() == 1 # cell #0 is found only
6  assert cellIdsArr2.getNumberOfTuples() == mesh.getNumberOfCells() # all cells are found


If the last parameter is true getCellIdsLyingOnNodes() looks for cells whose all nodes are given to it, hence it finds the cell #0 only.
If the last parameter is false getCellIdsLyingOnNodes() looks for any cell whose nodes are given to it, hence it finds all cells of mesh because all cells share the node #4.

Getting cells by nodes

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4])
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7])
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10])
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14])
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18])
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

In the following code we retrieve nodes of two cells an then we use getCellIdsFullyIncludedInNodeIds() to find these cells by their nodes.

1  cellIds = [1,2]
2  nodeIds = mesh.getNodeIdsOfCell( cellIds[0] )
3  nodeIds += mesh.getNodeIdsOfCell( cellIds[1] )
4  cellIdsArr = mesh.getCellIdsFullyIncludedInNodeIds( nodeIds )
5  assert cellIdsArr.getValues() == cellIds

Retrieving the descending connectivity with orientation

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we get and check the descending connectivity.

1  mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity2()
2  assert desc.getValues() == [1,2,3,4,-3,5,6, 7,8,-5,9,10,-2,11, 12,13,-7,-10]
3  assert descIndx.getValues() == [0,4,7,10,14,18]
4  assert revDesc.getValues() == [0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4]
5  assert revDescIndx.getValues() == [0,1,3,5,6,8,9,11,12,13,15,16,17,18]

Here we get connectivity of the cell #2 (#3 in FORTRAN mode) of mesh2 to see how mutual orientation of cells in mesh and mesh2 is defined.

1  assert mesh2.getNodeIdsOfCell( 3-1 ) == [4, 1] # cell #3 in FORTRAN mode

The contents of the result arrays desc and descIndx mean the following.

  • The cell #0 of mesh (QUAD4) is bound by 4 (== descIndx[1] - descIndx[0]) segments (SEG2) of mesh2 whose ids in FORTRAN mode are
    • #1 (== desc[ descIndx[ 0 ]]),
    • #2 (== desc[ descIndx[ 0 ] + 1 ]),
    • #3 (== desc[ descIndx[ 0 ] + 2 ]) and
    • #4 (== desc[ descIndx[ 0 ] + 3 ]).
      Ids are positive since order of nodes in the corresponding cells of mesh and mesh2 are same. For example nodes of SEG2 #3 are [4,1] and nodes of QUAD4 #0 are [0,3,4,1].
  • The cell #1 of mesh (TRI3) is bound by 3 (== descIndx[2] - descIndx[1]) segements of mesh2 whose ids in FORTRAN mode are:
    • #-3 (== desc[ descIndx[ 1 ]]),
    • #5 (== desc[ descIndx[ 1 ] + 1 ]) and
    • #6 (== desc[ descIndx[ 1 ] + 2 ]).
      The id -3 means that order of nodes in SEG2 #3 ([4,1]) is different from the order of these nodes in TRI3 #1: [1,4,2].
  • etc.

The contents of the result arrays revDesc and revDescIndx mean the following.

  • The cell #0 of mesh2 (SEG2) bounds 1 (== revDescIndx[1] - revDescIndx[0]) cell of mesh whose id is:
    • # 0 (== revDesc[ revDescIndx[ 0 ]]).
  • The cell #1 of mesh2 bounds 2 (== revDescIndx[2] - revDescIndx[1]) cells of mesh whose ids are:
    • # 0 (== revDesc[ revDescIndx[ 1 ]]) and
    • # 1 (== revDesc[ revDescIndx[ 1 ] + 1 ]).
  • etc.

Retrieving the descending connectivity

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we get and check the descending connectivity.

1  mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity()
2  assert desc.getValues() == [0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9]
3  assert descIndx.getValues() == [0,4,7,10,14,18]
4  assert revDesc.getValues() == [0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4]
5  assert revDescIndx.getValues() == [0,1,3,5,6,8,9,11,12,13,15,16,17,18]

The contents of the result arrays desc and descIndx mean the following.

  • The cell #0 of mesh (QUAD4) is bound by 4 (== descIndx[1] - descIndx[0]) segments (SEG2) of mesh2 whose ids are
    • #0 (== desc[ descIndx[ 0 ]]),
    • #1 (== desc[ descIndx[ 0 ] + 1 ]),
    • #2 (== desc[ descIndx[ 0 ] + 2 ]) and
    • #3 (== desc[ descIndx[ 0 ] + 3 ]).
  • The cell #1 of mesh (TRI3) is bound by 3 (== descIndx[2] - descIndx[1]) segements of mesh2 whose ids are:
    • #2 (== desc[ descIndx[ 1 ]]),
    • #4 (== desc[ descIndx[ 1 ] + 1 ]) and
    • #5 (== desc[ descIndx[ 1 ] + 2 ]).
  • etc.

The contents of the result arrays revDesc and revDescIndx mean the following.

  • The cell #0 of mesh2 (SEG2) bounds 1 (== revDescIndx[1] - revDescIndx[0]) cell of mesh whose id is:
    • # 0 (== revDesc[ revDescIndx[ 0 ]]).
  • The cell #1 of mesh2 bounds 2 (== revDescIndx[2] - revDescIndx[1]) cells of mesh whose ids are:
    • # 0 (== revDesc[ revDescIndx[ 1 ]]) and
    • # 1 (== revDesc[ revDescIndx[ 1 ] + 1 ]).
  • etc.

Getting the reverse nodal connectivity

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells.

1  mesh=MEDCouplingUMesh()
2  mesh.setMeshDimension(2)
3  mesh.allocateCells(5)
4  conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
5  mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0
6  mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1
7  mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2
8  mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3
9  mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4
10  mesh.finishInsertingCells()
11  coords=[-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 ]
12  coordsArr=DataArrayDouble(coords,9,2)
13  mesh.setCoords(coordsArr)

Now we get and check its reverse nodal connectivity.

1  revNodal,revNodalIndx=mesh.getReverseNodalConnectivity()
2  assert revNodal.getValues() == [0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4]
3  assert revNodalIndx.getValues() == [0,1,3,5,7,12,14,15,17,18]

The contents of the result arrays mean the following.

  • Node #0 is shared by 1 (== revNodalIndx[1] - revNodalIndx[0]) cell whose id is #0 (== revNodal[ revNodalIndx[ 0 ]]).
  • Node #1 is shared by 2 (== revNodalIndx[2] - revNodalIndx[1]) cells whose ids are #0 (== revNodal[ revNodalIndx[ 1 ]]) and #1 (== revNodal[ revNodalIndx[ 1 ] + 1 ]).
  • etc.

Getting a minimum box bounding nodes

First, we create a 3D mesh with 2 nodes, so that the first one has minimal coordinates and the second one has maximal coordinates.

1  cc=[0.0, 0.1, 0.2, # 3D coordinates of 2 nodes
2  2.0, 2.1, 2.2]
3  coordsArr=DataArrayDouble(cc,2,3)
4  mesh=MEDCouplingUMesh()
5  mesh.setCoords(coordsArr)

Now we get a bounding box enclosing these nodes. This bounding box should contain coordinates of our two nodes (but in "no interlace" mode), as the nodes coincide with points returned by the bounding box.

1  bbox=mesh.getBoundingBox()
2  assert bbox == [( cc[0], cc[3] ), # NOTE: list of 3 tuples is retirned!
3  ( cc[1], cc[4] ),
4  ( cc[2], cc[5] )]

Getting nodes close to a point

The following code creates a 2D MEDCouplingUMesh with 5 nodes and no cells.

1  # 2D coordinates of 5 nodes
2  coords=[0.3,-0.301, # 0
3  0.2,-0.3, # 1
4  0.3,-0.302, # 2
5  1.1,0.0, # 3
6  0.3,-0.30299999999999]# 4
7  coordsArr=DataArrayDouble(coords,5,2)
8  mesh=MEDCouplingUMesh()
9  mesh.setCoords(coordsArr)

Now we define an array of coordinates of a point close to nodes #0, #2 and #4.

Thus we expect that getNodeIdsNearPoint() that we are going to use, if called with eps = 0.003, would return ids of nodes #0, #2 and #4.

1  point=[0.3, -0.3] # point close to nodes #0, #2 and #4
2  ids=mesh.getNodeIdsNearPoint(point,0.003)
3  assert ids.getValues() == [0,2,4]

Getting nodes close to some points

The following code creates a 2D MEDCouplingUMesh with 7 nodes and no cells.

1  # 2D coordinates of 7 nodes
2  coords=[0.3,-0.301, # 0
3  0.2,-0.3, # 1
4  0.3,-0.302, # 2
5  1.1,0.0, # 3
6  1.1,0.0, # 4
7  1.1,0.002, # 5
8  0.3,-0.303]# 6
9  coordsArr=DataArrayDouble(coords,7,2)
10  mesh=MEDCouplingUMesh()
11  mesh.setCoords(coordsArr)

Now we define an array of coordinates of 3 points near which we want to find nodes of the mesh.

  • Point #0 is at distance 0.001 from the node #1.
  • Point #1 is rather far from all nodes.
  • Point #2 is close to nodes #3, #4 and #5.

Thus we expect that getNodeIdsNearPoints() that we are going to use, if called with eps = 0.003, would return ids of close nodes #1, #3, #4 and #5.

1  points=[0.2,-0.301, # ~ node #1
2  0.0, 0.0,
3  1.1, 0.002] # ~ nodes #3, #4 and #5
4  ids,idsIndex=mesh.getNodeIdsNearPoints(points,3,0.003)
5  assert ids.getValues() == [1, 3, 4, 5]
6  assert idsIndex.getValues() == [0, 1, 1, 4]

idsIndex returns [0, 1, 1, 4] which means that:

  • Point #0 is close to 1 (== idsIndex[1] - idsIndex[0]) node whose id is ids[ idsIndex[ 0 ]].
  • Point #1 is close to 0 (== idsIndex[2] - idsIndex[1]) nodes.
  • Point #2 is close to 3 (== idsIndex[3] - idsIndex[2]) nodes whose ids are ids[ idsIndex[ 2 ]], ids[ idsIndex[ 2 ] + 1 ] and ids[ idsIndex[ 2 ] + 2 ].

Finding coincident nodes

First, we create a mesh with 6 nodes, of which two nodes (#3 and #4) are fully coincident and 3 nodes (#0, #2 and #5) have distance less than 0.004 between them.

1  coords=[0.3,-0.301, # 0
2  0.2,-0.3, # 1
3  0.3,-0.302, # 2
4  1.1,0.0, # 3
5  1.1,0.0, # 4
6  0.3,-0.303]# 5
7  coordsArr=DataArrayDouble(coords,6,2)
8  mesh=MEDCouplingUMesh()
9  mesh.setCoords(coordsArr)

Then, we use findCommonNodes() to find coincident nodes, and check that (1) calling findCommonNodes() with prec == 1e-13 finds the two fully coincident nodes only and (2) findCommonNodes(0.004) finds 5 equal nodes.

1  comm,commI=mesh.findCommonNodes(1e-13)
2  assert comm.getValues() == [3,4]
3  comm,commI=mesh.findCommonNodes(0.004)
4  assert comm.getValues() == [0,2,5,3,4]

Arrays

Create

Building an array from scratch in Python

Building a double array from scratch in Python

Let's consider a list of floats dataDouble.

1  dataDouble=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.]

The easiest way to build the DataArrayDouble instance called arrayDouble simply call :

1  arrayDouble=DataArrayDouble(dataDouble,5,3)

An another way is to do that :

1  arrayDouble=DataArrayDouble()
2  arrayDouble.setValues(dataDouble,5,3)# 5 tuples containing each 3 components

Building an int array from scratch in Python

Let's consider a list of ints dataInt.

1  dataInt=[0, 10, 20, 1, 11, 21, 2, 12, 22, 3, 13, 23, 4, 14, 24]

The easiest way to build the DataArrayInt instance called arrayInt simply call :

1  arrayInt=DataArrayInt(dataInt,5,3)

An another way is to do that :

1  arrayInt=DataArrayInt()
2  arrayInt.setValues(dataInt,5,3)# 5 tuples containing each 3 components

Building a permutation array

Here we create two arrays containing same values but in different order and then we use DataArrayInt::buildPermutationArr() to get an array showing in what places the values of b array are located in a array.

1  a=DataArrayInt()
2  a.setValues([4,5,6,7,8],5,1)
3  b=DataArrayInt()
4  b.setValues([5,4,8,6,7],5,1)
5  c=a.buildPermutationArr(b)

The result array c contains [1,0,4,2,3].

Modify

Inverting renumbering maps

invertArrayO2N2N2O()

In this example we create a DataArrayInt containing a renumbering map in "Old to New" mode, convert it into the renumbering map in "New to Old" mode and check the result.

1  arr1=[2,0,4,1,5,3]
2  da=DataArrayInt()
3  da.setValues(arr1,6,1)
4  da2=da.invertArrayO2N2N2O(6)
5  expected1=[1,3,0,5,2,4]
6  for i in xrange(6):
7  self.assertEqual(expected1[i],da2.getIJ(i,0))
8  pass


invertArrayN2O2O2N()

In this example we create a DataArrayInt containing a renumbering map in "New to Old" mode, convert it into the renumbering map in "Old to New" mode and check the result.

1  arr1=[2,0,4,1,5,3]
2  da=DataArrayInt()
3  da.setValues(arr1,6,1)
4  da2=da.invertArrayN2O2O2N(7)
5  expected1=[1,3,0,5,2,4,-1]
6  for i in xrange(6):
7  self.assertEqual(expected1[i],da2.getIJ(i,0))
8  pass

Set part of values of DataArrayDouble

setSelectedComponents()

First, we create a 'source' array.

1  array1=[1.,2., 3.,4., 5.,6.]
2  da=DataArrayDouble(array1,3,2)
3  da.setInfoOnComponents( ["a1","a2"])

Now we create a larger zero array and assign the array da into it.

1  dv=DataArrayDouble()
2  dv.alloc( 4, 4 )
3  dv.fillWithZero()
4  dv.setInfoOnComponents( ["v1","v2","v3","v4"])
5  dv2 = dv.deepCopy()
6  dv.setSelectedComponents( da, [1,0] )

As result contents of the array dv are as follows.

Info of components : "a2"   "a1"   "v3"   "v4"
    Tuple #0 : 2 1 0 0
    Tuple #1 : 4 3 0 0
    Tuple #2 : 6 5 0 0
    Tuple #3 : 0 0 0 0

The same result can be achieved other way (except that component info is not copied):

1  dv2[:3,[1,0]] = da
2  self.assertTrue( dv.isEqualWithoutConsideringStr( dv2, 1e-20 ))


setPartOfValues1()

We create two arrays:

  • a "large" (4x4) zero array da to assign to and
  • a smaller (2x2) array dv filled with values [7.,8.,9.,10].
1  da=DataArrayDouble()
2  da.alloc( 4, 4 )
3  da.setInfoOnComponents( ["v1","v2","v3","v4"])
4  #
5  dv=DataArrayDouble()
6  dv.alloc( 4, 1 )
7  dv.iota(7)
8  dv.rearrange( 2 )
9  dv.setInfoOnComponents( ["a1","a2"])

Now we copy dv to the middle of da.

1  da.fillWithZero()
2  da.setPartOfValues1( dv, 1,3,1, 1,3,1, True )

As result contents of the array da are as follows.

    Info of components :"v1"   "v2"   "v3"   "v4"
    Tuple #0 : 0 0 0 0
    Tuple #1 : 0 7 8 0
    Tuple #2 : 0 9 10 0
    Tuple #3 : 0 0 0 0

Here we re-fill da with zeros and copy dv into a component of da.

Note that the last parameter strictCompoCompare should be False in this case, else MEDCoupling::DataArrayDouble::setPartOfValues1() throws an exception because da has 2 components but only one target component is specified.

1  da.fillWithZero()
2  da.setPartOfValues1( dv, 0,4,1, 1,2,1, False )
    Tuple #0 : 0 7 0 0
    Tuple #1 : 0 8 0 0
    Tuple #2 : 0 9 0 0
    Tuple #3 : 0 10 0 0

Below more two variants of location of target values are shown.

1  da.fillWithZero()
2  da.setPartOfValues1( dv, 1,2,1, 0,4,1, False )
    Tuple #0 : 0 0 0 0
    Tuple #1 : 7 8 9 10
    Tuple #2 : 0 0 0 0
    Tuple #3 : 0 0 0 0
1  da.fillWithZero()
2  da.setPartOfValues1( dv, 0,3,2, 1,4,2, True )
    Tuple #0 : 0 7 0 8
    Tuple #1 : 0 0 0 0
    Tuple #2 : 0 9 0 10
    Tuple #3 : 0 0 0 0

The same result can be achieved other way:

1  da2 = da.deepCopy()
2  da2.fillWithZero()
3  da2[ 0:3:2, 1:4:2 ] = dv
4  self.assertTrue( da.isEqual( da2, 1e-20 ))


setPartOfValuesSimple1()

We create an array (4x4) da to assign to and define a value dv to assign.

1  da=DataArrayDouble()
2  da.alloc( 4, 4 )
3  dv = 7

Now we assign dv to the middle of da.

1  da.fillWithZero()
2  da.setPartOfValuesSimple1( dv, 1,3,1, 1,3,1 )

As result contents of the array da are as follows.

    Tuple #0 : 0 0 0 0
    Tuple #1 : 0 7 7 0
    Tuple #2 : 0 7 7 0
    Tuple #3 : 0 0 0 0

Here we re-fill da with zeros and assign dv to a component of da.

1  da.fillWithZero()
2  da.setPartOfValuesSimple1( dv, 0,4,1, 1,2,1 )
    Tuple #0 : 0 7 0 0
    Tuple #1 : 0 7 0 0
    Tuple #2 : 0 7 0 0
    Tuple #3 : 0 7 0 0

Below more two variants of location of target values are shown.

1  da.fillWithZero()
2  da.setPartOfValuesSimple1( dv, 1,2,1, 0,4,1 )
    Tuple #0 : 0 0 0 0
    Tuple #1 : 7 7 7 7
    Tuple #2 : 0 0 0 0
    Tuple #3 : 0 0 0 0
1  da.fillWithZero()
2  da.setPartOfValuesSimple1( dv, 0,3,2, 1,4,2 )
    Tuple #0 : 0 7 0 7
    Tuple #1 : 0 0 0 0
    Tuple #2 : 0 7 0 7
    Tuple #3 : 0 0 0 0

The same result can be achieved other way:

1  da2 = da.deepCopy()
2  da2.fillWithZero()
3  da2[ 0:3:2, 1:4:2 ] = dv
4  self.assertTrue( da.isEqual( da2, 1e-20 ))


setPartOfValuesSimple2()

We create an array (4x4) da to assign to and define a value dv to assign.

1  da=DataArrayDouble()
2  da.alloc( 4, 4 )
3  dv = 7

Now we assign dv to the middle of da. We explicitly specify tuples and component to assign to by a list [1,2].

1  da.fillWithZero()
2  da[[1,2], [1,2]] = dv

As result contents of the array da are as follows.

    Tuple #0 : 0 0 0 0
    Tuple #1 : 0 7 7 0
    Tuple #2 : 0 7 7 0
    Tuple #3 : 0 0 0 0

Here we re-fill da with zeros and assign dv to a component of da.

1  da.fillWithZero()
2  da[[0,1,2,3], [1]] = dv
    Tuple #0 : 0 7 0 0
    Tuple #1 : 0 7 0 0
    Tuple #2 : 0 7 0 0
    Tuple #3 : 0 7 0 0

Below more two variants of location of target values are shown.

1  da.fillWithZero()
2  da[[1], [0,1,2,3]] = dv
    Tuple #0 : 0 0 0 0
    Tuple #1 : 7 7 7 7
    Tuple #2 : 0 0 0 0
    Tuple #3 : 0 0 0 0
1  da.fillWithZero()
2  da[[0,2], [1,3]] = dv
    Tuple #0 : 0 7 0 7
    Tuple #1 : 0 0 0 0
    Tuple #2 : 0 7 0 7
    Tuple #3 : 0 0 0 0
Note
MEDCoupling::DataArrayDouble::setPartOfValuesSimple2() can't be explicitly called in Python.


setPartOfValuesSimple3()

We create an array (4x4) da to assign to and define a value dv to assign.

1  da=DataArrayDouble()
2  da.alloc( 4, 4 )
3  dv = 7

Now we assign dv to the middle of da. We explicitly specify tuples to assign to by a list [1,2]. And we specify components to assign to using slicing: 1:3.

1  da.fillWithZero()
2  da[[1,2], 1:3] = dv

As result contents of the array da are as follows.

    Tuple #0 : 0 0 0 0
    Tuple #1 : 0 7 7 0
    Tuple #2 : 0 7 7 0
    Tuple #3 : 0 0 0 0

Here we re-fill da with zeros and assign dv to a component of da.

1  da.fillWithZero()
2  da[[0,1,2,3], 1:2] = dv
    Tuple #0 : 0 7 0 0
    Tuple #1 : 0 7 0 0
    Tuple #2 : 0 7 0 0
    Tuple #3 : 0 7 0 0

Below more two variants of location of target values are shown.

1  da.fillWithZero()
2  da[[1], 0:4] = dv
    Tuple #0 : 0 0 0 0
    Tuple #1 : 7 7 7 7
    Tuple #2 : 0 0 0 0
    Tuple #3 : 0 0 0 0
1  da.fillWithZero()
2  da[[0,2], 1:4:2] = dv
    Tuple #0 : 0 7 0 7
    Tuple #1 : 0 0 0 0
    Tuple #2 : 0 7 0 7
    Tuple #3 : 0 0 0 0
Note
MEDCoupling::DataArrayDouble::setPartOfValuesSimple3() can't be explicitly called in Python.


setPartOfValues2()

We create two arrays:

  • a "large" (4x7) zero array da to assign to,
  • a smaller (3x2) array dv filled with values [7.,8.,9.,10.,11.,12.].
1  da=DataArrayDouble()
2  da.alloc( 4, 7 )
3  #
4  dv=DataArrayDouble()
5  dv.alloc( 6, 1 )
6  dv.iota(7)
7  dv.rearrange( 2 )

Now we assign the two components of dv to the components of da with indices [1,3], and the 3 tuples of dv to the 3 tuples of da with indices [0,1,2]. This is the first mode of usage.

1  da.fillWithZero()
2  da[ [0,1,2], [1,3] ] = dv

As result contents of the array da are as follows.

    Tuple #0 : 0  7  0  8  0  0  0
    Tuple #1 : 0  9  0 10  0  0  0
    Tuple #2 : 0 11  0 12  0  0  0
    Tuple #3 : 0  0  0  0  0  0  0

Every value of dv has been assigned to its own location within da.

Now we re-fill da with zeros and rearrange dv to have 6 components. And we assign dv to the tuples of da with indices [0,2,3] . This is the second mode of usage.

1  da.fillWithZero()
2  dv.rearrange( 6 )
3  da[ [0,2,3], [0,2,3,4,5,6]] = dv

The contents of dv have been assigned to each of specified tuples of da. Every value of dv is repeated in the 3 specified tuples within da.

    Tuple #0 : 7  0  8  9 10 11 12
    Tuple #1 : 0  0  0  0  0  0  0
    Tuple #2 : 7  0  8  9 10 11 12
    Tuple #3 : 7  0  8  9 10 11 12
Note
MEDCoupling::DataArrayDouble::setPartOfValues2() can't be explicitly called in Python.


setPartOfValues3()

We create two arrays:

  • a "large" (4x7) zero array da to assign to,
  • a smaller (3x2) array dv filled with values [7.,8.,9.,10.,11.,12.].
1  da=DataArrayDouble()
2  da.alloc( 4, 7 )
3  #
4  dv=DataArrayDouble()
5  dv.alloc( 6, 1 )
6  dv.iota(7)
7  dv.rearrange( 2 )

Now we assign the two components of dv to the components of da with indices [1,3], and the 3 tuples of dv to the 3 tuples of da with indices [0,1,2] which are specified using slicing: "0:3". This is the first mode of usage.

1  da.fillWithZero()
2  da[ 0:3, [1,3] ] = dv

As result contents of the array da are as follows.

    Tuple #0 : 0  7  0  8  0  0  0
    Tuple #1 : 0  9  0 10  0  0  0
    Tuple #2 : 0 11  0 12  0  0  0
    Tuple #3 : 0  0  0  0  0  0  0

Every value of dv has been assigned to its own location within da.

Now we re-fill da with zeros and rearrange dv to have 6 components. And we assign dv to the tuples of da with indices [0,2] using slice notation "0:4:2". This is the second mode of usage.

1  da.fillWithZero()
2  dv.rearrange( 6 )
3  da[ 0:4:2, [0,2,3,4,5,6]] = dv

The contents of dv have been assigned to each of specified tuples of da. Every value of dv is repeated in the 3 specified tuples within da.

    Tuple #0 : 7  0  8  9 10 11 12
    Tuple #1 : 0  0  0  0  0  0  0
    Tuple #2 : 7  0  8  9 10 11 12
    Tuple #3 : 0  0  0  0  0  0  0
Note
MEDCoupling::DataArrayDouble::setPartOfValues3() can't be explicitly called in Python.

Set part of values of DataArrayInt

setSelectedComponents()

First, we create a 'source' array.

1  da=DataArrayInt()
2  array1=[1,2, 3,4, 5,6]
3  da.setValues(array1,3,2)
4  da.setInfoOnComponents( ["a1","a2"])

Now we create a larger zero array and assign the array da to it.

1  dv=DataArrayInt()
2  dv.alloc( 4, 4 )
3  dv.fillWithZero()
4  dv.setInfoOnComponents( ["v1","v2","v3","v4"])
5  dv2 = dv.deepCopy()
6  dv.setSelectedComponents( da, [1,0] )

As result contents of the array dv are as follows.

Info of components : "a2"   "a1"   "v3"   "v4"
    Tuple #0 : 2 1 0 0
    Tuple #1 : 4 3 0 0
    Tuple #2 : 6 5 0 0
    Tuple #3 : 0 0 0 0

The same result can be achieved other way (except that component info is not copied):

1  dv2[:3,[1,0]] = da
2  self.assertTrue( dv.isEqualWithoutConsideringStr( dv2 ))


setPartOfValues1()

We create two arrays:

  • a "large" (4x4) zero array da to assign to, and
  • a smaller (2x2) array dv filled with values [7,8,9,10].
1  da=DataArrayInt()
2  da.alloc( 4, 4 )
3  da.setInfoOnComponents( ["v1","v2","v3","v4"])
4  #
5  dv=DataArrayInt()
6  dv.alloc( 4, 1 )
7  dv.iota(7)
8  dv.rearrange( 2 )
9  dv.setInfoOnComponents( ["a1","a2"])

Now we copy dv to the middle of da.

1  da.fillWithZero()
2  da.setPartOfValues1( dv, 1,3,1, 1,3,1, True )

As result contents of the array da are as follows.

    Info of components :"v1"   "v2"   "v3"   "v4"
    Tuple #0 : 0 0 0 0
    Tuple #1 : 0 7 8 0
    Tuple #2 : 0 9 10 0
    Tuple #3 : 0 0 0 0

Here we re-fill da with zeros and copy dv into a component of da.

Note that the last parameter strictCompoCompare should be False in this case, else MEDCoupling::DataArrayInt::setPartOfValues1() throws an exception because da has 2 components but only one target component is specified.

1  da.fillWithZero()
2  da.setPartOfValues1( dv, 0,4,1, 1,2,1, False )
    Tuple #0 : 0 7 0 0
    Tuple #1 : 0 8 0 0
    Tuple #2 : 0 9 0 0
    Tuple #3 : 0 10 0 0

Below more two variants of location of target values are shown.

1  da.fillWithZero()
2  da.setPartOfValues1( dv, 1,2,1, 0,4,1, False )
    Tuple #0 : 0 0 0 0
    Tuple #1 : 7 8 9 10
    Tuple #2 : 0 0 0 0
    Tuple #3 : 0 0 0 0
1  da.fillWithZero()
2  da.setPartOfValues1( dv, 0,3,2, 1,4,2, True )
    Tuple #0 : 0 7 0 8
    Tuple #1 : 0 0 0 0
    Tuple #2 : 0 9 0 10
    Tuple #3 : 0 0 0 0

The same result can be achieved other way:

1  da2 = da.deepCopy()
2  da2.fillWithZero()
3  da2[ 0:3:2, 1:4:2 ] = dv
4  self.assertTrue( da.isEqual( da2 ))


setPartOfValuesSimple1()

We create an array (4x4) da to assign to and define a value dv to assign.

1  da=DataArrayInt()
2  da.alloc( 4, 4 )
3  dv = 7

Now we assign dv to the middle of da.

1  da.fillWithZero()
2  da.setPartOfValuesSimple1( dv, 1,3,1, 1,3,1 )

As result contents of the array da are as follows.

    Tuple #0 : 0 0 0 0
    Tuple #1 : 0 7 7 0
    Tuple #2 : 0 7 7 0
    Tuple #3 : 0 0 0 0

Here we re-fill da with zeros and assign dv to a component of da.

1  da.fillWithZero()
2  da.setPartOfValuesSimple1( dv, 0,4,1, 1,2,1 )
    Tuple #0 : 0 7 0 0
    Tuple #1 : 0 7 0 0
    Tuple #2 : 0 7 0 0
    Tuple #3 : 0 7 0 0

Below more two variants of location of target values are shown.

1  da.fillWithZero()
2  da.setPartOfValuesSimple1( dv, 1,2,1, 0,4,1 )
    Tuple #0 : 0 0 0 0
    Tuple #1 : 7 7 7 7
    Tuple #2 : 0 0 0 0
    Tuple #3 : 0 0 0 0
1  da.fillWithZero()
2  da.setPartOfValuesSimple1( dv, 0,3,2, 1,4,2 )
    Tuple #0 : 0 7 0 7
    Tuple #1 : 0 0 0 0
    Tuple #2 : 0 7 0 7
    Tuple #3 : 0 0 0 0

The same result can be achieved other way:

1  da2 = da.deepCopy()
2  da2.fillWithZero()
3  da2[ 0:3:2, 1:4:2 ] = dv
4  self.assertTrue( da.isEqual( da2 ))


setPartOfValuesSimple2()

We create an array (4x4) da to assign to and define a value dv to assign.

1  da=DataArrayInt()
2  da.alloc( 4, 4 )
3  dv = 7

Now we assign dv to the middle of da. We explicitly specify tuples and component to assign to by a list [1,2].

1  da.fillWithZero()
2  da[[1,2], [1,2]] = dv

As result contents of the array da are as follows.

    Tuple #0 : 0 0 0 0
    Tuple #1 : 0 7 7 0
    Tuple #2 : 0 7 7 0
    Tuple #3 : 0 0 0 0

Here we re-fill da with zeros and assign dv to a component of da.

1  da.fillWithZero()
2  da[[0,1,2,3], [1]] = dv
    Tuple #0 : 0 7 0 0
    Tuple #1 : 0 7 0 0
    Tuple #2 : 0 7 0 0
    Tuple #3 : 0 7 0 0

Below more two variants of location of target values are shown.

1  da.fillWithZero()
2  da[[1], [0,1,2,3]] = dv
    Tuple #0 : 0 0 0 0
    Tuple #1 : 7 7 7 7
    Tuple #2 : 0 0 0 0
    Tuple #3 : 0 0 0 0
1  da.fillWithZero()
2  da[[0,2], [1,3]] = dv
    Tuple #0 : 0 7 0 7
    Tuple #1 : 0 0 0 0
    Tuple #2 : 0 7 0 7
    Tuple #3 : 0 0 0 0
Note
MEDCoupling::DataArrayInt::setPartOfValuesSimple2() can't be explicitly called in Python.


setPartOfValuesSimple3()

We create an array (4x4) da to assign to and define a value dv to assign.

1  da=DataArrayInt()
2  da.alloc( 4, 4 )
3  dv = 7

Now we assign dv to the middle of da. We explicitly specify tuples to assign to by a list [1,2]. And we specify components to assign to using slicing: 1:3.

1  da.fillWithZero()
2  da[[1,2], 1:3] = dv

As result contents of the array da are as follows.

    Tuple #0 : 0 0 0 0
    Tuple #1 : 0 7 7 0
    Tuple #2 : 0 7 7 0
    Tuple #3 : 0 0 0 0

Here we re-fill da with zeros and assign dv to a component of da.

1  da.fillWithZero()
2  da[[0,1,2,3], 1:2] = dv
    Tuple #0 : 0 7 0 0
    Tuple #1 : 0 7 0 0
    Tuple #2 : 0 7 0 0
    Tuple #3 : 0 7 0 0

Below more two variants of location of target values are shown.

1  da.fillWithZero()
2  da[[1], 0:4] = dv
    Tuple #0 : 0 0 0 0
    Tuple #1 : 7 7 7 7
    Tuple #2 : 0 0 0 0
    Tuple #3 : 0 0 0 0
1  da.fillWithZero()
2  da[[0,2], 1:4:2] = dv
    Tuple #0 : 0 7 0 7
    Tuple #1 : 0 0 0 0
    Tuple #2 : 0 7 0 7
    Tuple #3 : 0 0 0 0
Note
MEDCoupling::DataArrayInt::setPartOfValuesSimple3() can't be explicitly called in Python.


setPartOfValues2()

We create two arrays:

  • a "large" (4x7) zero array da to assign to,
  • a smaller (3x2) array dv filled with values [7,8,9,10,11,12].
1  da=DataArrayInt()
2  da.alloc( 4, 7 )
3  #
4  dv=DataArrayInt()
5  dv.alloc( 6, 1 )
6  dv.iota(7)
7  dv.rearrange( 2 )

Now we assign the two components of dv to the components of da with indices [1,3], and the 3 tuples of dv to the 3 tuples of da with indices [0,1,2]. This is the first mode of usage.

1  da.fillWithZero()
2  da[ [0,1,2], [1,3] ] = dv

As result contents of the array da are as follows.

    Tuple #0 : 0  7  0  8  0  0  0
    Tuple #1 : 0  9  0 10  0  0  0
    Tuple #2 : 0 11  0 12  0  0  0
    Tuple #3 : 0  0  0  0  0  0  0

Every value of dv has been assigned to its own location within da.

Now we re-fill da with zeros and rearrange dv to have 6 components. And we assign dv to the tuples of da with indices [0,2,3] . This is the second mode of usage.

1  da.fillWithZero()
2  dv.rearrange( 6 )
3  da[ [0,2,3], [0,2,3,4,5,6]] = dv

The contents of dv have been assigned to each of specified tuples of da. Every value of dv is repeated in the 3 specified tuples within da.

    Tuple #0 : 7  0  8  9 10 11 12
    Tuple #1 : 0  0  0  0  0  0  0
    Tuple #2 : 7  0  8  9 10 11 12
    Tuple #3 : 7  0  8  9 10 11 12
Note
MEDCoupling::DataArrayInt::setPartOfValues2() can't be explicitly called in Python.


setPartOfValues3()

We create two arrays:

  • a "large" (4x7) zero array da to assign to,
  • a smaller (3x2) array dv filled with values [7,8,9,10,11,12].
1  da=DataArrayInt()
2  da.alloc( 4, 7 )
3  #
4  dv=DataArrayInt()
5  dv.alloc( 6, 1 )
6  dv.iota(7)
7  dv.rearrange( 2 )

Now we assign the two components of dv to the components of da with indices [1,3], and the 3 tuples of dv to the 3 tuples of da with indices [0,1,2] which are specified using slicing: "0:3". This is the first mode of usage.

1  da.fillWithZero()
2  da[ 0:3, [1,3] ] = dv

As result contents of the array da are as follows.

    Tuple #0 : 0  7  0  8  0  0  0
    Tuple #1 : 0  9  0 10  0  0  0
    Tuple #2 : 0 11  0 12  0  0  0
    Tuple #3 : 0  0  0  0  0  0  0

Every value of dv has been assigned to its own location within da.

Now we re-fill da with zeros and rearrange dv to have 6 components. And we assign dv to the tuples of da with indices [0,2] using slice notation "0:4:2". This is the second mode of usage.

1  da.fillWithZero()
2  dv.rearrange( 6 )
3  da[ 0:4:2, [0,2,3,4,5,6]] = dv

The contents of dv have been assigned to each of specified tuples of da. Every value of dv is repeated in the 3 specified tuples within da.

    Tuple #0 : 7  0  8  9 10 11 12
    Tuple #1 : 0  0  0  0  0  0  0
    Tuple #2 : 7  0  8  9 10 11 12
    Tuple #3 : 0  0  0  0  0  0  0
Note
MEDCoupling::DataArrayInt::setPartOfValues3() can't be explicitly called in Python.

Excluding coincident tuples from DataArrayDouble

The code below creates an array of real values and than an array of unique values, not closer one to another than 0.2, is retrieved from it.

1  array1=[2.3,1.2,1.3,2.3,2.301,0.8]
2  da=DataArrayDouble(array1,6,1)
3  #
4  dv=da.getDifferentValues(2e-1)
5  expected2=[2.301,1.3,0.8]
6  self.assertEqual(3,dv.getNbOfElems())
7  for i in xrange(3):
8  self.assertAlmostEqual(expected2[i],dv.getIJ(i,0),14)
9  pass

Concatenating DataArrayDouble's by appending components

In this example we create two data arrays including same number of tuples and then we concatenate them using meldWith().

1  da1=DataArrayDouble()
2  da1.alloc(7,2)
3  da2=DataArrayDouble()
4  da2.alloc(7,1)
5  #
6  da1.fillWithValue(7.)
7  da2.iota(0.)
8  da3=da2.applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec")
9  #
10  da1.setInfoOnComponent(0,"c0da1")
11  da1.setInfoOnComponent(1,"c1da1")
12  da3.setInfoOnComponent(0,"c0da3")
13  da3.setInfoOnComponent(1,"c1da3")
14  da3.setInfoOnComponent(2,"c2da3")
15  #
16  da1C=da1.deepCopy()
17  da1.meldWith(da3)

Now the array da1 includes 7 tuples (as before) of 3 components each. Its components are: "c0da1","c1da1","c0da2".

Concatenating DataArrayInt's by appending components

In this example we create two data arrays including same number of tuples and then we concatenate them using meldWith().

1  da1=DataArrayInt()
2  da1.alloc(7,2)
3  da2=DataArrayInt()
4  da2.alloc(7,1)
5  #
6  da1.fillWithValue(7)
7  da2.iota(0)
8  #
9  da1.setInfoOnComponent(0,"c0da1")
10  da1.setInfoOnComponent(1,"c1da1")
11  da2.setInfoOnComponent(0,"c0da2")
12  #
13  da1.meldWith(da2)

Now the array da1 includes 7 tuples (as before) of 3 components each. Its components are: "c0da1","c1da1","c0da2".

Access

Getting a tuple of DataArrayInt

In this simple example we create an array of integers arranged into 3 tuples per 2 components, and finally print the second tuple.

1  dv=DataArrayInt()
2  dv.alloc( 6, 1 )
3  dv.iota(7)
4  dv.rearrange( 2 )
5  assert dv.getTuple( 1 ) == [9,10]

The output is

 [9, 10] 

Note that we can traverse all tuples in the array by simply iterating over it as the code below does.

1  for tpl in dv:
2  print tpl

Its output follows.

(7, 8)
(9, 10)
(11, 12)

Finding values in range in DataArrayDouble

In this example we create an array da containing same values as ones returned by range( 10 ). Then we get an array of indices of values of da being in range [ 2.5, 6 ].

1  da=DataArrayDouble()
2  da.alloc( 10, 1 )
3  da[ :, :] = range(10)
4  da2 = da.findIdsInRange( 2.5, 6 )

As result contents of the array da2 are as follows.

    Tuple #0 : 3
    Tuple #1 : 4
    Tuple #2 : 5
    Tuple #3 : 6

Finding coincident tuples in DataArrayDouble

Let's create an array of 6 tuples and 2 components that can be considered as coordinates of 6 points in 2D space.

1  array2=[2.3,2.3, 1.2,1.2, 1.3,1.3, 2.3,2.3, 2.301,2.301, 0.8,0.8]
2  da=DataArrayDouble(array2,6,2)

Now we find points that are not far each from other than 1e-1.

1  c,cI=da.findCommonTuples(1.01e-1)
2  expected3=[0,3,4,1,2]
3  expected4=[0,3,5]
4  self.assertEqual(expected3,c.getValues())
5  self.assertEqual(expected4,cI.getValues())

As we can realize from the above code, a hardcoded array expected3 is equal to the raw data of a DataArrayInt c and a hardcoded array expected4 is equal to the raw data of the DataArrayInt cI.

The array c contains indices of 5 coincident points. The array cI shows us boundaries of (cI->getNumberOfTuples()-1) = 2 groups of coincident points:

  • The first group starts at index 0 and includes (3 - 0) = 3 points: 0,3,4.
  • The second group starts at index 3 and includes (5 - 3) = 2 points: 1,2.

Creation of a sub-part of the DataArrayDouble by selecting components

1  arr1=[1.,2.,3.,4., # tuple 0
2  11.,12.,13.,14., # tuple 1
3  21.,22.,23.,24., # ...
4  31.,32.,33.,34.,
5  41.,42.,43.,44.]
6  a1=DataArrayDouble(arr1,5,4)
7  a1.setInfoOnComponent(0,"a")
8  a1.setInfoOnComponent(1,"b")
9  a1.setInfoOnComponent(2,"c")
10  a1.setInfoOnComponent(3,"d")

We created an array a1 containing 5 tuples of 4 components each (20 values). Now we are going to create an array a2 containing some components of a1.

1  arr2V=[1,2,1,2,0,0]
2  a2=a1.keepSelectedComponents(arr2V)

Now each tuple of a2 includes components named "b","c","b","c","a","a". Thus the result array a2 includes 30 elements (5 tuples per 6 components).

Creation of a sub-part of the DataArrayInt by selecting components

1  arr1=[1,2,3,4, # tuple 0
2  11,12,13,14, # tuple 1
3  21,22,23,24, #
4  31,32,33,34,
5  41,42,43,44]
6  a1=DataArrayInt()
7  a1.setValues(arr1,5,4)
8  a1.setInfoOnComponent(0,"a")
9  a1.setInfoOnComponent(1,"b")
10  a1.setInfoOnComponent(2,"c")
11  a1.setInfoOnComponent(3,"d")

We created an array a1 containing 5 tuples of 4 components each (20 values). Now we are going to create an array a2 containing some components of a1.

1  arr2V=[1,2,1,2,0,0]
2  a2=a1.keepSelectedComponents(arr2V)

Now each tuple of a2 includes components named "b","c","b","c","a","a". Thus the result array a2 includes 30 elements (5 tuples per 6 components).

Note that DataArrayInt::keepSelectedComponents() is called, providing the same result, by the following python code:

1  a3=a1[:,arr2V ]

Other

Input/Output

Writing fields in a VTK file

In this example we

  • create an 2D mesh and 3 fields on it,
  • use WriteVTK() to write all the fields and the mesh to a VTK file.
1  # mesh
2  coords = [0.,2.,4.]
3  coordsArr=DataArrayDouble(coords,3,1)
4  mesh=MEDCouplingCMesh()
5  mesh.setCoords(coordsArr,coordsArr) # mesh becomes a 2D one
6 
7  # 3 fields (lying on the same mesh!)
8  field1 = mesh.getMeasureField( True )
9  field2 = mesh.buildOrthogonalField()
10  field3 = mesh.fillFromAnalytic( ON_CELLS, 2, "IVec * x + JVec * y" )
11  field2.setName( "Normal" ) # name is necessary!
12  field3.setName( "Barycenter" ) # name is necessary!
13 
14  # WriteVTK
15  fileName = "testExample_MEDCouplingFieldDouble_WriteVTK"
16  fs = [ field1, field2, field3 ] # field series
17  writtenFileName=MEDCouplingFieldDouble.WriteVTK( fileName, fs )
18  print "The file name with correct extension is : %s"%(writtenFileName)

Loading a mesh using basic API

Consider a mesh called "Example2" in file "file2.med" containing MED_POLYHEDRA, MED_TETRA4, MED_QUAD8, MED_TRI6, MED_SEG2 and MED_POINT1. In this case you will have :

1  self.assertEqual(3,ReadUMeshDimFromFile("file2.med","Example2"))

To get 3D cells (MED_POLYHEDRA and MED_TETRA4) you should type :

1  m2D=ReadUMeshFromFile("file2.med","Example2",0)

To get 2D cells (MED_TRI6 and MED_QUAD8) you should type :

1  m2D=ReadUMeshFromFile("file2.med","Example2",-1)

To get 1D cells (MED_SEG2) you should type :

1  m1D=ReadUMeshFromFile("file2.med","Example2",-2)

And finally for 0D cells (MED_POINT1) you will write :

1  m0D=ReadUMeshFromFile("file2.med","Example2",-3)

Writing one mesh using basic API

To write one mesh myMesh with name "myMeshName" in a MED file "wfile1.med" the following code should be typed :

1  self.assertTrue(isinstance(myMesh,MEDCouplingUMesh))
2  myMesh.setName(meshName)
3  WriteUMesh("wFile1.med",myMesh,True)

With the previous code, if "wFile1.med" file exists the file is crashed and will contain after the call only the contents of myMesh instance.

If you want to append a mesh in "wFile1.med" you should type :

1  self.assertTrue(isinstance(myMesh,MEDCouplingUMesh))
2  myMesh.setName(meshName)
3  WriteUMesh("wFile1.med",myMesh,False)

With the previous code, if the "wFile1.med" has already a mesh called "myMeshName" an INTERP_KERNEL::Exception will be thrown.

Reading a field at one time step using basic API

So to retrieve a field on 3D cell called "F1Cell" in example file "file2.med" on a mesh "Example2" (as defined here) on time step defined by iteration number 2 and iteration 3 the request will be :

1  f1Cell_3D=ReadFieldCell("file2.med","Example2",0,"F1Cell",2,3)

To retrieve the same field (same iteration) on 2D cells only the call will be :

1  f1Cell_2D=ReadFieldCell("file2.med","Example2",-1,"F1Cell",2,3)

Reading a field at all time steps using basic API

It is typically recommended to use the following code when you want to load all time steps of a field on cell "myField" lying on same mesh "mesh1" in one shot :

1  timeStepsIds=GetCellFieldIterations("file3.med","Example2","myField")
2  self.assertEqual([(1, 0),(2, 0)],timeStepsIds)
3  fs=ReadFieldsOnSameMesh(ON_CELLS,"file3.med","Example2",0,"myField",timeStepsIds);

Reading a field on all entities using advanced API

Let's read a field on all entity called fieldName lying on a mesh called meshName in a MED file called fname at a iteration defined on time step defined by iteration and order.

1  fname="PyExamples1.med"
2  meshName="mesh"
3  fieldName="FieldOnAll"
4  iteration=3
5  order=4

To read it there are 3 main approaches :

1  medfileField1TS=MEDFileField1TS.New(fname,fieldName,iteration,order)
2  mm=MEDFileMesh.New(fname)
3  fread=medfileField1TS.getFieldOnMeshAtLevel(ON_CELLS,0,mm)
4  fread2=medfileField1TS.getFieldAtLevel(ON_CELLS,0)
5  self.assertTrue(fread.isEqual(f,1e-12,1e-12))
6  self.assertTrue(fread2.isEqual(f,1e-12,1e-12))
1  medfileFieldMTS=MEDFileFieldMultiTS.New(fname,fieldName)
2  mm=MEDFileMesh.New(fname)
3  fread=medfileFieldMTS.getFieldOnMeshAtLevel(ON_CELLS,iteration,order,0,mm)
4  fread2=medfileFieldMTS.getFieldAtLevel(ON_CELLS,iteration,order,0)
5  self.assertTrue(fread.isEqual(f,1e-12,1e-12))
6  self.assertTrue(fread2.isEqual(f,1e-12,1e-12))
1  medfileFieldMTS=MEDFileFieldMultiTS.New(fname,fieldName)
2  for medfileField1TS in medfileFieldMTS:
3  if medfileField1TS.getTime()[:2]==[iteration,order]:
4  fread=medfileField1TS.getFieldOnMeshAtLevel(ON_CELLS,0,mm)
5  fread2=medfileField1TS.getFieldAtLevel(ON_CELLS,0)
6  self.assertTrue(fread.isEqual(f,1e-12,1e-12))
7  self.assertTrue(fread2.isEqual(f,1e-12,1e-12))
8  pass
9  pass

Reading a partial field using advanced API

Let's read a partial field called fieldName lying on a mesh called meshName in a MED file called fname at a iteration defined on time step defined by iteration and order.

1  fname="PyExamples2.med"
2  meshName="mesh"
3  fieldName="FieldPartial"
4  iteration=3
5  order=4

Fields defined partially on a meshes can been read using 2 main approaches :

  • Either the user wants to retrieve it's field in MEDCoupling sense, that is to say for interpolation, to evaluate such field on different points...
    In this mode the link with the whole mesh is not useful for the user
1  mm=MEDFileMesh.New(fname)
2  medfileField1TS=MEDFileField1TS.New(fname,fieldName,iteration,order)
3  fread=medfileField1TS.getFieldOnMeshAtLevel(ON_CELLS,0,mm)
4  fread2=medfileField1TS.getFieldAtLevel(ON_CELLS,0)
5  self.assertTrue(fread.isEqual(f,1e-12,1e-12))
6  self.assertTrue(fread2.isEqual(f,1e-12,1e-12))
  • Or the user wants to retrieve the binding (cell ids or node ids) with the whole mesh on which the partial field lies partially on.
1  medfileField1TS=MEDFileField1TS.New(fname,fieldName,iteration,order)
2  mm=MEDFileMesh.New(fname)
3  valsRead,pflRead=medfileField1TS.getFieldWithProfile(ON_CELLS,0,mm)
4  self.assertEqual(valsRead.getName(),f.getName())
5  valsRead.setName("")
6  self.assertTrue(valsRead.isEqual(f.getArray(),1e-12))
7  pflRead.setName(pfl.getName())
8  self.assertTrue(pflRead.isEqual(pfl))

MEDCoupling allows to make bridges between the approaches. For example pfl DataArrayInt instance retrieved directly from the file in the second approach can be retrieved starting from first approach.

Starting from mesh firstApproachMesh of read field in first approach fread, whith the whole mesh wholeMesh the profile pflComputed can be computed :

1  firstApproachMesh=fread.getMesh()
2  mm=MEDFileMesh.New(fname)
3  wholeMesh=mm.getMeshAtLevel(0)
4  wholeMesh.tryToShareSameCoords(firstApproachMesh,1e-12)
5  isIncluded,pflComputed=wholeMesh.areCellsIncludedIn(firstApproachMesh,2)
6  self.assertTrue(isIncluded)
7  self.assertEqual(pflComputed.getName(),mm.getName())
8  pflComputed.setName(pflRead.getName())
9  self.assertTrue(pflComputed.isEqual(pflRead))

Inversely, it is possible to rebuild field obtained in first approach starting from second approach :

1  mm=MEDFileMesh.New(fname)
2  wholeMesh=mm.getMeshAtLevel(0)
3  computedMesh=wholeMesh[pflRead] ; computedMesh.setName(mm.getName())
4  self.assertTrue(computedMesh.isEqual(fread.getMesh(),1e-12))
5  fieldFromSecondApproach=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME)
6  fieldFromSecondApproach.setName(medfileField1TS.getName())
7  fieldFromSecondApproach.setMesh(computedMesh)
8  fieldFromSecondApproach.setArray(valsRead)
9  fieldFromSecondApproach.setTime(medfileField1TS.getTime()[2],medfileField1TS.getTime()[0],medfileField1TS.getTime()[1])
10  self.assertTrue(fieldFromSecondApproach.isEqual(fread,1e-12,1e-12))

Writing several time steps of a field using basic API

To write a serie of time steps in a "file3.med" file lying on the same unstructured mesh the typical code to write is the following :

1  WriteUMesh("file3.med",f.getMesh(),True)
2  f.setTime(1.2,1,0)
3  fileNameMultiTimeStep="file3.med"
4  WriteFieldUsingAlreadyWrittenMesh(fileNameMultiTimeStep,f)
5  f.setTime(1.3,2,0)
6  f.applyFunc("sqrt(x)");
7  #Writing second time step with iteration==2 and order==0

In the above code, it is important to note that the values of pairs (iteration,order) should be different between two calls to avoid that a call to MEDLoader::WriteFieldUsingAlreadyWrittenMesh overwrites a previous call. Another important thing is the fact that f.getMesh() is not modified. This write method presents the big advantage to be fast, because neither check nor read is performed. That's why the parameter of writeFromScratch is not needed here, contrary to other MEDLoader::Write* methods.

Writing a field defined on all entities using advanced API

Let's write a cell field on all entities called fieldName lying on a mesh called meshName in a MED file called fname at a iteration defined on time step defined by iteration and order.

1  m=MEDLoaderDataForTest.build2DMesh_3()
2  m=m[:10]
3  m.setName(meshName)
4  f=m.getMeasureField(False)
5  f=f.buildNewTimeReprFromThis(ONE_TIME,False)
6  f.setTime(5.5,iteration,order)
7  f.setName(fieldName)
8  # MEDCoupling finished, MEDLoader advanced API specific part starting from here
9  mm=MEDFileUMesh.New()
10  mm.setMeshAtLevel(0,m)
11  ff=MEDFileField1TS.New()
12  ff.setFieldNoProfileSBT(f)
13  mm.write(fname,2)
14  ff.write(fname,0)

We can see here that the necessity to deal with both mesh and field to write a field is exposed by the API. The mesh write mode is 2 to tell to MED file that is file already exists to scratch it. The mode of write is 0 to simply add to the file the field specific part.

Writing a partial field using advanced API

1  m=MEDLoaderDataForTest.build2DMesh_1()
2  m.sortCellsInMEDFileFrmt()
3  m.setName(meshName)
4  # end of generation of a mesh -> let's create a field on that mesh
5  f=m.getMeasureField(False)
6  f=f.buildNewTimeReprFromThis(ONE_TIME,False)
7  f.setTime(5.5,iteration,order)
8  f.setName(fieldName)
9  # The MEDCoupling part is finished -> let's perform advanced API
10  mm=MEDFileUMesh.New()
11  mm.setMeshAtLevel(0,m) # the MED file data structure is ready for writing. Of course mm could have been more complicated with groups, families, multilevel
12  # Let's building a sub field
13  pfl=DataArrayInt.New([1,3,4,5])
14  pfl.setName("myPfl") # here it is necessary to give a name to be compliant with MED file
15  f=f[pfl] ; f.getMesh().setName(m.getName()) # of course f should be in coherence with pfl -> f[pfl]
16  #
17  ff=MEDFileField1TS.New()
18  tmp=f.getMesh() # useless line, only to show that mesh into f is not considered by MEDFileField1TS.setFieldProfile
19  f.setMesh(None) # useless line, only to show that mesh into f is not considered by MEDFileField1TS.setFieldProfile
20  ff.setFieldProfile(f,mm,0,pfl)
21  f.setMesh(tmp) # useless line, only to show that mesh into f is not considered by MEDFileField1TS.setFieldProfile
22  mm.write(fname,2)
23  ff.write(fname,0)

To write a partial field f can have a null mesh, because the link with mesh is made given the entry of mm MEDFileField1TS::setFieldProfile method.