Salome HOME
Debug of CMake build procedure
[modules/med.git] / doc / doxygen / doxfiles / medcoupling / MEDCouplingArray.dox
1
2 /*!
3
4 \page MEDCouplingArrayPage MEDCoupling Arrays
5
6 [TOC]
7
8 \section MEDCouplingArrayIntro Introduction
9
10 One of the most basic concept mainly used all over MEDCoupling is
11 MEDCoupling array.
12
13 This concept is used all over
14 \ref medcoupling "MEDCoupling", \ref paramedmem "ParaMEDMEM", \ref medloader "MEDLoader" modules so it should be correctly
15 handled to play well with \ref MEDCouplingMeshesPage "Meshes" and \ref MEDCouplingFieldsPage "Fields".
16
17 \ref ParaMEDMEM::DataArray "DataArrays" are the atomic element of potentially heavy in memory objects in \ref medcoupling "MEDCoupling", \ref paramedmem "ParaMEDMEM" and \ref medloader "MEDLoader".
18
19 There are for the moment two types of arrays :
20  - double precision float (64 bits) array incarnated by \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble class".
21  - signed integer (32 bits) array incarnated by \ref ParaMEDMEM::DataArrayInt "DataArrayInt class".
22
23 \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" and \ref ParaMEDMEM::DataArrayInt "DataArrayInt" classes inherits from
24 \ref ParaMEDMEM::DataArray "DataArray" \b non \b instantiable \b class that factorizes some common methods of inherited instantiable classes.
25
26 In the rest of the documentation \b DataArray will be used for both \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" and \ref ParaMEDMEM::DataArrayInt "DataArrayInt".
27
28 \section MEDCouplingArrayBasics Basics concepts of the DataArrays.
29
30 It will be presented in this section common concept shared by the two classes to \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" and \ref ParaMEDMEM::DataArrayInt "DataArrayInt".
31
32 \subsection MEDCouplingArrayBasicsName Name
33
34 A \ref ParaMEDMEM::DataArray "DataArray" instance has an attribute **name**.
35
36 **name** is particularly useful for \ref ParaMEDMEM::DataArray "DataArray" representing profiles, families, groups, fields in MEDLoader.
37 But excepted these useful usecases, **name** attribute is often ignored when \ref ParaMEDMEM::DataArray "DataArrays" are aggregated (field array, connectivity, coordinates) in a bigger object.
38 Whatever the usage of the **name** attribute of \ref ParaMEDMEM::DataArray "DataArrays", all methods in ParaMEDMEM::DataArrayDouble and ParaMEDMEM::DataArrayInt class deal with **name** as they do for components names.
39
40 \subsection MEDCouplingArrayBasicsTuplesAndCompo Raw data, tuples and components of DataArrays.
41
42 The main goal of \ref ParaMEDMEM::DataArray "DataArray" is to store contiguous vector of atomical elements with same basic datatype (signed integers, double precision...). This vector of atomical elements is called **raw data** of \ref ParaMEDMEM::DataArray "DataArray".
43
44 The size of this vector of data is called <em>"number of elements"</em>. So the number of bytes stored by a \ref ParaMEDMEM::DataArray "DataArray" instance, is equal to
45 the  product of the __number of elements__ * __constant size of DataType__ .
46
47 As \ref ParaMEDMEM::DataArray "DataArray" instances are designed to store vector fields, tensor fields, coordinate of nodes, the notion of _components_ has been added.
48
49 So, \ref ParaMEDMEM::DataArray "DataArrays" have an additional attribute that is number of components that represent the size of a contiguous set of atomical elements.
50 The vector of atomical elements stored into \ref ParaMEDMEM::DataArray "DataArrays" are grouped in contiguous memory set of atomical elements having each same size.
51
52 The contiguous set of atomical elements is called **tuple**. And each **tuple** stored in raw data, has a length exactly equal to the number of components of
53 \ref ParaMEDMEM::DataArray "DataArray" storing it.
54
55 Thus :
56
57 \f[
58  N_{elements}=N_{tuples}*N_{components}.
59 \f]
60
61 \f[
62  N_{bytes}=N_{elements}*sizeof(DataType)=N_{tuples}*N_{components}*sizeof(DataType).
63 \f]
64
65 In other words, **raw data** of \ref ParaMEDMEM::DataArray "DataArrays" can be seen as a dense matrix, whose number of components would be the row size and number of tuples
66 would be the column size. In this point of view of \ref ParaMEDMEM::DataArray "DataArrays" a **tuple** is represented by the corresponding row in the dense matrix.
67
68 Typically in the **raw data** of  \ref ParaMEDMEM::DataArray "DataArrays" **number of tuples** is highly bigger than **number of components** !
69
70 To finish, raw data is stored tuples by tuples, in another words, in **full interlace mode**, which is the natural storage strategy in C/C++ world.
71
72 For example, let's consider a DataArray having 3 components (called *x* for the first component, *y* for the second, and *z* for the third) and composed by 5 tuples.
73 \n The *raw data* of the DataAarray instance will be organized in memory like that : \f$ x_0,y_0,z_0,x_1,y_1,z_1,x_2,y_2,z_2,x_3,y_3,z_3,x_4,y_4,z_4 \f$.
74
75
76 \subsection MEDCouplingArrayBasicsCompoName Information on components name.
77
78 As seen in the sub section above, a \ref ParaMEDMEM::DataArray "DataArray" instance has a defined number of components.
79
80 There is an information attached to each of these components constituting the \ref ParaMEDMEM::DataArray "DataArray".
81
82 This information is concretely a string of characters that allows, if needed, to give information about the corresponding component.
83
84 The format chosen in **MEDCoupling** for information on is "MY_COMPO_INFO [MYUNIT]". If needed, the unit attached to the component
85 should be put between "[" and "]" after the information of the components after one space character.
86
87 \subsection MEDCouplingArrayBasicsTimeLabel DataArrays and TimeLabel.
88
89 \ref ParaMEDMEM::DataArray "DataArrays instances" can consume big amount of data in memory so they inherit from \ref MEDCouplingTimeLabelPage "TimeLabel".
90 So in C++ it is a good practice to use :
91 - \c getConstPointer method in readonly access.
92 - \c getPointer method only if write is needed.
93
94 If the user in C++ or Python wants to modify intensively its **big** \ref ParaMEDMEM::DataArray "DataArray" instance **not** using raw data pointer it is better to invoke
95 \c setIJSilent just after invocation of \c declareAsNew instead of calling \c setIJ method that will increment time label of \ref ParaMEDMEM::DataArray "DataArray" instance
96 on each call.
97
98 \c setIJ method usage should be reduced to little modification sessions.
99
100 \section MEDCouplingArrayBuildFromScratch Building an array from scratch
101
102 Here is a description of typical usages of \ref ParaMEDMEM::DataArrayDouble "MEDCoupling arrays".
103
104 \if ENABLE_EXAMPLES
105 \ref MEDCouplingArraySteps1 "Here is a C++ example."<br>
106 \ref MEDCouplingArraySteps0 "Here is a Python example."<br>
107 \endif
108
109 \section MEDCouplingArrayBasicsCopy Copy DataArrays.
110
111 As \ref ParaMEDMEM::DataArray "DataArrays" are the atomic entity of potentially big memory objects into \ref medcoupling "MEDCoupling"
112 , \ref ParaMEDMEM::DataArray "DataArrays" introduces concepts of copy and comparison that will be used by aggregating classes.
113
114 For more complex objects (that aggregate themselves big objects)
115 like ParaMEDMEM::MEDCouplingFieldDouble the concept of copy (shallow or deep) is less straight forward because which aggregated subobjects are copied or not.
116
117 \subsection MEDCouplingArrayBasicsCopyDeep Deep copy of DataArray
118
119 As for all potentially heavy memory consumer objects in \ref medcoupling "MEDCoupling", \ref ParaMEDMEM::DataArray "DataArrays" implement
120  method \c deepCpy. This method deeply copies an instance. The life cycle of the returned object is *fully* independent from the instance on which the method
121 \c deepCpy has been invoked.
122
123 \if ENABLE_EXAMPLES
124 \ref cpp_mcdataarray_deepcopy "Here is a C++ example."<br>
125 \endif
126
127 \subsection MEDCouplingArrayBasicsCopyShallow Shallow copy of DataArray
128
129 As \ref ParaMEDMEM::DataArray "DataArrays" are the atomic entity of potentially big memory objects into \ref medcoupling "MEDCoupling", the shallow copy
130 simply returns the same object with the reference counter incremented.
131
132 \if ENABLE_EXAMPLES
133 \ref cpp_mcdataarray_shallowcopy "Here is a C++ example."<br>
134 \endif
135
136 \section MEDCouplingArrayBasicsCompare Compare DataArrays.
137
138 Comparison is \ref medcoupling "MEDCoupling" is a concept highly sensitive because big amount of tests uses this to state about the success or the fail of these tests.
139 There are two types of comparison :
140
141 - strict, that compares strictly all the non mutable attributes (state sensitive). Methods to perform this strict comparison are :
142   - ParaMEDMEM::DataArrayInt::isEqual
143   - ParaMEDMEM::DataArrayDouble::isEqual.
144
145 - less strict, that focus only on non string attributes. Methods to perform less strict comparison are :
146   - ParaMEDMEM::DataArrayInt::isEqualWithoutConsideringStr
147   - ParaMEDMEM::DataArrayDouble::isEqualWithoutConsideringStr
148
149 \section MEDCouplingArrayFill Filling DataArray with values
150
151 Both DataArrayDouble and DataArrayInt provide comfort methods that
152 fill the array with some values. These methods are:
153 - ParaMEDMEM::DataArrayInt::fillWithZero and
154   ParaMEDMEM::DataArrayDouble::fillWithZero which assigns zero to all
155   values in array.
156 - ParaMEDMEM::DataArrayInt::fillWithValue and
157   ParaMEDMEM::DataArrayDouble::fillWithValue which assigns a certain value to all
158   values in array.
159 - ParaMEDMEM::DataArrayInt::iota() and
160   ParaMEDMEM::DataArrayDouble::iota() which assigns incrementing values to all
161   values in array.
162
163 \section MEDCouplingArrayRenumbering Array renumbering
164
165 Here is presented all it is necessary to know concerning renumbering.
166 Renumbering is intensely required in %MEDLoader in %ParaMEDMEM. One of the user of renumbering is MED file for I/O where cells are sorted by type.
167 But it is also used on operations of node cell merging. It is also used in parallel mode when splitting of mesh is needed...
168
169 Formally a renumbering is a mathematical application that can be surjective, injective or bijective. This application is defined using an instance of
170 \ref ParaMEDMEM::DataArrayInt "DataArrayInt". There are different ways to define this application.
171
172 \subsection MEDCouplingArrayRenumberingO2N Old to new mode
173
174 The old to new mode is particularly recommended for surjective and bijective application. This is typically the case of \ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "MEDCouplingUMesh::mergeNodes" method.
175 Let's consider a call to \ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes" that reduces the number of nodes from 5 nodes to 3 nodes.\n
176 In old to new mode the array \b MySurjection that specifies this surjection will have 5 tuples and 1 component. The content of the 5*1 values will be in {0,1,2}.\n
177
178 If \b MySujection equals [2,1,0,1,2], it means that :
179
180 - old id #0 will have new id equal to 2
181 - old id #1 will have new id equal to 1
182 - old id #2 will have new id equal to 0
183 - old id #3 will have new id equal to 1 like old id #1
184 - old id #4 will have new id equal to 2 like old id #0
185
186 This is the most common mode of renumbering in MEDCoupling because there is more methods implying renumbering that reduce the number of entities than method that increase number of entities.
187
188 Method in old to new mode that works on bijective applications :
189
190 - \ref ParaMEDMEM::DataArrayDouble::renumber "DataArrayDouble::renumber"
191 - \ref ParaMEDMEM::DataArrayDouble::renumberInPlace "DataArrayDouble::renumberInPlace"
192
193 Method in old to new mode that works on surjective applications :
194
195 - \ref ParaMEDMEM::DataArrayDouble::renumberAndReduce "DataArrayDouble::renumberAndReduce"
196
197 Sometimes the format old to new for surjections can be replaced by another format with 2 arrays. Less compact in memory. The \ref ParaMEDMEM::DataArrayInt::changeSurjectiveFormat "DataArrayInt::changeSurjectiveFormat" method performs that.
198
199 \subsection MEDCouplingArrayRenumberingN2O New to old mode
200
201 The new to old mode is particularly recommended for strictly injective and bijective permutations. This is particularly useful for methods that increase the number of entities like for example
202 \ref ParaMEDMEM::MEDCouplingUMesh::simplexize "MEDCouplingUMesh::simplexize".\n
203 All non static methods in \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" or \ref ParaMEDMEM::DataArrayInt "DataArrayInt" having as last letter \b R (meaning Reversed) in capital works with
204 the mode new to old.
205 Let's consider a call to \ref ParaMEDMEM::MEDCouplingUMesh::simplexize "simplexize" that increases the number of cell from 4 cells to 6 cells.\n
206 In new to old mode the array \b MyInjection that specifies this injection will have 6 tuples and 1 component. The content of the 5*1 values will be in {0,1,2,3}.\n
207 If \b MyInjection equals [2,0,1,1,3,0] it means that :
208
209 - new id #0 comes from old id 2
210 - new id #1 comes from old id 0
211 - new id #2 comes from old id 1
212 - new id #3 comes from old id 1
213 - new id #4 comes from old id 3
214 - new id #5 comes from old id 0
215
216 Method in new to old mode that works on bijective applications :
217
218 - \ref ParaMEDMEM::DataArrayDouble::renumberR "DataArrayDouble::renumberR"
219 - \ref ParaMEDMEM::DataArrayDouble::renumberInPlace "DataArrayDouble::renumberInPlaceR"
220
221 Method in new to old mode that works on surjective applications :
222
223 - \ref ParaMEDMEM::DataArrayDouble::selectByTupleId "DataArrayDouble::selectByTupleId"
224 - \ref ParaMEDMEM::DataArrayDouble::selectByTupleIdSafe "DataArrayDouble::selectByTupleIdSafe"
225 - \ref ParaMEDMEM::DataArrayDouble::selectByTupleId2 "DataArrayDouble::selectByTupleId2"
226 - \ref ParaMEDMEM::DataArrayDouble::selectByTupleRanges "DataArrayDouble::selectByTupleRanges"
227
228 \section MEDCouplingArrayApplyFunc Application of a function on DataArrayDouble instances.
229
230 This section is only dedicated for \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble instances".
231
232 It is possible to apply to \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble instance" a function given by a string.
233
234 There are different API for applyFunc* methods of \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble class".
235
236 \subsection MEDCouplingArrayApplyFuncExpr Expressions supported
237
238 In order to reduce as much as possible dependencies, a little dynamic formula interpreter has been developed into INTERP_KERNEL.
239 This dynamic expression evaluator can deal the following exhaustive list :
240
241 - +,-,*,^ (^ for exponent 3^2==9)
242 - sin,cos,tan,sqrt,abs,exp,max,min,ln (neper logarithm), log (neper logarithm), log10 (decimal logarithm),
243 - >,<
244 - if
245
246 The expression evaluator is also sensitive to the following var pattern : IVec, JVec, KVec, LVec,... ,ZVec
247
248 - IVec stands for unitary vector [1,0,0,0,...]
249 - JVec stands for unitary vector [0,1,0,0,...]
250 - KVec stands for unitary vector [0,0,1,0,...]
251 - ...
252
253 The dynamic expression evaluator works tuple by tuple through the *raw data* of DataArrayDouble instance.
254
255 The principle of the dynamic expression evaluator is the following :
256
257 - Given the input string a compilation tree is built whose leaves are either constants or variables.
258   At this phase only syntax errors are thrown.
259 \anchor MEDCouplingArrayApplyFuncExprA1
260 - Then given the computed tree, a link phase is performed to accelerate evaluation. At this phase the incoherence between the number of
261   components and the number of variables are detected.
262
263 - The given the preprocessed tree given an input tuple a preallocated tuple is fed with the result of the evaluation.
264   At this last phase only mathematical errors are thrown (division by 0, log(0), sqrt of a negative number ...)
265
266 \subsection MEDCouplingArrayApplyFunc0 applyFunc method with only one parameter
267
268 This method produces a newly allocated DataArrayDouble instance having exactly the same number of components **and** number of tuples than the instance on which the
269 \ref ParaMEDMEM::DataArrayDouble::applyFunc(const char *) const applyFunc method is applied.
270
271 **This method is useful when the evaluation expression do not need to consider the components of each tuple separately**.
272
273 That's why this method of \ref ParaMEDMEM::DataArrayDouble::applyFunc(const char *) const applyFunc method with one parameter accepts at most only one variable.
274
275 If it is not the case an exception is thrown as seen here :
276
277 \snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_1
278
279 Let's take a very simple example on a DataArrayDouble instance \c d having 4 tuples and 2 components.
280
281 In the next example the expression contains only one variable : \c smth.
282 So \c smth represent a tuple of size 2.
283
284 \snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_2
285
286 As the example shows, the output \c d1 has 2 components as \c d.
287
288 Whereas all the components of the input of \c d be not considered separately, it is also, possible with \ref ParaMEDMEM::DataArrayDouble::applyFunc(const char *) const applyFunc method with one parameter
289 to build an output having same number of components than input but where components in input are treated separately.
290
291 Let's build an example using DataArrayDouble instance \c d defined just above.
292
293 \snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_3
294
295 In this example using IVec and JVec it is possible to differentiate output in component #0 and output in component #1 for DataArrayDouble instance \c d2.
296
297 \subsection MEDCouplingArrayApplyFunc1 applyFunc method with only two parameters
298
299 This method also returns a newly allocated DataArrayDouble instance having the same number of tuples than the DataArrayDouble instance on which \ref ParaMEDMEM::DataArrayDouble::applyFunc(int,const char *) const applyFunc method is called, but the contrary to previous \ref MEDCouplingArrayApplyFunc0 "applyFunc with one parameter version" here the number of components is set by the user.
300
301 The big difference with \ref MEDCouplingArrayApplyFunc0 "applyFunc method with one parameter" seen above is that here components of tuples are treated separately.
302
303 The method that implements it is \ref ParaMEDMEM::DataArrayDouble::applyFunc(int,const char *) const here.
304
305 Here the number of variables appearing in the expression should be equal at most to the number of component of the DataArrayDouble instance on which \ref ParaMEDMEM::DataArrayDouble::applyFunc(int,const char *) const applyFunc method is called.
306
307 Let's consider the following DataArrayDouble having 4 tuples with 3 components called dd.
308
309 \snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_4
310
311 If you intend to create a new DataArrayDouble instance called \c dd1 having only one component that is the result of the sum of first component and the square root of the second component and the third component
312 the invocation should be something like this :
313
314 \snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_5
315
316 \warning In the expression \c "f+sqrt(g)+h", there are 3 variables \c {"g","h","f"}. As seen \ref MEDCouplingArrayApplyFuncExprA1 "in link phase in expression evaluator" it is needed to match a variable to
317 the component id. The strategy of expression evaluator is the following. Sort ascendingly variables using their names and affect component id following this sorted list. It leads to :
318 - \c f will be attached to component #0 of \c dd
319 - \c g will be attached to component #1 of \c dd
320 - \c h will be attached to component #2 of \c dd
321
322 Considering the previous warning, let's try to perform an application of function to compute in a DataArrayDouble instance called \c dd2 starting by adding component #0 and component #2
323 of \c dd.
324 \nThe expression \c "a+c" will add component #0 to component #1 as seen in warning section !!!! It can appear silly, but this strategy has been chosen in order to support different set of variables.
325 \n \ref ParaMEDMEM::DataArrayDouble::applyFunc2 "applyFunc2" and \ref ParaMEDMEM::DataArrayDouble::applyFunc3 "applyFunc3" methods have been developed to remedy to that feature that can be surprising.
326 \n These two methods are explained respectively \ref MEDCouplingArrayApplyFunc2 "here for applyFunc2" and \ref MEDCouplingArrayApplyFunc3 "here for applyFunc3".
327
328 Whatever it is possible to find a workaround using \ref ParaMEDMEM::DataArrayDouble::applyFunc(int,const char *) const applyFunc with 2 parameters.
329 \n Here is a solution to compute \c dd2 :
330
331 \snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_6
332
333 \subsection MEDCouplingArrayApplyFunc2 applyFunc2 method
334
335 The method that implements it is \ref ParaMEDMEM::DataArrayDouble::applyFunc2 here.
336
337 This method is very close to \ref MEDCouplingArrayApplyFunc1 "applyFunc method with only two parameters".
338
339 The only difference is the mapping between variables found in expression and tuple id. Rather than using rank in string sorting as \ref MEDCouplingArrayApplyFunc1 "applyFunc method with only two parameters uses" here the component information are considered.
340
341 Let's consider DataArrayDouble instance \c ddd constituted with 4 tuples containing each 3 components. The components are named respectively \c {"Y","AA","GG"} with following different units attached on them.
342
343 \snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_7
344
345 To compute the sum of the first component (component #0) and the third component (component #2) simply do that :
346
347 \snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_8
348
349 \subsection MEDCouplingArrayApplyFunc3 applyFunc3 method
350
351 The method that implements it is \ref ParaMEDMEM::DataArrayDouble::applyFunc3 here.
352
353 This method is very close to \ref MEDCouplingArrayApplyFunc1 "applyFunc method with only two parameters" and \ref MEDCouplingArrayApplyFunc2 "applyFunc2".
354
355 The only difference is the mapping between variables found in expression and tuple id. Rather than using rank in string sorting as in \ref MEDCouplingArrayApplyFunc1 "applyFunc method with only two parameters uses" or the component information as in \ref MEDCouplingArrayApplyFunc2 "applyFunc2", here an explicit vector is given in input.
356
357 Let's consider DataArrayDouble instance \c ddd constituted with 4 tuples containing each 3 components. To add first component (component #0) and the third component (component #2) simply do that :
358
359 \snippet MEDCouplingExamplesTest.py PySnippetDataArrayApplyFunc1_9
360
361 */