7 medcoupling provides information on memory occupied by every object: mesh, field, array etc.:
9 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
10 :start-after: UG_MEDCouplingFieldDouble_4
11 :end-before: UG_MEDCouplingFieldDouble_4
16 .. _extract_for_meshes:
21 If *m* is a mesh (MEDCouplingUMesh) and *Ids* a list of cell ids, you can extract the mesh ids by simply doing :
23 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
24 :start-after: UG_ExtractForMeshes_0
25 :end-before: UG_ExtractForMeshes_0
27 .. figure:: ../images/extract_mesh_ids.png
30 *m* (to the left) and *part* extracted by calling m[1,2,4,5,7,8] (to the right)
32 .. note:: in medcoupling ids count from zero unlike SMESH where they count from one.
34 *part* is also a MEDCouplingUMesh with same coordinates than *m*. Reason is that medcoupling tries to reduce memory effort.
36 But it's highly likely that some nodes in part will be not fetched by part.
38 It can be interesting to locate the fetched nodes.
40 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
41 :start-after: UG_ExtractForMeshes_1
42 :end-before: UG_ExtractForMeshes_1
44 .. figure:: ../images/extract_mesh_fetched_nodes.png
47 part.computeFetchedNodeIds() returns [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]. Ids 0 and 17 are not fetched
49 To extract coordinates, simply invoke
51 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
52 :start-after: UG_ExtractForMeshes_2
53 :end-before: UG_ExtractForMeshes_2
55 It can be interesting to reduce set of points *part* is lying on. Simply by doing.
57 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
58 :start-after: UG_ExtractForMeshes_3
59 :end-before: UG_ExtractForMeshes_3
61 Or it can be interesting for further data handling to have both reduction and array.
63 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
64 :start-after: UG_ExtractForMeshes_4
65 :end-before: UG_ExtractForMeshes_4
67 To have more information about *o2n* read renumbering_ section.
69 .. _renumbering: ../../developer/numbering.html
71 Extraction in meshes often leads to locate cells/nodes regarding their neighborhood.
73 Let's consider *m2* 3D mesh. To locate nodes on boundaries simply invoke :
75 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
76 :start-after: UG_ExtractForMeshes_5
77 :end-before: UG_ExtractForMeshes_5
79 And now to extract cells lying on boundary nodes simply call :
81 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
82 :start-after: UG_ExtractForMeshes_6
83 :end-before: UG_ExtractForMeshes_6
85 False means if a cell has at least one node in *bn*, take it. True means if all nodes of cell are in *bn*, take it.
87 If a mesh consists of several contiguous zones of cells, it is possible to retrieve cell ids of each zone:
89 .. figure:: ../images/zones.png
94 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
95 :start-after: UG_ExtractForMeshes_20
96 :end-before: UG_ExtractForMeshes_20
98 Zones returned by partitionBySpreadZone are::
105 Arrays are the common entry point to selection. If *arr* is a 2 component DataArrayDouble you can locate tuple ids by finding those whose first component is in [a,b):
107 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
108 :start-after: UG_ExtractForArrays_0
109 :end-before: UG_ExtractForArrays_0
111 Or you can find tuples whose magnitude is in [c,d):
113 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
114 :start-after: UG_ExtractForArrays_1
115 :end-before: UG_ExtractForArrays_1
117 To find which of *tupleIds* are missing from *tupleIds1*, call
119 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
120 :start-after: UG_ExtractForArrays_2
121 :end-before: UG_ExtractForArrays_2
127 If *field4* is a MEDCouplingFieldDouble, you can extract a sub-part of *field4* on a specified cell ids *ids4* by doing
129 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
130 :start-after: UG_ExtractForFields_0
131 :end-before: UG_ExtractForFields_0
133 .. note:: It works whatever the spatial discretization of *field4*
135 .. figure:: ../images/extract_fields.png
138 A field on nodes (to the left) and its sub-field on a half of nodes (to the right)
140 You can extract a field on plane by cutting *field5* like this:
142 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
143 :start-after: UG_ExtractForFields_1
144 :end-before: UG_ExtractForFields_1
146 The plane is defined by its *origin* and its normal vector *normvec*. The last argument is a half-thickness of the plane.
148 .. note:: It works for fields on cells only
150 .. figure:: ../images/extractSlice3D.png
153 A field on cells (to the left) and a sub-field on a plane (to the right)
158 Geometric handling of unstructured meshes
159 -----------------------------------------
161 Consider *m2* as a 3D MEDCouplingUMesh instance. You can translate it by simply
163 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
164 :start-after: UG_ExtractForMeshes_7
165 :end-before: UG_ExtractForMeshes_7
167 Which is equivalent to
169 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
170 :start-after: UG_ExtractForMeshes_8
171 :end-before: UG_ExtractForMeshes_8
173 Samely you can simply rotate it around the point [1,2,1] along Y axis with an angle of pi/3 by doing
175 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
176 :start-after: UG_ExtractForMeshes_9
177 :end-before: UG_ExtractForMeshes_9
179 Which is equivalent to
181 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
182 :start-after: UG_ExtractForMeshes_10
183 :end-before: UG_ExtractForMeshes_10
185 To scale *m2* relative to point [1,2,4] by a factor of 6, call
187 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
188 :start-after: UG_ExtractForMeshes_17
189 :end-before: UG_ExtractForMeshes_17
191 It can also interesting to retrieve volume of cells in m2 (resp area, length in 2D, 1D):
193 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
194 :start-after: UG_ExtractForMeshes_11
195 :end-before: UG_ExtractForMeshes_11
197 *volPerCell* is a field on cell (MEDCouplingFieldDouble). *True* means I don't care of cell orientation. *False* tells I care of cell orientation using signed values.
199 .. figure:: ../images/measure_field.png
202 Area field of a cartesian mesh
204 You can compute total volume covered by mesh by doing
206 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
207 :start-after: UG_ExtractForMeshes_12
208 :end-before: UG_ExtractForMeshes_12
210 You also can locate cells (using *cellIds*) having volume greater than a threshold *t1*:
212 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
213 :start-after: UG_ExtractForMeshes_13
214 :end-before: UG_ExtractForMeshes_13
216 In this case it is easy to :ref:`build a sub-mesh<extract_for_meshes>` containing cells having a volume higher than *t1*:
218 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
219 :start-after: UG_ExtractForMeshes_14
220 :end-before: UG_ExtractForMeshes_14
222 There are other common geometric methods on meshes:
224 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
225 :start-after: UG_ExtractForMeshes_15
226 :end-before: UG_ExtractForMeshes_15
228 *centers* will be a DataArrayDouble giving for each cell of *m2* its center of mass.
230 It's possible to compute a DataArrayDouble giving the center of mass of *m2* simply by doing
232 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
233 :start-after: UG_ExtractForMeshes_16
234 :end-before: UG_ExtractForMeshes_16
236 Iso barycenter of nodes constituting each cell can be computed by calling
238 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
239 :start-after: UG_ExtractForMeshes_19
240 :end-before: UG_ExtractForMeshes_19
242 *ibc* will be a DataArrayDouble.
244 You can retrieve a field (MEDCouplingFieldDouble) of unitary vectors normal to cells:
246 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
247 :start-after: UG_ExtractForMeshes_18
248 :end-before: UG_ExtractForMeshes_18
250 .. figure:: ../images/ortho_field.png
253 A skin mesh with a normal field on it computed by buildOrthogonalField method
255 You also have a set of methods to caracterize mesh quality: getEdgeRatioField, getAspectRatioField, getWarpField, getSkewField, computeDiameterField.
258 medcoupling provides methods to intersect 2D meshes in 2D space. MEDCouplingUMesh.Intersect2DMeshWith1DLine partitions a 2D and a 1D mesh:
260 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
261 :start-after: UG_ExtractForMeshes_21
262 :end-before: UG_ExtractForMeshes_21
264 The last argument is a precision used to perform intersections and localization operations.
266 .. figure:: ../images/intersect_2d1d.png
269 2D and 1D meshes before and after intersection
271 Intersect2DMeshWith1DLine returns new 2D and 1D meshes and two arrays. *a2d* gives for each cell in *m2d* the id in *mesh2d* it comes from. *a1d* is an array of pair that gives for each cell id i in *m1d* the cell in *md2* on the left for the 1st component and the cell in *m2d* on the right for the 2nd component. -1 means no cell.
273 For the example in the picture above *a2d* is::
275 [0, 4, 1, 1, 2, 2, 3, 3]
279 [-1, -1, -1, -1, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7, -1, -1, -1, -1]
281 There also a method to partition a 2D mesh by another 2D mesh:
283 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
284 :start-after: UG_ExtractForMeshes_22
285 :end-before: UG_ExtractForMeshes_22
287 .. figure:: ../images/intersect_2d2d.png
290 Two 2D meshes before partitioning (to the left) and a result mesh after partitioning (to the right)
292 Intersect2DMeshes returns a new 2D mesh and two arrays. *a1* gives for each result cell an id of the cell of *mesh1* it comes from. *a2* for each result cell gives an id of the cell of *mesh2* it comes from.
294 You can compute distance from a set of points to cells of a mesh by calling
296 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
297 :start-after: UG_ExtractForMeshes_23
298 :end-before: UG_ExtractForMeshes_23
300 This method returns distance and a closest cell id for each of given *points*. *points* is a DataArrayDouble with 3 components. Returned *dist* is a DataArrayDouble and *cells* is a DataArrayInt.
305 It is a common question. You have two meshes *m1* and *m2* coming from 2 different sources (2 files) and expected to be more or less equivalent.
307 medcoupling proposes some methods to help to caracterize equivalence of these 2 meshes.
309 The first, the strongest, is informatical equality:
311 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
312 :start-after: UG_MeshComparison_0
313 :end-before: UG_MeshComparison_0
315 *eps* is the tolerance in coordinates.
317 If true is returned, you are lucky.
319 Sometimes only names (and or component names or units) are not the same:
321 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
322 :start-after: UG_MeshComparison_1
323 :end-before: UG_MeshComparison_1
325 But sometime the last call also returns False. It may mean that there is a permutation of nodes and or cells.
327 If you know by construction that *m1* and *m2* share the same coords object:
329 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
330 :start-after: UG_MeshComparison_2
331 :end-before: UG_MeshComparison_2
333 checkGeoEquivalWith returns 2 elements. The first one is relative to cells and the second one is relative to nodes.
335 If the mapping between *m1* and *m2* is impossible regarding the specified code an exception is thrown.
338 - 20=2*10+0. 2 tells I know that coords are the same. 0 tells two cells are equal if and only if their connectivity is exactly the same.
339 - 21=2*10+1. 2 tells I know that coords are the same. 1 tells two cells are equal if and only if their connectivity is equal within a circular permutation.
340 - 22=2*10+2 . 2 tells I know that coords are the same. 2 tells two cells are equal if and only if nodes set is the same independently from :ref:`order <renumber_for_MED>`.
342 If you expect that two meshes are geometrically the same without knowing if there is any cell/node permutation use code 12:
344 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
345 :start-after: UG_MeshComparison_3
346 :end-before: UG_MeshComparison_3
348 Code meaning: 12=1*10+2. 1 tells coords can be different. 2 tells two cells are equal if and only if nodes set is the same independently from order.
350 .. admonition:: Remark
352 *a* and/or *b* may be *None*. It's not a bug it only means that renumbering is equal to identity, meaning that no associated permutation is needed.
357 *field1* is a node field containing non simplex cells. simplexize on field1.getMesh() can help to
358 overpass this limitation.
360 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
361 :start-after: UG_CommonHandlingMesh_0
362 :end-before: UG_CommonHandlingMesh_0
364 .. figure:: ../images/simplexize.png
367 Initial mesh (to the left) and its simplexization (to the right)
369 .. admonition:: Remark
371 The mesh has been modified by simplexize. This method of simplexization is fast but leads to non conform mesh that can be a problem in some context
373 tetrahedrize method is dedicated to simplexization of 3D meshes only. It can create a conform mesh. Unlike simplexize method, tetrahedrize method can add new points to the result mesh.
375 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
376 :start-after: UG_CommonHandlingMesh_15
377 :end-before: UG_CommonHandlingMesh_15
379 The argument specifies how to split hexahedral cells. it must be in (PLANAR_FACE_5, PLANAR_FACE_6, GENERAL_24, GENERAL_48).
380 *n2ocells* is a DataArrayInt holding, for each new cell, an id of old cell producing it.
381 *np* is a number of new points.
383 Using medcoupling you can create a 3D extruded mesh. To do that you need a 2D mesh and a 1D mesh, which defines the vector of extrusion and the number of steps. The both meshes must be in 3D space. To extrude a 2D mesh *m2* along a 1D mesh *m1*, call
385 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
386 :start-after: UG_CommonHandlingMesh_1
387 :end-before: UG_CommonHandlingMesh_1
389 The last argument is a policy defining the type of extrusion:
391 * 0 means "translation only": the cells of the 1D mesh represent the vectors along which the 2D mesh will be repeated to build each level.
392 * 1 means "translation and rotation": the translation is done as above. For each level, an arc of circle is fitted on the 3 preceding points of the 1D mesh. The center of the arc is the center of rotation for each level, the rotation is done along an axis normal to the plane containing the arc, and finally the angle of rotation is defined by the first two points on the arc.
395 .. figure:: ../images/extrusion.png
398 A 2D mesh and an 1D mesh (to the left), an extrusion mesh built with policy=0 (in the middle) and with policy=1 (to the right)
401 In order to aggregate several meshes of the same dimension into one mesh, call
403 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
404 :start-after: UG_CommonHandlingMesh_2
405 :end-before: UG_CommonHandlingMesh_2
407 To transform a linear mesh into a quadratic one, call
409 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
410 :start-after: UG_CommonHandlingMesh_3
411 :end-before: UG_CommonHandlingMesh_3
413 A parameter of convertLinearCellsToQuadratic provides type of conversion:
415 * 0 creates cells of simple quadratic types, e.g. NORM_TRI6 and NORM_QUAD8
416 * 1 creates cells of complex quadratic types, e.g. NORM_TRI7 and NORM_QUAD9
418 .. figure:: ../images/convert2quadratic.png
421 Result quadratic 2D meshes converted with typeOfConversion=0 (to the left) and typeOfConversion=1 (to the right)
423 It's common to deduce skin of a mesh *m1*:
425 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
426 :start-after: UG_CommonHandlingMesh_4
427 :end-before: UG_CommonHandlingMesh_4
429 *skin* and *m1* share the same coordinate array.
431 .. figure:: ../images/skin.png
434 A 2D mesh (to the left) and its skin (to the right)
436 .. _explodeIntoEdges:
438 In order to get a 1D mesh from a given 2D or 3D mesh, call
440 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
441 :start-after: UG_CommonHandlingMesh_6
442 :end-before: UG_CommonHandlingMesh_6
444 In addition to *mesh1d*, explodeIntoEdges method returns four arrays describing descending connectivity and reverse descending connectivity in indirect-indexing_ format. *d* and *di* describe the descending connectivity, i.e. enumerate cells of *mesh1d* bounding each cell of *mesh3d*. *r* and *ri* describe the reverse descending connectivity, i.e. enumerate cells of *mesh3d* bounded by each cell of *mesh1d*.
446 .. _indirect-indexing: ../../developer/numbering.html#numbering-indirect
448 .. figure:: ../images/explodeIntoEdges.png
451 A 2D mesh (to the left) and a 1D mesh returned by explodeIntoEdges (to the right)
453 There is also a method similar to explodeIntoEdges_ which returns a mesh of one less dimensions than a given mesh, i.e. 3D->2D or 2D->1D:
455 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
456 :start-after: UG_CommonHandlingMesh_7
457 :end-before: UG_CommonHandlingMesh_7
459 If a mesh is non-conformal, medcoupling can make it conformal. conformize2D method is to conformize a 2D mesh in 2D space, conformize3D is to conformize a 3D mesh in 3D space:
461 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
462 :start-after: UG_CommonHandlingMesh_8
463 :end-before: UG_CommonHandlingMesh_8
465 *changedCells* is an array of ids of changed cells. The changed cells become polygons in 2D and polyhedrons in 3D. *eps* is the relative error to detect merged edges.
467 You can duplicate some nodes in a mesh by calling
469 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
470 :start-after: UG_CommonHandlingMesh_9
471 :end-before: UG_CommonHandlingMesh_9
473 This will create new nodes at locations of nodes #3 and #4, the new nodes will replace nodes #3 and #4 within cells so that the nodes #3 and #4 will become orphan.
475 Inversly it is possible to merges nodes equal within a given precision:
477 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
478 :start-after: UG_CommonHandlingMesh_16
479 :end-before: UG_CommonHandlingMesh_16
481 If your 2D mesh in 3D space includes incorrectly oriented cells, you can fix their orientation by calling:
483 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
484 :start-after: UG_CommonHandlingMesh_11
485 :end-before: UG_CommonHandlingMesh_11
487 The last argument if True, only polygons are checked, else, all cells are checked.
489 .. figure:: ../images/orient_2d.png
492 A mesh before applying orientCorrectly2DCells (to the left) and after (to the right)
494 If your mesh includes incorrectly oriented polyhedra, the following method can help to fix your mesh:
496 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
497 :start-after: UG_CommonHandlingMesh_12
498 :end-before: UG_CommonHandlingMesh_12
500 If *m1d* is a 1D line mesh, you can ensure consecutive order of its segments by calling
502 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
503 :start-after: UG_CommonHandlingMesh_10
504 :end-before: UG_CommonHandlingMesh_10
506 .. figure:: ../images/orderConsecutiveCells1D.png
509 1D mesh before and after renumbering
511 orderConsecutiveCells1D method returns a permutation map in new-to-old_ mode but renumberCells method requires the map in old-to-new_ mode, hence we use invertArrayN2O2O2N method to fit to that requirement.
513 .. _new-to-old: ../../developer/numbering.html#MEDCouplingArrayRenumberingN2O
515 .. _old-to-new: ../../developer/numbering.html#MEDCouplingArrayRenumberingO2N
517 .. _renumber_for_MED:
519 To arrange cells to comply with MED format requirement you can call either of the following methods:
521 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
522 :start-after: UG_CommonHandlingMesh_13
523 :end-before: UG_CommonHandlingMesh_13
526 It is also possible to rearrange, and even remove, nodes by calling renumberNodes:
528 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
529 :start-after: UG_CommonHandlingMesh_14
530 :end-before: UG_CommonHandlingMesh_14
532 The code above rearranges a mesh with 4 nodes so that old node #0 becomes #2, old node #1 remains #1, old node #2 becomes #0, old node #3 is removed. The last argument 3 means that number of nodes becomes 3.
534 .. figure:: ../images/renumber_nodes.png
537 The mesh before renumberNodes (to the left) and after (to the right). Shown Ids are a unit more than Ids in medcoupling
542 Integral of a *field* can be computed by calling
544 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
545 :start-after: UG_MEDCouplingFieldDouble_9
546 :end-before: UG_MEDCouplingFieldDouble_9
548 The first call returns a list of integrals of all components. The second, returns integral of 0-th component. True means that abs is applied to support size used for computing the integral.
550 deviator method returns the stress deviator tensor field of a stress tensor *field* (with 6 components):
552 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
553 :start-after: UG_MEDCouplingFieldDouble_10
554 :end-before: UG_MEDCouplingFieldDouble_10
556 To get value of a *field* at certain *points* call
558 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
559 :start-after: UG_MEDCouplingFieldDouble_8
560 :end-before: UG_MEDCouplingFieldDouble_8