4 medcoupling includes MEDCouplingRemapper object that allows given a
5 source field and a target mesh to produce a field lying on target
8 MEDCouplingRemapper goal is to compute a projection by minimizing
9 diffusive effects and conserve at most the magnitude of key
12 The MEDCouplingRemapper object computes a remap function that allows
13 to transform source field into target field.
15 The function is represented using sparse matrix given:
19 - a source spatial discretization ("P0" means ON_CELLS and "P1" means ON_NODES)
20 - a target spatial discretization
22 Apply a projection is then equivalent to apply matrix vector
25 As projection requires mathematically to compute for every cell in
26 target mesh, the contribution relative to each of cell in source
27 mesh. So projection is computation-intensive task.
29 To optimize time spent by MEDCouplingRemapper, it implements a fast
30 algorithm that select coarsely the pairs of cells that have a chance
31 to be in interaction each other.
32 It allows to drop from O(n^2) to O(n) the complexity of algorithm.
33 The algorithm is based on rectilinear bounding boxes of cells along
34 axis. 2 cells in interaction have their respective bounding boxes in
37 Unfortunately it works well mathematically but in the real life
38 projections especially when spacedim and meshdim are not the same it
43 Projection cells/cells with meshes having same mesh dimension/space dimension
44 -----------------------------------------------------------------------------
46 Let us create meshes for sample projection: a source mesh consisting of two quadrangles and a target mesh consisting of a triangle:
48 .. figure:: ../images/projection_P0P1_meshes.png
51 Two source quadrangles in blue and a target triangle in red
53 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
54 :start-after: UG_Projection_0
55 :end-before: UG_Projection_0
57 Now perform projection:
59 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
60 :start-after: UG_Projection_1
61 :end-before: UG_Projection_1
63 Here "P0P0" specifies spatial discretization of both source and target field. "P0" is for cell discretization (ON_CELLS). "P1" is for node discretization (ON_NODES). For example, "P0P1" means from a source cell field (lying on a source mesh) to a target node field (lying on a target mesh).
65 Remapper *rem* has just performed intersection of *src* and *tgt* meshes. Result of intersection is stored in a matrix which is returned by getCrudeMatrix method. Each element of the matrix is size of intersection of two cells i and j of the source and target meshes correspondingly.
67 Generally the matrix is sparse. To reduce memory usage, the space matrix is represented by an array whose i-th element is a map storing indices and intersection sizes of source cells intersecting i-th target cell.
69 Here is a sample sparse matrix:
81 and a corresponding array, which stores only non-zero matrix elements:
85 [{0: 11, 3: 14}, {3: 24, 4: 25}, {1: 32, 2: 33}, {2: 43, 4: 45}]
87 Now we create a field on all cells of *src* mesh and call rem.transferField() to transfer the field to the cells of *tgt* mesh
89 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
90 :start-after: UG_Projection_2
91 :end-before: UG_Projection_2
93 The last argument -1 is a default value that will be assigned in *trgF* to each entity of *tgt* mesh that is not intercepted by any entity of *src* mesh.
95 It is crucial to setNature() of the field by which an adequate interpolation formula is chosen. The field nature is expressed by one of the following values: ExtensiveMaximum, IntensiveMaximum, ExtensiveConservation, IntensiveConservation.
97 The field is represented by a vector with a discrete value on each cell. This value can represent either
99 * an average value of the field in the cell (average density, velocity or temperature in the cell) in which case the representation is said to be **intensive**,
100 * an integrated value over the cell (total mass, power of the cell) in which case the representation is said to be **extensive**.
102 In the case where the source and target meshes are not fully overlapping, it is important to make a correct choice between Maximum and Conservation.
104 * **Conservation** means that the interpolation algorithm preserves the integral of the field over a domain.
105 * **Maximum** means that the field values resulting from the interpolation remain between the upper and lower bounds of the original field.
107 Projection cells/nodes nodes/cells nodes/nodes with meshes having same mesh dimension/space dimension
108 -----------------------------------------------------------------------------------------------------
110 Suppose we have the same source and target meshes as in the :ref:`previous chapter <projection_P0P0>`. I.e. the source mesh consists of two quadrangles and the target mesh consists of a triangle.
112 .. figure:: ../images/projection_P0P1_meshes.png
115 Two source quadrangles in blue and a target triangle in red
117 The source field is also on cells but the target field is on **nodes** of target mesh. In such a case we do the following:
119 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
120 :start-after: UG_Projection_3
121 :end-before: UG_Projection_3
123 Here "P0P1" specifies support of the source (P0=ON_CELLS) and the target (P1=ON_NODES) fields. The computed martix is::
125 [{0: 0.125, 1: 0.04166666666666663}, {1:0.16666666666666669}, {1: 0.041666666666666685}]
127 The result matrix contains values for each of the three nodes of the target mesh. In order to be able to compute these values by means of intersection of cells, an algorithm constructs an auxiliary target mesh. This auxiliary mesh is a dual mesh of the actual target mesh, hence it includes cells corresponding to each actual target node.
129 .. figure:: ../images/projection_P0P1_dual.png
132 The target mesh used for projection is a dual one of the actual target mesh
134 If the case is reverse, i.e. the source field is on nodes and the target one should be on cells, we change "P0P1" to "P1P0":
136 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
137 :start-after: UG_Projection_4
138 :end-before: UG_Projection_4
140 The computed martix is::
142 [{1: 0.07291666666666663, 4: 0.375}]
144 In the same way as in "P0P1" case, an auxiliary dual mesh is internally constructed for a mesh supporting a field on nodes (the source field in our case). But since the source cells are not simplexes, simplexization of quadrangles is perfrormed on the fly to be able to construct the dual mesh. Cell #0 (0,3,4,1) is split into (0,3,4) and (0,4,1)
146 .. figure:: ../images/projection_P1P0_dual.png
149 The source mesh used for projection is a dual one of simplexized actual source mesh
155 .. note:: in present implementation of Remapper, the projection of fields on nodes lying on quadratic meshes is not available. If you are in this case you have 2 choices :|br|
156 1) you accept to lose precision by converting your mesh (MEDCouplingUMesh.convertLinearCellsToQuadratic) |br|
157 2) you subdivide your mesh.
159 Projection cell/cell when meshdim != spacedim
160 ---------------------------------------------
162 When meshdim is not equal to spacedim some additional important parameters should be considered.
164 Consider a simple case with spacedim=3 and meshdim=2 where :
166 - source mesh contains one triangle cell [0.,0.,0.], [1,0,0], [0,1,0]
167 - target mesh also contains one triange cell [0.,0.,0.], [1,0,0], [0,1,0], which coincides with the source triangle.
169 Only "P0P0" projection (ON_CELLS->ON_CELLS) will be considered here but all elements presented here are applicable for other spatial discretizations projections.
171 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
172 :start-after: UG_Projection_5
173 :end-before: UG_Projection_5
175 A remapper returns the following correct matrix::
179 where 0.5 is equal to area of the source (or target) triangle.
181 Let us see what the remapper will return if the meshes are not overlapping. To this end we translate the source mesh along its normal by a small distance (1e-3):
183 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
184 :start-after: UG_Projection_6
185 :end-before: UG_Projection_6
187 The remapper returns the following matrix, which means that it have not found any intersection of the meshes::
191 This happens because bounding boxes of cells used to detect possibly intersecting cells do not intersect. In order to get a correct result of intersection we can increase those bounding boxes. The remapper provides two ways to do that:
193 - rem.setBoundingBoxAdjustmentAbs( *thickness* ) expands a bounding box by *thickness*.
194 - rem.setBoundingBoxAdjustment( *factor* ) expands a bounding box by thickness computed by multiplying a maximal bounding box size by *factor*.
196 .. figure:: ../images/projection_bnd_box.png
199 If source and target meshes do not overlap we can increase their bounding boxes to help remapper to detect intersecting cells
201 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
202 :start-after: UG_Projection_7
203 :end-before: UG_Projection_7
205 With bounding box tuning we obtain the correct result matrix::
209 The bounding box tuning has a disadvantage in the case where a cell has large angle with either of planes OXY, OYZ or OXZ. In such a case cells that are rather far one from another can be detected as possibly intersecting since their bounding boxes are too large. setMaxDistance3DSurfIntersect method helps avoiding excess intersections. If a distance between fast barycenter of target cell and medium source plane is more than the value specified via setMaxDistance3DSurfIntersect then cell intersection is not performed.
211 .. figure:: ../images/projection_setMaxDistance3DSurfIntersect.png
214 If the tuned bounding box is too large we can use setMaxDistance3DSurfIntersect to exclude unnecessary intersections
216 Let us rotate the source mesh by pi/4 angle around Y axis. The result matrix is
218 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
219 :start-after: UG_Projection_8
220 :end-before: UG_Projection_8
224 [{0: 0.46155716207961217}]
226 If we use setMaxDistance3DSurfIntersect, the result matrix shows that no intersection found:
228 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
229 :start-after: UG_Projection_9
230 :end-before: UG_Projection_9
236 Another function useful to avoid unnecessary intersection is setMinDotBtwPlane3DSurfIntersect. It tells the remapper not to intersect cells whose normals are too much different. setMinDotBtwPlane3DSurfIntersect specifies minimal dot product of unitary normal vectors of a source and target cells.
238 Let us switch off setMaxDistance3DSurfIntersect by passing a negative value. And use setMinDotBtwPlane3DSurfIntersect to avoid intersecting cells that has 45 degrees angle between their normals in our case.
240 .. literalinclude:: ../../../src/MEDCoupling_Swig/UsersGuideExamplesTest.py
241 :start-after: UG_Projection_10
242 :end-before: UG_Projection_10