Salome HOME
warning hunting in medcoupling to ease template action in DataArrays
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingFieldDouble.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingFieldDouble.hxx"
22 #include "MEDCouplingFieldTemplate.hxx"
23 #include "MEDCouplingFieldT.txx"
24 #include "MEDCouplingFieldInt.hxx"
25 #include "MEDCouplingUMesh.hxx"
26 #include "MEDCouplingTimeDiscretization.hxx"
27 #include "MEDCouplingFieldDiscretization.hxx"
28 #include "MCAuto.txx"
29 #include "MEDCouplingVoronoi.hxx"
30 #include "MEDCouplingNatureOfField.hxx"
31
32 #include "InterpKernelAutoPtr.hxx"
33 #include "InterpKernelGaussCoords.hxx"
34
35 #include <sstream>
36 #include <limits>
37 #include <algorithm>
38 #include <functional>
39
40 using namespace MEDCoupling;
41
42 template class MEDCoupling::MEDCouplingFieldT<double>;
43
44 /*!
45  * Creates a new MEDCouplingFieldDouble, of given spatial type and time discretization.
46  * For more info, see \ref MEDCouplingFirstSteps3.
47  * \param [in] type - the type of spatial discretization of the created field, one of
48  *        (\ref MEDCoupling::ON_CELLS "ON_CELLS", 
49  *         \ref MEDCoupling::ON_NODES "ON_NODES",
50  *         \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT", 
51  *         \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE",
52  *         \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR").
53  * \param [in] td - the type of time discretization of the created field, one of
54  *        (\ref MEDCoupling::NO_TIME "NO_TIME", 
55  *         \ref MEDCoupling::ONE_TIME "ONE_TIME", 
56  *         \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME", 
57  *         \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
58  * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
59  *         caller is to delete this field using decrRef() as it is no more needed. 
60  */
61 MEDCouplingFieldDouble* MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td)
62 {
63   return new MEDCouplingFieldDouble(type,td);
64 }
65
66 /*!
67  * Creates a new MEDCouplingFieldDouble, of a given time discretization and with a
68  * spatial type and supporting mesh copied from a given 
69  * \ref MEDCouplingFieldTemplatesPage "field template".
70  * For more info, see \ref MEDCouplingFirstSteps3.
71  * \warning This method does not deeply copy neither the mesh nor the spatial
72  * discretization. Only a shallow copy (reference) is done for the mesh and the spatial
73  * discretization!
74  * \param [in] ft - the \ref MEDCouplingFieldTemplatesPage "field template" defining
75  *        the spatial discretization and the supporting mesh.
76  * \param [in] td - the type of time discretization of the created field, one of
77  *        (\ref MEDCoupling::NO_TIME "NO_TIME", 
78  *         \ref MEDCoupling::ONE_TIME "ONE_TIME", 
79  *         \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME", 
80  *         \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
81  * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
82  *         caller is to delete this field using decrRef() as it is no more needed. 
83  */
84 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td)
85 {
86   return new MEDCouplingFieldDouble(ft,td);
87 }
88
89 /*!
90  * Sets a time \a unit of \a this field. For more info, see \ref MEDCouplingFirstSteps3.
91  * \param [in] unit \a unit (string) in which time is measured.
92  */
93 //void MEDCouplingFieldDouble::setTimeUnit(const std::string& unit)
94
95 /*!
96  * Returns a time unit of \a this field.
97  * \return a string describing units in which time is measured.
98  */
99 //std::string MEDCouplingFieldDouble::getTimeUnit() const
100
101
102 /*!
103  * This method if possible the time information (time unit, time iteration, time unit and time value) with its support
104  * that is to say its mesh.
105  * 
106  * \throw  If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is
107  *         NO_TIME.
108  */
109 void MEDCouplingFieldDouble::synchronizeTimeWithSupport()
110 {
111   timeDiscr()->synchronizeTimeWith(_mesh);
112 }
113
114 /*!
115  * Returns a new MEDCouplingFieldDouble which is a copy of \a this one. The data
116  * of \a this field is copied either deep or shallow depending on \a recDeepCpy
117  * parameter. But the underlying mesh is always shallow copied.
118  * Data that can be copied either deeply or shallow are:
119  * - \ref MEDCouplingTemporalDisc "temporal discretization" data that holds array(s)
120  * of field values,
121  * - \ref MEDCouplingSpatialDisc "a spatial discretization".
122  * 
123  * \c clone(false) is rather dedicated for advanced users that want to limit the amount
124  * of memory. It allows the user to perform methods like operator+(), operator*()
125  * etc. with \a this and the returned field. If the user wants to duplicate deeply the
126  * underlying mesh he should call cloneWithMesh() method or deepCopy() instead. 
127  * \warning The underlying \b mesh of the returned field is **always the same**
128  *         (pointer) as \a this one **whatever the value** of \a recDeepCpy parameter.
129  *  \param [in] recDeepCpy - if \c true, the copy of the underlying data arrays is
130  *         deep, else all data arrays of \a this field are shared by the new field.
131  *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The
132  *         caller is to delete this field using decrRef() as it is no more needed.
133  * \sa cloneWithMesh()
134  */
135 MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
136 {
137   return new MEDCouplingFieldDouble(*this,recDeepCpy);
138 }
139
140 /*!
141  * Returns a new MEDCouplingFieldDouble which is a deep copy of \a this one **including
142  * the mesh**.
143  * The result of this method is exactly the same as that of \c cloneWithMesh(true).
144  * So the resulting field can not be used together with \a this one in the methods
145  * like operator+(), operator*() etc. To avoid deep copying the underlying mesh,
146  * the user can call clone().
147  *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The
148  *         caller is to delete this field using decrRef() as it is no more needed.
149  * \sa cloneWithMesh()
150  */
151 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCopy() const
152 {
153   return cloneWithMesh(true);
154 }
155
156 /*!
157  * Creates a new MEDCouplingFieldDouble of given
158  * \ref MEDCouplingTemporalDisc "temporal discretization". The result field either
159  * shares the data array(s) with \a this field, or holds a deep copy of it, depending on
160  * \a deepCopy parameter. But the underlying \b mesh is always **shallow copied**.
161  * \param [in] td - the type of time discretization of the created field, one of
162  *        (\ref MEDCoupling::NO_TIME "NO_TIME", 
163  *         \ref MEDCoupling::ONE_TIME "ONE_TIME", 
164  *         \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME", 
165  *         \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
166  * \param [in] deepCopy - if \c true, the copy of the underlying data arrays is
167  *         deep, else all data arrays of \a this field are shared by the new field.
168  * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
169  *         caller is to delete this field using decrRef() as it is no more needed. 
170  * 
171  * \if ENABLE_EXAMPLES
172  * \ref cpp_mcfielddouble_buildNewTimeReprFromThis "Here is a C++ example."<br>
173  * \ref py_mcfielddouble_buildNewTimeReprFromThis "Here is a Python example."
174  * \endif
175  * \sa clone()
176  */
177 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const
178 {
179   MEDCouplingTimeDiscretization *tdo=timeDiscr()->buildNewTimeReprFromThis(td,deepCpy);
180   MCAuto<MEDCouplingFieldDiscretization> disc;
181   if(_type)
182     disc=_type->clone();
183   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),tdo,disc.retn()));
184   ret->setMesh(getMesh());
185   ret->setName(getName());
186   ret->setDescription(getDescription());
187   return ret.retn();
188 }
189
190 /*!
191  * This method converts a field on nodes (\a this) to a cell field (returned field). The convertion is a \b non \b conservative remapping !
192  * This method is useful only for users that need a fast convertion from node to cell spatial discretization. The algorithm applied is simply to attach
193  * to each cell the average of values on nodes constituting this cell.
194  *
195  * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
196  *         caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this.
197  * \throw If \a this spatial discretization is empty or not ON_NODES.
198  * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkConsistencyLight).
199  * 
200  * \warning This method is a \b non \b conservative method of remapping from node spatial discretization to cell spatial discretization.
201  * If a conservative method of interpolation is required MEDCoupling::MEDCouplingRemapper class should be used instead with "P1P0" method.
202  */
203 MEDCouplingFieldDouble *MEDCouplingFieldDouble::nodeToCellDiscretization() const
204 {
205   checkConsistencyLight();
206   TypeOfField tf(getTypeOfField());
207   if(tf!=ON_NODES)
208     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::nodeToCellDiscretization : this field is expected to be on ON_NODES !");
209   MCAuto<MEDCouplingFieldDouble> ret(clone(false));
210   MCAuto<MEDCouplingFieldDiscretizationP0> nsp(new MEDCouplingFieldDiscretizationP0);
211   ret->setDiscretization(nsp);
212   const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkConsistencyLight call
213   int nbCells(m->getNumberOfCells());
214   std::vector<DataArrayDouble *> arrs(getArrays());
215   std::size_t sz(arrs.size());
216   std::vector< MCAuto<DataArrayDouble> > outArrsSafe(sz); std::vector<DataArrayDouble *> outArrs(sz);
217   for(std::size_t j=0;j<sz;j++)
218     {
219       int nbCompo(arrs[j]->getNumberOfComponents());
220       outArrsSafe[j]=DataArrayDouble::New(); outArrsSafe[j]->alloc(nbCells,nbCompo);
221       outArrsSafe[j]->copyStringInfoFrom(*arrs[j]);
222       outArrs[j]=outArrsSafe[j];
223       double *pt(outArrsSafe[j]->getPointer());
224       const double *srcPt(arrs[j]->begin());
225       for(int i=0;i<nbCells;i++,pt+=nbCompo)
226         {
227           std::vector<int> nodeIds;
228           m->getNodeIdsOfCell(i,nodeIds);
229           std::fill(pt,pt+nbCompo,0.);
230           std::size_t nbNodesInCell(nodeIds.size());
231           for(std::size_t k=0;k<nbNodesInCell;k++)
232             std::transform(srcPt+nodeIds[k]*nbCompo,srcPt+(nodeIds[k]+1)*nbCompo,pt,pt,std::plus<double>());
233           if(nbNodesInCell!=0)
234             std::transform(pt,pt+nbCompo,pt,std::bind2nd(std::multiplies<double>(),1./((double)nbNodesInCell)));
235           else
236             {
237               std::ostringstream oss; oss << "MEDCouplingFieldDouble::nodeToCellDiscretization : Cell id #" << i << " has been detected to have no nodes !";
238               throw INTERP_KERNEL::Exception(oss.str());
239             }
240         }
241     }
242   ret->setArrays(outArrs);
243   return ret.retn();
244 }
245
246 /*!
247  * This method converts a field on cell (\a this) to a node field (returned field). The convertion is a \b non \b conservative remapping !
248  * This method is useful only for users that need a fast convertion from cell to node spatial discretization. The algorithm applied is simply to attach
249  * to each node the average of values on cell sharing this node. If \a this lies on a mesh having orphan nodes the values applied on them will be NaN (division by 0.).
250  *
251  * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
252  *         caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this.
253  * \throw If \a this spatial discretization is empty or not ON_CELLS.
254  * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkConsistencyLight).
255  *
256  * \warning This method is a \b non \b conservative method of remapping from cell spatial discretization to node spatial discretization.
257  * If a conservative method of interpolation is required MEDCoupling::MEDCouplingRemapper class should be used instead with "P0P1" method.
258  */
259 MEDCouplingFieldDouble *MEDCouplingFieldDouble::cellToNodeDiscretization() const
260 {
261   checkConsistencyLight();
262   TypeOfField tf(getTypeOfField());
263   if(tf!=ON_CELLS)
264     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::cellToNodeDiscretization : this field is expected to be on ON_CELLS !");
265   MCAuto<MEDCouplingFieldDouble> ret(clone(false));
266   MCAuto<MEDCouplingFieldDiscretizationP1> nsp(new MEDCouplingFieldDiscretizationP1);
267   ret->setDiscretization(nsp);
268   const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkConsistencyLight call
269   MCAuto<DataArrayInt> rn(DataArrayInt::New()),rni(DataArrayInt::New());
270   m->getReverseNodalConnectivity(rn,rni);
271   MCAuto<DataArrayInt> rni2(rni->deltaShiftIndex());
272   MCAuto<DataArrayDouble> rni3(rni2->convertToDblArr()); rni2=0;
273   std::vector<DataArrayDouble *> arrs(getArrays());
274   std::size_t sz(arrs.size());
275   std::vector< MCAuto<DataArrayDouble> > outArrsSafe(sz); std::vector<DataArrayDouble *> outArrs(sz);
276   for(std::size_t j=0;j<sz;j++)
277     {
278       MCAuto<DataArrayDouble> tmp(arrs[j]->selectByTupleIdSafe(rn->begin(),rn->end()));
279       outArrsSafe[j]=(tmp->accumulatePerChunck(rni->begin(),rni->end())); tmp=0;
280       outArrsSafe[j]->divideEqual(rni3);
281       outArrsSafe[j]->copyStringInfoFrom(*arrs[j]);
282       outArrs[j]=outArrsSafe[j];
283     }
284   ret->setArrays(outArrs);
285   return ret.retn();
286 }
287
288 /*!
289  * Returns a string describing \a this field. The string includes info on
290  * - name,
291  * - description,
292  * - \ref MEDCouplingSpatialDisc "spatial discretization",
293  * - \ref MEDCouplingTemporalDisc "time discretization",
294  * - components,
295  * - mesh,
296  * - contents of data arrays.
297  *
298  *  \return std::string - the string describing \a this field.
299  */
300 std::string MEDCouplingFieldDouble::advancedRepr() const
301 {
302   std::ostringstream ret;
303   ret << "FieldDouble with name : \"" << getName() << "\"\n";
304   ret << "Description of field is : \"" << getDescription() << "\"\n";
305   if(_type)
306     { ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; }
307   else
308     { ret << "FieldDouble has no space discretization set !\n"; }
309   if(timeDiscr())
310     { ret << "FieldDouble time discretization is : " << timeDiscr()->getStringRepr() << "\n"; }
311   else
312     { ret << "FieldDouble has no time discretization set !\n"; }
313   if(getArray())
314     ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
315   if(_mesh)
316     ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr();
317   else
318     ret << "Mesh support information : No mesh set !\n";
319   std::vector<DataArrayDouble *> arrays;
320   timeDiscr()->getArrays(arrays);
321   int arrayId=0;
322   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++)
323     {
324       ret << "Array #" << arrayId << " :\n__________\n";
325       if(*iter)
326         (*iter)->reprWithoutNameStream(ret);
327       else
328         ret << "Array empty !";
329       ret << "\n";
330     }
331   return ret.str();
332 }
333
334 std::string MEDCouplingFieldDouble::writeVTK(const std::string& fileName, bool isBinary) const
335 {
336   std::vector<const MEDCouplingFieldDouble *> fs(1,this);
337   return MEDCouplingFieldDouble::WriteVTK(fileName,fs,isBinary);
338 }
339
340 /*!
341  * This method states if \a this and 'other' are compatibles each other before performing any treatment.
342  * This method is good for methods like : mergeFields.
343  * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields.
344  */
345 bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const
346 {
347   if(!MEDCouplingField::areCompatibleForMerge(other))
348     return false;
349   const MEDCouplingFieldDouble *otherC(dynamic_cast<const MEDCouplingFieldDouble *>(other));
350   if(!otherC)
351     return false;
352   if(!timeDiscr()->areCompatible(otherC->timeDiscr()))
353     return false;
354   return true;
355 }
356
357 /*!
358  * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible,
359  * except that \a this and other can have different number of components.
360  */
361 bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const
362 {
363   if(!MEDCouplingField::areStrictlyCompatible(other))
364     return false;
365   if(!timeDiscr()->areCompatibleForMeld(other->timeDiscr()))
366     return false;
367   return true;
368 }
369
370 /*!
371  * Permutes values of \a this field according to a given permutation array for cells
372  * renumbering. The underlying mesh is deeply copied and its cells are also permuted. 
373  * The number of cells remains the same; for that the permutation array \a old2NewBg
374  * should not contain equal ids.
375  * ** Warning, this method modifies the mesh aggreagated by \a this (by performing a deep copy ) **.
376  *
377  *  \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
378  *         to be equal to \a this->getMesh()->getNumberOfCells().
379  *  \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation
380  *         array, so that its maximal cell id to correspond to (be less than) the number
381  *         of cells in mesh. This new array is then used for the renumbering. If \a 
382  *         check == \c false, \a old2NewBg is used as is, that is less secure as validity 
383  *         of ids in \a old2NewBg is not checked.
384  *  \throw If the mesh is not set.
385  *  \throw If the spatial discretization of \a this field is NULL.
386  *  \throw If \a check == \c true and \a old2NewBg contains equal ids.
387  *  \throw If mesh nature does not allow renumbering (e.g. structured mesh).
388  * 
389  *  \if ENABLE_EXAMPLES
390  *  \ref cpp_mcfielddouble_renumberCells "Here is a C++ example".<br>
391  *  \ref  py_mcfielddouble_renumberCells "Here is a Python example".
392  *  \endif
393  */
394 void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check)
395 {
396   renumberCellsWithoutMesh(old2NewBg,check);
397   MCAuto<MEDCouplingMesh> m=_mesh->deepCopy();
398   m->renumberCells(old2NewBg,check);
399   setMesh(m);
400   updateTime();
401 }
402
403 /*!
404  * Permutes values of \a this field according to a given permutation array for cells
405  * renumbering. The underlying mesh is \b not permuted. 
406  * The number of cells remains the same; for that the permutation array \a old2NewBg
407  * should not contain equal ids.
408  * This method performs a part of job of renumberCells(). The reasonable use of this
409  * method is only for multi-field instances lying on the same mesh to avoid a
410  * systematic duplication and renumbering of _mesh attribute. 
411  * \warning Use this method with a lot of care!
412  *  \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
413  *         to be equal to \a this->getMesh()->getNumberOfCells().
414  *  \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation
415  *         array, so that its maximal cell id to correspond to (be less than) the number
416  *         of cells in mesh. This new array is then used for the renumbering. If \a 
417  *         check == \c false, \a old2NewBg is used as is, that is less secure as validity 
418  *         of ids in \a old2NewBg is not checked.
419  *  \throw If the mesh is not set.
420  *  \throw If the spatial discretization of \a this field is NULL.
421  *  \throw If \a check == \c true and \a old2NewBg contains equal ids.
422  *  \throw If mesh nature does not allow renumbering (e.g. structured mesh).
423  */
424 void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check)
425 {
426   if(!_mesh)
427     throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !");
428   if(_type.isNull())
429     throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !");
430   //
431   _type->renumberCells(old2NewBg,check);
432   std::vector<DataArrayDouble *> arrays;
433   timeDiscr()->getArrays(arrays);
434   std::vector<DataArray *> arrays2(arrays.size()); std::copy(arrays.begin(),arrays.end(),arrays2.begin());
435   _type->renumberArraysForCell(_mesh,arrays2,old2NewBg,check);
436   //
437   updateTime();
438 }
439
440 /*!
441  * Permutes values of \a this field according to a given permutation array for node
442  * renumbering. The underlying mesh is deeply copied and its nodes are also permuted. 
443  * The number of nodes can change, contrary to renumberCells().
444  *  \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
445  *         to be equal to \a this->getMesh()->getNumberOfNodes().
446  *  \param [in] eps - a precision used to compare field values at merged nodes. If
447  *         the values differ more than \a eps, an exception is thrown.
448  *  \throw If the mesh is not set.
449  *  \throw If the spatial discretization of \a this field is NULL.
450  *  \throw If \a check == \c true and \a old2NewBg contains equal ids.
451  *  \throw If mesh nature does not allow renumbering (e.g. structured mesh).
452  *  \throw If values at merged nodes deffer more than \a eps.
453  * 
454  *  \if ENABLE_EXAMPLES
455  *  \ref cpp_mcfielddouble_renumberNodes "Here is a C++ example".<br>
456  *  \ref  py_mcfielddouble_renumberNodes "Here is a Python example".
457  *  \endif
458  */
459 void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps)
460 {
461   const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
462   if(!meshC)
463     throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !");
464   int nbOfNodes=meshC->getNumberOfNodes();
465   MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
466   int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1;
467   renumberNodesWithoutMesh(old2NewBg,newNbOfNodes,eps);
468   meshC2->renumberNodes(old2NewBg,newNbOfNodes);
469   setMesh(meshC2);
470 }
471
472 /*!
473  * Permutes values of \a this field according to a given permutation array for nodes
474  * renumbering. The underlying mesh is \b not permuted. 
475  * The number of nodes can change, contrary to renumberCells().
476  * A given epsilon specifies a threshold of error in case of two nodes are merged but
477  * the difference of values on these nodes are higher than \a eps.
478  * This method performs a part of job of renumberNodes(), excluding node renumbering
479  * in mesh. The reasonable use of this
480  * method is only for multi-field instances lying on the same mesh to avoid a
481  * systematic duplication and renumbering of _mesh attribute. 
482  * \warning Use this method with a lot of care!
483  * \warning In case of an exception thrown, the contents of the data array can be
484  *         partially modified until the exception occurs. 
485  *  \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
486  *         to be equal to \a this->getMesh()->getNumberOfNodes().
487  *  \param [in] newNbOfNodes - a number of nodes in the mesh after renumbering.
488  *  \param [in] eps - a precision used to compare field values at merged nodes. If
489  *         the values differ more than \a eps, an exception is thrown.
490  *  \throw If the mesh is not set.
491  *  \throw If the spatial discretization of \a this field is NULL.
492  *  \throw If values at merged nodes deffer more than \a eps.
493  */
494 void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps)
495 {
496   if(_type.isNull())
497     throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !");
498   std::vector<DataArrayDouble *> arrays;
499   timeDiscr()->getArrays(arrays);
500   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
501     if(*iter)
502       _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter);
503 }
504
505 /*!
506  * Returns all tuple ids of \a this scalar field that fit the range [\a vmin,
507  * \a vmax]. This method calls DataArrayDouble::findIdsInRange().
508  *  \param [in] vmin - a lower boundary of the range. Tuples with values less than \a
509  *         vmin are not included in the result array.
510  *  \param [in] vmax - an upper boundary of the range. Tuples with values more than \a
511  *         vmax are not included in the result array.
512  *  \return DataArrayInt * - a new instance of DataArrayInt holding ids of selected
513  *          tuples. The caller is to delete this array using decrRef() as it is no
514  *          more needed.
515  *  \throw If the data array is not set.
516  *  \throw If \a this->getNumberOfComponents() != 1.
517  */
518 DataArrayInt *MEDCouplingFieldDouble::findIdsInRange(double vmin, double vmax) const
519 {
520   if(getArray()==0)
521     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::findIdsInRange : no default array set !");
522   return getArray()->findIdsInRange(vmin,vmax);
523 }
524
525 MEDCouplingFieldInt *MEDCouplingFieldDouble::convertToIntField() const
526 {
527   MCAuto<MEDCouplingFieldTemplate> tmp(MEDCouplingFieldTemplate::New(*this));
528   int t1,t2;
529   double t0(getTime(t1,t2));
530   MCAuto<MEDCouplingFieldInt> ret(MEDCouplingFieldInt::New(*tmp,getTimeDiscretization()));
531   ret->setTime(t0,t1,t2);
532   if(getArray())
533     {
534       MCAuto<DataArrayInt> arr(getArray()->convertToIntArr());
535       ret->setArray(arr);
536     }
537   return ret.retn();
538 }
539
540 MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(type,MEDCouplingTimeDiscretization::New(td))
541 {
542 }
543
544 /*!
545  * ** WARINING : This method do not deeply copy neither mesh nor spatial discretization. Only a shallow copy (reference) is done for mesh and spatial discretization ! **
546  */
547 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(ft,MEDCouplingTimeDiscretization::New(td),false)
548 {
549 }
550
551 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCpy):MEDCouplingFieldT<double>(other,deepCpy)
552 {
553 }
554
555 MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingFieldT<double>(type,n,td)
556 {
557 }
558
559 /*!
560  * Accumulate values of a given component of \a this field.
561  *  \param [in] compId - the index of the component of interest.
562  *  \return double - a sum value of *compId*-th component.
563  *  \throw If the data array is not set.
564  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
565  *         not respected.
566  */
567 double MEDCouplingFieldDouble::accumulate(int compId) const
568 {
569   if(getArray()==0)
570     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
571   return getArray()->accumulate(compId);
572 }
573
574 /*!
575  * Accumulates values of each component of \a this array.
576  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
577  *         by the caller, that is filled by this method with sum value for each
578  *         component.
579  *  \throw If the data array is not set.
580  */
581 void MEDCouplingFieldDouble::accumulate(double *res) const
582 {
583   if(getArray()==0)
584     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
585   getArray()->accumulate(res);
586 }
587
588 /*!
589  * Returns the maximal value within \a this scalar field. Values of all arrays stored
590  * in \a this->_time_discr are checked.
591  *  \return double - the maximal value among all values of \a this field.
592  *  \throw If \a this->getNumberOfComponents() != 1
593  *  \throw If the data array is not set.
594  *  \throw If there is an empty data array in \a this field.
595  */
596 double MEDCouplingFieldDouble::getMaxValue() const
597 {
598   std::vector<DataArrayDouble *> arrays;
599   timeDiscr()->getArrays(arrays);
600   double ret(-std::numeric_limits<double>::max());
601   bool isExistingArr=false;
602   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
603     {
604       if(*iter)
605         {
606           isExistingArr=true;
607           int loc;
608           ret=std::max(ret,(*iter)->getMaxValue(loc));
609         }
610     }
611   if(!isExistingArr)
612     throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !");
613   return ret;
614 }
615
616 /*!
617  * Returns the maximal value and all its locations within \a this scalar field.
618  * Only the first of available data arrays is checked.
619  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
620  *               tuples holding the maximal value. The caller is to delete it using
621  *               decrRef() as it is no more needed.
622  *  \return double - the maximal value among all values of the first array of \a this filed.
623  *  \throw If \a this->getNumberOfComponents() != 1.
624  *  \throw If there is an empty data array in \a this field.
625  */
626 double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const
627 {
628   std::vector<DataArrayDouble *> arrays;
629   timeDiscr()->getArrays(arrays);
630   double ret(-std::numeric_limits<double>::max());
631   bool isExistingArr=false;
632   tupleIds=0;
633   MCAuto<DataArrayInt> ret1;
634   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
635     {
636       if(*iter)
637         {
638           isExistingArr=true;
639           DataArrayInt *tmp;
640           ret=std::max(ret,(*iter)->getMaxValue2(tmp));
641           MCAuto<DataArrayInt> tmpSafe(tmp);
642           if(!((const DataArrayInt *)ret1))
643             ret1=tmpSafe;
644         }
645     }
646   if(!isExistingArr)
647     throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !");
648   tupleIds=ret1.retn();
649   return ret;
650 }
651
652 /*!
653  * Returns the minimal value within \a this scalar field. Values of all arrays stored
654  * in \a this->_time_discr are checked.
655  *  \return double - the minimal value among all values of \a this field.
656  *  \throw If \a this->getNumberOfComponents() != 1
657  *  \throw If the data array is not set.
658  *  \throw If there is an empty data array in \a this field.
659  */
660 double MEDCouplingFieldDouble::getMinValue() const
661 {
662   std::vector<DataArrayDouble *> arrays;
663   timeDiscr()->getArrays(arrays);
664   double ret(std::numeric_limits<double>::max());
665   bool isExistingArr=false;
666   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
667     {
668       if(*iter)
669         {
670           isExistingArr=true;
671           int loc;
672           ret=std::min(ret,(*iter)->getMinValue(loc));
673         }
674     }
675   if(!isExistingArr)
676     throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !");
677   return ret;
678 }
679
680 /*!
681  * Returns the minimal value and all its locations within \a this scalar field.
682  * Only the first of available data arrays is checked.
683  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
684  *               tuples holding the minimal value. The caller is to delete it using
685  *               decrRef() as it is no more needed.
686  *  \return double - the minimal value among all values of the first array of \a this filed.
687  *  \throw If \a this->getNumberOfComponents() != 1.
688  *  \throw If there is an empty data array in \a this field.
689  */
690 double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const
691 {
692   std::vector<DataArrayDouble *> arrays;
693   timeDiscr()->getArrays(arrays);
694   double ret(-std::numeric_limits<double>::max());
695   bool isExistingArr=false;
696   tupleIds=0;
697   MCAuto<DataArrayInt> ret1;
698   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
699     {
700       if(*iter)
701         {
702           isExistingArr=true;
703           DataArrayInt *tmp;
704           ret=std::max(ret,(*iter)->getMinValue2(tmp));
705           MCAuto<DataArrayInt> tmpSafe(tmp);
706           if(!((const DataArrayInt *)ret1))
707             ret1=tmpSafe;
708         }
709     }
710   if(!isExistingArr)
711     throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !");
712   tupleIds=ret1.retn();
713   return ret;
714 }
715
716 /*!
717  * Returns the average value of \a this scalar field.
718  *  \return double - the average value over all values of the data array.
719  *  \throw If \a this->getNumberOfComponents() != 1
720  *  \throw If the data array is not set or it is empty.
721  */
722 double MEDCouplingFieldDouble::getAverageValue() const
723 {
724   if(getArray()==0)
725     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !");
726   return getArray()->getAverageValue();
727 }
728
729 /*!
730  * This method returns the euclidean norm of \a this field.
731  * \f[
732  * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]}
733  * \f]
734  *  \throw If the data array is not set.
735  */
736 double MEDCouplingFieldDouble::norm2() const
737 {
738   if(getArray()==0)
739     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !");
740   return getArray()->norm2();
741 }
742
743 /*!
744  * This method returns the max norm of \a this field.
745  * \f[
746  * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
747  * \f]
748  *  \throw If the data array is not set.
749  */
750 double MEDCouplingFieldDouble::normMax() const
751 {
752   if(getArray()==0)
753     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
754   return getArray()->normMax();
755 }
756
757 /*!
758  * Computes the weighted average of values of each component of \a this field, the weights being the
759  * values returned by buildMeasureField().  
760  *  \param [out] res - pointer to an array of result sum values, of size at least \a
761  *         this->getNumberOfComponents(), that is to be allocated by the caller.
762  *  \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by
763  *         buildMeasureField(). It makes this method slower. If you are sure that all
764  *         the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs ==
765  *         \c false to speed up the method.
766  *  \throw If the mesh is not set.
767  *  \throw If the data array is not set.
768  */
769 void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const
770 {
771   if(getArray()==0)
772     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
773   MCAuto<MEDCouplingFieldDouble> w=buildMeasureField(isWAbs);
774   double deno=w->getArray()->accumulate(0);
775   MCAuto<DataArrayDouble> arr=getArray()->deepCopy();
776   arr->multiplyEqual(w->getArray());
777   arr->accumulate(res);
778   int nCompo = getArray()->getNumberOfComponents();
779   std::transform(res,res+nCompo,res,std::bind2nd(std::multiplies<double>(),1./deno));
780 }
781
782 /*!
783  * Computes the weighted average of values of a given component of \a this field, the weights being the
784  * values returned by buildMeasureField().
785  *  \param [in] compId - an index of the component of interest.
786  *  \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by
787  *         buildMeasureField(). It makes this method slower. If you are sure that all
788  *         the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs ==
789  *         \c false to speed up the method.
790  *  \throw If the mesh is not set.
791  *  \throw If the data array is not set.
792  *  \throw If \a compId is not valid.
793            A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
794  */
795 double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const
796 {
797   int nbComps=getArray()->getNumberOfComponents();
798   if(compId<0 || compId>=nbComps)
799     {
800       std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
801       throw INTERP_KERNEL::Exception(oss.str());
802     }
803   INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
804   getWeightedAverageValue(res,isWAbs);
805   return res[compId];
806 }
807
808 /*!
809  * Returns the \c normL1 of values of a given component of \a this field:
810  * \f[
811  * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
812  * \f]
813  *  \param [in] compId - an index of the component of interest.
814  *  \throw If the mesh is not set.
815  *  \throw If the spatial discretization of \a this field is NULL.
816  *  \throw If \a compId is not valid.
817            A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
818  */
819 double MEDCouplingFieldDouble::normL1(int compId) const
820 {
821   if(!_mesh)
822     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1 !");
823   if(_type.isNull())
824     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
825   int nbComps=getArray()->getNumberOfComponents();
826   if(compId<0 || compId>=nbComps)
827     {
828       std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
829       throw INTERP_KERNEL::Exception(oss.str());
830     }
831   INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
832   _type->normL1(_mesh,getArray(),res);
833   return res[compId];
834 }
835
836 /*!
837  * Returns the \c normL1 of values of each component of \a this field:
838  * \f[
839  * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
840  * \f]
841  *  \param [out] res - pointer to an array of result values, of size at least \a
842  *         this->getNumberOfComponents(), that is to be allocated by the caller.
843  *  \throw If the mesh is not set.
844  *  \throw If the spatial discretization of \a this field is NULL.
845  */
846 void MEDCouplingFieldDouble::normL1(double *res) const
847 {
848   if(!_mesh)
849     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
850   if(_type.isNull())
851     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
852   _type->normL1(_mesh,getArray(),res);
853 }
854
855 /*!
856  * Returns the \c normL2 of values of a given component of \a this field:
857  * \f[
858  * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
859  * \f]
860  *  \param [in] compId - an index of the component of interest.
861  *  \throw If the mesh is not set.
862  *  \throw If the spatial discretization of \a this field is NULL.
863  *  \throw If \a compId is not valid.
864            A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
865  */
866 double MEDCouplingFieldDouble::normL2(int compId) const
867 {
868   if(!_mesh)
869     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
870   if(_type.isNull())
871     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
872   int nbComps=getArray()->getNumberOfComponents();
873   if(compId<0 || compId>=nbComps)
874     {
875       std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
876       throw INTERP_KERNEL::Exception(oss.str());
877     }
878   INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
879   _type->normL2(_mesh,getArray(),res);
880   return res[compId];
881 }
882
883 /*!
884  * Returns the \c normL2 of values of each component of \a this field:
885  * \f[
886  * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
887  * \f]
888  *  \param [out] res - pointer to an array of result values, of size at least \a
889  *         this->getNumberOfComponents(), that is to be allocated by the caller.
890  *  \throw If the mesh is not set.
891  *  \throw If the spatial discretization of \a this field is NULL.
892  */
893 void MEDCouplingFieldDouble::normL2(double *res) const
894 {
895   if(!_mesh)
896     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
897   if(_type.isNull())
898     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
899   _type->normL2(_mesh,getArray(),res);
900 }
901
902 /*!
903  * Computes a sum of values of a given component of \a this field multiplied by
904  * values returned by buildMeasureField().
905  * This method is useful to check the conservativity of interpolation method.
906  *  \param [in] compId - an index of the component of interest.
907  *  \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by
908  *         buildMeasureField() that makes this method slower. If a user is sure that all
909  *         cells of the underlying mesh have correct orientation, he can put \a isWAbs ==
910  *         \c false that speeds up this method.
911  *  \throw If the mesh is not set.
912  *  \throw If the data array is not set.
913  *  \throw If \a compId is not valid.
914            A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
915  */
916 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const
917 {
918   if(!_mesh)
919     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
920   if(_type.isNull())
921     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral !");
922   int nbComps=getArray()->getNumberOfComponents();
923   if(compId<0 || compId>=nbComps)
924     {
925       std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
926       throw INTERP_KERNEL::Exception(oss.str());
927     }
928   INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
929   _type->integral(_mesh,getArray(),isWAbs,res);
930   return res[compId];
931 }
932
933 /*!
934  * Computes a sum of values of each component of \a this field multiplied by
935  * values returned by buildMeasureField().
936  * This method is useful to check the conservativity of interpolation method.
937  *  \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by
938  *         buildMeasureField() that makes this method slower. If a user is sure that all
939  *         cells of the underlying mesh have correct orientation, he can put \a isWAbs ==
940  *         \c false that speeds up this method.
941  *  \param [out] res - pointer to an array of result sum values, of size at least \a
942  *         this->getNumberOfComponents(), that is to be allocated by the caller.
943  *  \throw If the mesh is not set.
944  *  \throw If the data array is not set.
945  *  \throw If the spatial discretization of \a this field is NULL.
946  */
947 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const
948 {
949   if(!_mesh)
950     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
951   if(_type.isNull())
952     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral2 !");
953   _type->integral(_mesh,getArray(),isWAbs,res);
954 }
955
956 /*!
957  * Returns a value at a given cell of a structured mesh. The cell is specified by its
958  * (i,j,k) index.
959  *  \param [in] i - a index of node coordinates array along X axis. The cell is
960  *         located between the i-th and ( i + 1 )-th nodes along X axis.
961  *  \param [in] j - a index of node coordinates array along Y axis. The cell is
962  *         located between the j-th and ( j + 1 )-th nodes along Y axis.
963  *  \param [in] k - a index of node coordinates array along Z axis. The cell is
964  *         located between the k-th and ( k + 1 )-th nodes along Z axis.
965  *  \param [out] res - pointer to an array returning a feild value, of size at least
966  *         \a this->getNumberOfComponents(), that is to be allocated by the caller.
967  *  \throw If the spatial discretization of \a this field is NULL.
968  *  \throw If the mesh is not set.
969  *  \throw If the mesh is not a structured one.
970  *
971  *  \if ENABLE_EXAMPLES
972  *  \ref cpp_mcfielddouble_getValueOnPos "Here is a C++ example".<br>
973  *  \ref  py_mcfielddouble_getValueOnPos "Here is a Python example".
974  *  \endif
975  */
976 void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const
977 {
978   const DataArrayDouble *arr=timeDiscr()->getArray();
979   if(!_mesh)
980     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
981   if(_type.isNull())
982     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
983   _type->getValueOnPos(arr,_mesh,i,j,k,res);
984 }
985
986 /*!
987  * Returns a value of \a this at a given point using spatial discretization.
988  *  \param [in] spaceLoc - the point of interest.
989  *  \param [out] res - pointer to an array returning a feild value, of size at least
990  *         \a this->getNumberOfComponents(), that is to be allocated by the caller.
991  *  \throw If the spatial discretization of \a this field is NULL.
992  *  \throw If the mesh is not set.
993  *  \throw If \a spaceLoc is out of the spatial discretization.
994  *
995  *  \if ENABLE_EXAMPLES
996  *  \ref cpp_mcfielddouble_getValueOn "Here is a C++ example".<br>
997  *  \ref  py_mcfielddouble_getValueOn "Here is a Python example".
998  *  \endif
999  */
1000 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const
1001 {
1002   const DataArrayDouble *arr=timeDiscr()->getArray();
1003   if(!_mesh)
1004     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
1005   if(_type.isNull())
1006     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
1007   _type->getValueOn(arr,_mesh,spaceLoc,res);
1008 }
1009
1010 /*!
1011  * Returns values of \a this at given points using spatial discretization.
1012  *  \param [in] spaceLoc - coordinates of points of interest in full-interlace
1013  *          mode. This array is to be of size ( \a nbOfPoints * \a this->getNumberOfComponents() ).
1014  *  \param [in] nbOfPoints - number of points of interest.
1015  *  \return DataArrayDouble * - a new instance of DataArrayDouble holding field
1016  *         values relating to the input points. This array is of size \a nbOfPoints
1017  *         tuples per \a this->getNumberOfComponents() components. The caller is to 
1018  *         delete this array using decrRef() as it is no more needed.
1019  *  \throw If the spatial discretization of \a this field is NULL.
1020  *  \throw If the mesh is not set.
1021  *  \throw If any point in \a spaceLoc is out of the spatial discretization.
1022  *
1023  *  \if ENABLE_EXAMPLES
1024  *  \ref cpp_mcfielddouble_getValueOnMulti "Here is a C++ example".<br>
1025  *  \ref  py_mcfielddouble_getValueOnMulti "Here is a Python example".
1026  *  \endif
1027  */
1028 DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const
1029 {
1030   const DataArrayDouble *arr=timeDiscr()->getArray();
1031   if(!_mesh)
1032     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
1033   if(_type.isNull())
1034     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnMulti !");
1035   return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
1036 }
1037
1038 /*!
1039  * Returns a value of \a this field at a given point at a given time using spatial discretization.
1040  * If the time is not covered by \a this->_time_discr, an exception is thrown.
1041  *  \param [in] spaceLoc - the point of interest.
1042  *  \param [in] time - the time of interest.
1043  *  \param [out] res - pointer to an array returning a feild value, of size at least
1044  *         \a this->getNumberOfComponents(), that is to be allocated by the caller.
1045  *  \throw If the spatial discretization of \a this field is NULL.
1046  *  \throw If the mesh is not set.
1047  *  \throw If \a spaceLoc is out of the spatial discretization.
1048  *  \throw If \a time is not covered by \a this->_time_discr.
1049  *
1050  *  \if ENABLE_EXAMPLES
1051  *  \ref cpp_mcfielddouble_getValueOn_time "Here is a C++ example".<br>
1052  *  \ref  py_mcfielddouble_getValueOn_time "Here is a Python example".
1053  *  \endif
1054  */
1055 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const
1056 {
1057   std::vector< const DataArrayDouble *> arrs=timeDiscr()->getArraysForTime(time);
1058   if(!_mesh)
1059     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
1060   if(_type.isNull())
1061     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOn !");
1062   std::vector<double> res2;
1063   for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
1064     {
1065       int sz=(int)res2.size();
1066       res2.resize(sz+(*iter)->getNumberOfComponents());
1067       _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]);
1068     }
1069   timeDiscr()->getValueForTime(time,res2,res);
1070 }
1071
1072 /*!
1073  * Apply a linear function to a given component of \a this field, so that
1074  * a component value <em>(x)</em> becomes \f$ a * x + b \f$.
1075  *  \param [in] a - the first coefficient of the function.
1076  *  \param [in] b - the second coefficient of the function.
1077  *  \param [in] compoId - the index of component to modify.
1078  *  \throw If the data array(s) is(are) not set.
1079  */
1080 void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
1081 {
1082   timeDiscr()->applyLin(a,b,compoId);
1083 }
1084
1085 /*!
1086  * Apply a linear function to all components of \a this field, so that
1087  * values <em>(x)</em> becomes \f$ a * x + b \f$.
1088  *  \param [in] a - the first coefficient of the function.
1089  *  \param [in] b - the second coefficient of the function.
1090  *  \throw If the data array(s) is(are) not set.
1091  */
1092 void MEDCouplingFieldDouble::applyLin(double a, double b)
1093 {
1094   timeDiscr()->applyLin(a,b);
1095 }
1096
1097 /*!
1098  * This method sets \a this to a uniform scalar field with one component.
1099  * All tuples will have the same value 'value'.
1100  * An exception is thrown if no underlying mesh is defined.
1101  */
1102 MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value)
1103 {
1104   if(!_mesh)
1105     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
1106   if(_type.isNull())
1107     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform operator = !");
1108   int nbOfTuple=_type->getNumberOfTuples(_mesh);
1109   timeDiscr()->setOrCreateUniformValueOnAllComponents(nbOfTuple,value);
1110   return *this;
1111 }
1112
1113 /*!
1114  * Creates data array(s) of \a this field by using a C function for value generation.
1115  *  \param [in] nbOfComp - the number of components for \a this field to have.
1116  *  \param [in] func - the function used to compute values of \a this field.
1117  *         This function is to compute a field value basing on coordinates of value
1118  *         location point.
1119  *  \throw If the mesh is not set.
1120  *  \throw If \a func returns \c false.
1121  *  \throw If the spatial discretization of \a this field is NULL.
1122  *
1123  *  \if ENABLE_EXAMPLES
1124  *  \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example".
1125  *  \endif
1126  */
1127 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func)
1128 {
1129   if(!_mesh)
1130     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1131   if(_type.isNull())
1132     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
1133   MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1134   timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
1135 }
1136
1137 /*!
1138  * Creates data array(s) of \a this field by using a function for value generation.<br>
1139  * The function is applied to coordinates of value location points. For example, if
1140  * \a this field is on cells, the function is applied to cell barycenters.
1141  * For more info on supported expressions that can be used in the function, see \ref
1142  * MEDCouplingArrayApplyFuncExpr. <br>
1143  * The function can include arbitrary named variables
1144  * (e.g. "x","y" or "va44") to refer to components of point coordinates. Names of
1145  * variables are sorted in \b alphabetical \b order to associate a variable name with a
1146  * component. For example, in the expression "2*x+z", "x" stands for the component #0
1147  * and "z" stands for the component #1 (\b not #2)!<br>
1148  * In a general case, a value resulting from the function evaluation is assigned to all
1149  * components of a field value. But there is a possibility to have its own expression for
1150  * each component within one function. For this purpose, there are predefined variable
1151  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1152  * the component #0 etc). A factor of such a variable is added to the
1153  * corresponding component only.<br>
1154  * For example, \a nbOfComp == 4, coordinates of a 3D point are (1.,3.,7.), then
1155  *   - "2*x + z"               produces (5.,5.,5.,5.)
1156  *   - "2*x + 0*y + z"         produces (9.,9.,9.,9.)
1157  *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1158  *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1159  *
1160  *  \param [in] nbOfComp - the number of components for \a this field to have.
1161  *  \param [in] func - the function used to compute values of \a this field.
1162  *         This function is used to compute a field value basing on coordinates of value
1163  *         location point. For example, if \a this field is on cells, the function
1164  *         is applied to cell barycenters.
1165  *  \throw If the mesh is not set.
1166  *  \throw If the spatial discretization of \a this field is NULL.
1167  *  \throw If computing \a func fails.
1168  *
1169  *  \if ENABLE_EXAMPLES
1170  *  \ref cpp_mcfielddouble_fillFromAnalytic "Here is a C++ example".<br>
1171  *  \ref  py_mcfielddouble_fillFromAnalytic "Here is a Python example".
1172  *  \endif
1173  */
1174 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func)
1175 {
1176   if(!_mesh)
1177     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1178   if(_type.isNull())
1179     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
1180   MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1181   timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
1182 }
1183
1184 /*!
1185  * Creates data array(s) of \a this field by using a function for value generation.<br>
1186  * The function is applied to coordinates of value location points. For example, if
1187  * \a this field is on cells, the function is applied to cell barycenters.<br>
1188  * This method differs from
1189  * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()"
1190  * by the way how variable
1191  * names, used in the function, are associated with components of coordinates of field
1192  * location points; here, a variable name corresponding to a component is retrieved from
1193  * a corresponding node coordinates array (where it is set via
1194  * DataArrayDouble::setInfoOnComponent()).<br>
1195  * For more info on supported expressions that can be used in the function, see \ref
1196  * MEDCouplingArrayApplyFuncExpr. <br> 
1197  * In a general case, a value resulting from the function evaluation is assigned to all
1198  * components of a field value. But there is a possibility to have its own expression for
1199  * each component within one function. For this purpose, there are predefined variable
1200  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1201  * the component #0 etc). A factor of such a variable is added to the
1202  * corresponding component only.<br>
1203  * For example, \a nbOfComp == 4, names of spatial components are "x", "y" and "z",
1204  * coordinates of a 3D point are (1.,3.,7.), then
1205  *   - "2*x + z"               produces (9.,9.,9.,9.)
1206  *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1207  *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1208  *
1209  *  \param [in] nbOfComp - the number of components for \a this field to have.
1210  *  \param [in] func - the function used to compute values of \a this field.
1211  *         This function is used to compute a field value basing on coordinates of value
1212  *         location point. For example, if \a this field is on cells, the function
1213  *         is applied to cell barycenters.
1214  *  \throw If the mesh is not set.
1215  *  \throw If the spatial discretization of \a this field is NULL.
1216  *  \throw If computing \a func fails.
1217  *
1218  *  \if ENABLE_EXAMPLES
1219  *  \ref cpp_mcfielddouble_fillFromAnalytic2 "Here is a C++ example".<br>
1220  *  \ref  py_mcfielddouble_fillFromAnalytic2 "Here is a Python example".
1221  *  \endif
1222  */
1223 void MEDCouplingFieldDouble::fillFromAnalyticCompo(int nbOfComp, const std::string& func)
1224 {
1225   if(!_mesh)
1226     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
1227   if(_type.isNull())
1228     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticCompo !");
1229   MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1230   timeDiscr()->fillFromAnalyticCompo(loc,nbOfComp,func);
1231 }
1232
1233 /*!
1234  * Creates data array(s) of \a this field by using a function for value generation.<br>
1235  * The function is applied to coordinates of value location points. For example, if
1236  * \a this field is on cells, the function is applied to cell barycenters.<br>
1237  * This method differs from
1238  * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()"
1239  * by the way how variable
1240  * names, used in the function, are associated with components of coordinates of field
1241  * location points; here, a component index of a variable is defined by a
1242  * rank of the variable within the input array \a varsOrder.<br>
1243  * For more info on supported expressions that can be used in the function, see \ref
1244  * MEDCouplingArrayApplyFuncExpr.
1245  * In a general case, a value resulting from the function evaluation is assigned to all
1246  * components of a field value. But there is a possibility to have its own expression for
1247  * each component within one function. For this purpose, there are predefined variable
1248  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1249  * the component #0 etc). A factor of such a variable is added to the
1250  * corresponding component only.<br>
1251  * For example, \a nbOfComp == 4, names of
1252  * spatial components are given in \a varsOrder: ["x", "y","z"], coordinates of a
1253  * 3D point are (1.,3.,7.), then
1254  *   - "2*x + z"               produces (9.,9.,9.,9.)
1255  *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1256  *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1257  *
1258  *  \param [in] nbOfComp - the number of components for \a this field to have.
1259  *  \param [in] func - the function used to compute values of \a this field.
1260  *         This function is used to compute a field value basing on coordinates of value
1261  *         location point. For example, if \a this field is on cells, the function
1262  *         is applied to cell barycenters.
1263  *  \throw If the mesh is not set.
1264  *  \throw If the spatial discretization of \a this field is NULL.
1265  *  \throw If computing \a func fails.
1266  *
1267  *  \if ENABLE_EXAMPLES
1268  *  \ref cpp_mcfielddouble_fillFromAnalytic3 "Here is a C++ example".<br>
1269  *  \ref  py_mcfielddouble_fillFromAnalytic3 "Here is a Python example".
1270  *  \endif
1271  */
1272 void MEDCouplingFieldDouble::fillFromAnalyticNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1273 {
1274   if(!_mesh)
1275     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
1276   if(_type.isNull())
1277     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticNamedCompo !");
1278   MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1279   timeDiscr()->fillFromAnalyticNamedCompo(loc,nbOfComp,varsOrder,func);
1280 }
1281
1282 /*!
1283  * Modifies values of \a this field by applying a C function to each tuple of all
1284  * data arrays.
1285  *  \param [in] nbOfComp - the number of components for \a this field to have.
1286  *  \param [in] func - the function used to compute values of \a this field.
1287  *         This function is to compute a field value basing on a current field value.
1288  *  \throw If \a func returns \c false.
1289  *
1290  *  \if ENABLE_EXAMPLES
1291  *  \ref cpp_mcfielddouble_applyFunc_c_func "Here is a C++ example".
1292  *  \endif
1293  */
1294 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
1295 {
1296   timeDiscr()->applyFunc(nbOfComp,func);
1297 }
1298
1299 /*!
1300  * Fill \a this field with a given value.<br>
1301  * This method is a specialization of other overloaded methods. When \a nbOfComp == 1
1302  * this method is equivalent to MEDCoupling::MEDCouplingFieldDouble::operator=().
1303  *  \param [in] nbOfComp - the number of components for \a this field to have.
1304  *  \param [in] val - the value to assign to every atomic value of \a this field.
1305  *  \throw If the spatial discretization of \a this field is NULL.
1306  *  \throw If the mesh is not set.
1307  *
1308  *  \if ENABLE_EXAMPLES
1309  *  \ref cpp_mcfielddouble_applyFunc_val "Here is a C++ example".<br>
1310  *  \ref  py_mcfielddouble_applyFunc_val "Here is a Python example".
1311  *  \endif
1312  */
1313 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
1314 {
1315   if(!_mesh)
1316     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
1317   if(_type.isNull())
1318     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform applyFunc !");
1319   int nbOfTuple=_type->getNumberOfTuples(_mesh);
1320   timeDiscr()->setUniformValue(nbOfTuple,nbOfComp,val);
1321 }
1322
1323 /*!
1324  * Modifies values of \a this field by applying a function to each tuple of all
1325  * data arrays.
1326  * For more info on supported expressions that can be used in the function, see \ref
1327  * MEDCouplingArrayApplyFuncExpr. <br>
1328  * The function can include arbitrary named variables
1329  * (e.g. "x","y" or "va44") to refer to components of a field value. Names of
1330  * variables are sorted in \b alphabetical \b order to associate a variable name with a
1331  * component. For example, in the expression "2*x+z", "x" stands for the component #0
1332  * and "z" stands for the component #1 (\b not #2)!<br>
1333  * In a general case, a value resulting from the function evaluation is assigned to all
1334  * components of a field value. But there is a possibility to have its own expression for
1335  * each component within one function. For this purpose, there are predefined variable
1336  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1337  * the component #0 etc). A factor of such a variable is added to the
1338  * corresponding component only.<br>
1339  * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then
1340  *   - "2*x + z"               produces (5.,5.,5.,5.)
1341  *   - "2*x + 0*y + z"         produces (9.,9.,9.,9.)
1342  *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1343  *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1344  *
1345  *  \param [in] nbOfComp - the number of components for \a this field to have.
1346  *  \param [in] func - the function used to compute values of \a this field.
1347  *         This function is to compute a field value basing on a current field value.
1348  *  \throw If computing \a func fails.
1349  *
1350  *  \if ENABLE_EXAMPLES
1351  *  \ref cpp_mcfielddouble_applyFunc "Here is a C++ example".<br>
1352  *  \ref  py_mcfielddouble_applyFunc "Here is a Python example".
1353  *  \endif
1354  */
1355 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func)
1356 {
1357   timeDiscr()->applyFunc(nbOfComp,func);
1358 }
1359
1360
1361 /*!
1362  * Modifies values of \a this field by applying a function to each tuple of all
1363  * data arrays.
1364  * For more info on supported expressions that can be used in the function, see \ref
1365  * MEDCouplingArrayApplyFuncExpr. <br>
1366  * This method differs from
1367  * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()"
1368  * by the way how variable
1369  * names, used in the function, are associated with components of field values;
1370  * here, a variable name corresponding to a component is retrieved from
1371  * component information of an array (where it is set via
1372  * DataArrayDouble::setInfoOnComponent()).<br>
1373  * In a general case, a value resulting from the function evaluation is assigned to all
1374  * components of a field value. But there is a possibility to have its own expression for
1375  * each component within one function. For this purpose, there are predefined variable
1376  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1377  * the component #0 etc). A factor of such a variable is added to the
1378  * corresponding component only.<br>
1379  * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then
1380  *   - "2*x + z"               produces (5.,5.,5.,5.)
1381  *   - "2*x + 0*y + z"         produces (9.,9.,9.,9.)
1382  *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1383  *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1384  *
1385  *  \param [in] nbOfComp - the number of components for \a this field to have.
1386  *  \param [in] func - the function used to compute values of \a this field.
1387  *         This function is to compute a new field value basing on a current field value.
1388  *  \throw If computing \a func fails.
1389  *
1390  *  \if ENABLE_EXAMPLES
1391  *  \ref cpp_mcfielddouble_applyFunc2 "Here is a C++ example".<br>
1392  *  \ref  py_mcfielddouble_applyFunc2 "Here is a Python example".
1393  *  \endif
1394  */
1395 void MEDCouplingFieldDouble::applyFuncCompo(int nbOfComp, const std::string& func)
1396 {
1397   timeDiscr()->applyFuncCompo(nbOfComp,func);
1398 }
1399
1400 /*!
1401  * Modifies values of \a this field by applying a function to each tuple of all
1402  * data arrays.
1403  * This method differs from
1404  * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()"
1405  * by the way how variable
1406  * names, used in the function, are associated with components of field values;
1407  * here, a component index of a variable is defined by a
1408  * rank of the variable within the input array \a varsOrder.<br>
1409  * For more info on supported expressions that can be used in the function, see \ref
1410  * MEDCouplingArrayApplyFuncExpr.
1411  * In a general case, a value resulting from the function evaluation is assigned to all
1412  * components of a field value. But there is a possibility to have its own expression for
1413  * each component within one function. For this purpose, there are predefined variable
1414  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1415  * the component #0 etc). A factor of such a variable is added to the
1416  * corresponding component only.<br>
1417  * For example, \a nbOfComp == 4, names of
1418  * components are given in \a varsOrder: ["x", "y","z"], components of a
1419  * 3D vector are (1.,3.,7.), then
1420  *   - "2*x + z"               produces (9.,9.,9.,9.)
1421  *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1422  *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1423  *
1424  *  \param [in] nbOfComp - the number of components for \a this field to have.
1425  *  \param [in] func - the function used to compute values of \a this field.
1426  *         This function is to compute a new field value basing on a current field value.
1427  *  \throw If computing \a func fails.
1428  *
1429  *  \if ENABLE_EXAMPLES
1430  *  \ref cpp_mcfielddouble_applyFunc3 "Here is a C++ example".<br>
1431  *  \ref  py_mcfielddouble_applyFunc3 "Here is a Python example".
1432  *  \endif
1433  */
1434 void MEDCouplingFieldDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1435 {
1436   timeDiscr()->applyFuncNamedCompo(nbOfComp,varsOrder,func);
1437 }
1438
1439 /*!
1440  * Modifies values of \a this field by applying a function to each atomic value of all
1441  * data arrays. The function computes a new single value basing on an old single value.
1442  * For more info on supported expressions that can be used in the function, see \ref
1443  * MEDCouplingArrayApplyFuncExpr. <br>
1444  * The function can include **only one** arbitrary named variable
1445  * (e.g. "x","y" or "va44") to refer to a field atomic value. <br>
1446  * In a general case, a value resulting from the function evaluation is assigned to 
1447  * a single field value. But there is a possibility to have its own expression for
1448  * each component within one function. For this purpose, there are predefined variable
1449  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1450  * the component #0 etc). A factor of such a variable is added to the
1451  * corresponding component only.<br>
1452  * For example, components of a field value are (1.,3.,7.), then
1453  *   - "2*x - 1"               produces (1.,5.,13.)
1454  *   - "2*x*IVec + (x+3)*KVec" produces (2.,0.,10.)
1455  *   - "2*x*IVec + (x+3)*KVec + 1" produces (3.,1.,11.)
1456  *
1457  *  \param [in] func - the function used to compute values of \a this field.
1458  *         This function is to compute a field value basing on a current field value.
1459  *  \throw If computing \a func fails.
1460  *
1461  *  \if ENABLE_EXAMPLES
1462  *  \ref cpp_mcfielddouble_applyFunc_same_nb_comp "Here is a C++ example".<br>
1463  *  \ref  py_mcfielddouble_applyFunc_same_nb_comp "Here is a Python example".
1464  *  \endif
1465  */
1466 void MEDCouplingFieldDouble::applyFunc(const std::string& func)
1467 {
1468   timeDiscr()->applyFunc(func);
1469 }
1470
1471 /*!
1472  * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1473  * The field will contain exactly the same number of components after the call.
1474  * Use is not warranted for the moment !
1475  */
1476 void MEDCouplingFieldDouble::applyFuncFast32(const std::string& func)
1477 {
1478   timeDiscr()->applyFuncFast32(func);
1479 }
1480
1481 /*!
1482  * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1483  * The field will contain exactly the same number of components after the call.
1484  * Use is not warranted for the moment !
1485  */
1486 void MEDCouplingFieldDouble::applyFuncFast64(const std::string& func)
1487 {
1488   timeDiscr()->applyFuncFast64(func);
1489 }
1490
1491 /*!
1492  * Returns number of components in the data array. For more info on the data arrays,
1493  * see \ref arrays.
1494  *  \return int - the number of components in the data array.
1495  *  \throw If the data array is not set.
1496  */
1497 std::size_t MEDCouplingFieldDouble::getNumberOfComponents() const
1498 {
1499   if(getArray()==0)
1500     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
1501   return getArray()->getNumberOfComponents();
1502 }
1503
1504 /*!
1505  * Use MEDCouplingField::getNumberOfTuplesExpected instead of this method. This method will be removed soon, because it is
1506  * confusing compared to getNumberOfComponents() and getNumberOfValues() behaviour.
1507  *
1508  * Returns number of tuples in \a this field, that depends on 
1509  * - the number of entities in the underlying mesh
1510  * - \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field (e.g. number
1511  * of Gauss points if \a this->getTypeOfField() == 
1512  * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT").
1513  *
1514  * The returned value does \b not \b depend on the number of tuples in the data array
1515  * (which has to be equal to the returned value), \b contrary to
1516  * getNumberOfComponents() and getNumberOfValues() that retrieve information from the
1517  * data array (Sorry, it is confusing !).
1518  * So \b this \b method \b behaves \b exactly \b as MEDCouplingField::getNumberOfTuplesExpected \b method.
1519  *
1520  * \warning No checkConsistencyLight() is done here.
1521  * For more info on the data arrays, see \ref arrays.
1522  *  \return int - the number of tuples.
1523  *  \throw If the mesh is not set.
1524  *  \throw If the spatial discretization of \a this field is NULL.
1525  *  \throw If the spatial discretization is not fully defined.
1526  *  \sa MEDCouplingField::getNumberOfTuplesExpected
1527  */
1528 std::size_t MEDCouplingFieldDouble::getNumberOfTuples() const
1529 {
1530   if(!_mesh)
1531     throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
1532   if(_type.isNull())
1533     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getNumberOfTuples !");
1534   return _type->getNumberOfTuples(_mesh);
1535 }
1536
1537 /*!
1538  * Returns number of atomic double values in the data array of \a this field.
1539  * For more info on the data arrays, see \ref arrays.
1540  *  \return int - (number of tuples) * (number of components) of the
1541  *  data array.
1542  *  \throw If the data array is not set.
1543  */
1544 std::size_t MEDCouplingFieldDouble::getNumberOfValues() const
1545 {
1546   if(getArray()==0)
1547     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
1548   return getArray()->getNbOfElems();
1549 }
1550
1551 /*!
1552  * Sets own modification time by the most recently modified element of data (the mesh,
1553  * the data array etc). For more info, see \ref MEDCouplingTimeLabelPage.
1554  */
1555 void MEDCouplingFieldDouble::updateTime() const
1556 {
1557   MEDCouplingField::updateTime();
1558   updateTimeWith(*timeDiscr());
1559 }
1560
1561 std::size_t MEDCouplingFieldDouble::getHeapMemorySizeWithoutChildren() const
1562 {
1563   return MEDCouplingField::getHeapMemorySizeWithoutChildren();
1564 }
1565
1566 std::vector<const BigMemoryObject *> MEDCouplingFieldDouble::getDirectChildrenWithNull() const
1567 {
1568   std::vector<const BigMemoryObject *> ret(MEDCouplingField::getDirectChildrenWithNull());
1569   if(timeDiscr())
1570     {
1571       std::vector<const BigMemoryObject *> ret2(timeDiscr()->getDirectChildrenWithNull());
1572       ret.insert(ret.end(),ret2.begin(),ret2.end());
1573     }
1574   return ret;
1575 }
1576
1577 /*!
1578  * Returns a value of \a this field of type either
1579  * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or
1580  * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE".
1581  *  \param [in] cellId - an id of cell of interest.
1582  *  \param [in] nodeIdInCell - a node index within the cell.
1583  *  \param [in] compoId - an index of component.
1584  *  \return double - the field value corresponding to the specified parameters.
1585  *  \throw If the data array is not set.
1586  *  \throw If the mesh is not set.
1587  *  \throw If the spatial discretization of \a this field is NULL.
1588  *  \throw If \a this field if of type other than 
1589  *         \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or
1590  *         \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE".
1591  */
1592 double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
1593 {
1594   if(_type.isNull())
1595     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getIJK !");
1596   return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
1597 }
1598
1599 /*!
1600  * Sets the data array. 
1601  *  \param [in] array - the data array holding values of \a this field. It's size
1602  *         should correspond to the mesh and
1603  *         \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1604  *         (see getNumberOfTuples()), but this size is not checked here.
1605  */
1606 //void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
1607
1608 /*!
1609  * Sets the data array holding values corresponding to an end of a time interval
1610  * for which \a this field is defined.
1611  *  \param [in] array - the data array holding values of \a this field. It's size
1612  *         should correspond to the mesh and
1613  *         \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1614  *         (see getNumberOfTuples()), but this size is not checked here.
1615  */
1616 //void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
1617
1618 /*!
1619  * Sets all data arrays needed to define the field values.
1620  *  \param [in] arrs - a vector of DataArrayDouble's holding values of \a this
1621  *         field. Size of each array should correspond to the mesh and
1622  *         \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1623  *         (see getNumberOfTuples()), but this size is not checked here.
1624  *  \throw If number of arrays in \a arrs does not correspond to type of
1625  *         \ref MEDCouplingTemporalDisc "temporal discretization" of \a this field.
1626  */
1627 //void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs)
1628
1629 /*!
1630  * Tries to set an \a other mesh as the support of \a this field. An attempt fails, if
1631  * a current and the \a other meshes are different with use of specified equality
1632  * criteria, and then an exception is thrown.
1633  *  \param [in] other - the mesh to use as the field support if this mesh can be
1634  *         considered equal to the current mesh.
1635  *  \param [in] levOfCheck - defines equality criteria used for mesh comparison. For
1636  *         it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which
1637  *         is used for mesh comparison.
1638  *  \param [in] precOnMesh - a precision used to compare nodes of the two meshes.
1639  *         It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith().
1640  *  \param [in] eps - a precision used at node renumbering (if needed) to compare field
1641  *         values at merged nodes. If the values differ more than \a eps, an
1642  *         exception is thrown.
1643  *  \throw If the mesh is not set.
1644  *  \throw If \a other == NULL.
1645  *  \throw If any of the meshes is not well defined.
1646  *  \throw If the two meshes do not match.
1647  *  \throw If field values at merged nodes (if any) deffer more than \a eps.
1648  *
1649  *  \if ENABLE_EXAMPLES
1650  *  \ref cpp_mcfielddouble_changeUnderlyingMesh "Here is a C++ example".<br>
1651  *  \ref  py_mcfielddouble_changeUnderlyingMesh "Here is a Python example".
1652  *  \endif
1653  */
1654 void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps)
1655 {
1656   if(_mesh==0 || other==0)
1657     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
1658   DataArrayInt *cellCor=0,*nodeCor=0;
1659   other->checkGeoEquivalWith(_mesh,levOfCheck,precOnMesh,cellCor,nodeCor);
1660   MCAuto<DataArrayInt> cellCor2(cellCor),nodeCor2(nodeCor);
1661   if(cellCor)
1662     renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
1663   if(nodeCor)
1664     renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps);
1665   setMesh(other);
1666 }
1667
1668 /*!
1669  * Subtracts another field from \a this one in case when the two fields have different
1670  * supporting meshes. The subtraction is performed provided that the tho meshes can be
1671  * considered equal with use of specified equality criteria, else an exception is thrown.
1672  * If the meshes match, the mesh of \a f is set to \a this field (\a this is permuted if 
1673  * necessary) and field values are subtracted. No interpolation is done here, only an
1674  * analysis of two underlying mesh is done to see if the meshes are geometrically
1675  * equivalent.<br>
1676  * The job of this method consists in calling
1677  * \a this->changeUnderlyingMesh() with \a f->getMesh() as the first parameter, and then
1678  * \a this -= \a f.<br>
1679  * This method requires that \a f and \a this are coherent (checkConsistencyLight()) and that \a f
1680  * and \a this are coherent for a merge.<br>
1681  * "DM" in the method name stands for "different meshes".
1682  *  \param [in] f - the field to subtract from this.
1683  *  \param [in] levOfCheck - defines equality criteria used for mesh comparison. For
1684  *         it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which
1685  *         is used for mesh comparison.
1686  *  \param [in] precOnMesh - a precision used to compare nodes of the two meshes.
1687  *         It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith().
1688  *  \param [in] eps - a precision used at node renumbering (if needed) to compare field
1689  *         values at merged nodes. If the values differ more than \a eps, an
1690  *         exception is thrown.
1691  *  \throw If \a f == NULL.
1692  *  \throw If any of the meshes is not set or is not well defined.
1693  *  \throw If the two meshes do not match.
1694  *  \throw If the two fields are not coherent for merge.
1695  *  \throw If field values at merged nodes (if any) deffer more than \a eps.
1696  *
1697  *  \if ENABLE_EXAMPLES
1698  *  \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".<br>
1699  *  \ref  py_mcfielddouble_substractInPlaceDM "Here is a Python example".
1700  *  \endif
1701  *  \sa changeUnderlyingMesh().
1702  */
1703 void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps)
1704 {
1705   checkConsistencyLight();
1706   if(!f)
1707     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : input field is NULL !");
1708   f->checkConsistencyLight();
1709   if(!areCompatibleForMerge(f))
1710     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : Fields are not compatible ; unable to apply mergeFields on them !");
1711   changeUnderlyingMesh(f->getMesh(),levOfCheck,precOnMesh,eps);
1712   operator-=(*f);
1713 }
1714
1715 /*!
1716  * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the
1717  * underlying mesh is replaced by a new mesh instance where the coincident nodes are merged.
1718  *  \param [in] eps - a precision used to compare nodes of the two meshes.
1719  *  \param [in] epsOnVals - a precision used to compare field
1720  *         values at merged nodes. If the values differ more than \a epsOnVals, an
1721  *         exception is thrown.
1722  *  \return bool - \c true if some nodes have been merged and hence \a this field lies
1723  *         on another mesh.
1724  *  \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1725  *  \throw If the mesh is not well defined.
1726  *  \throw If the spatial discretization of \a this field is NULL.
1727  *  \throw If the data array is not set.
1728  *  \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
1729  */
1730 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals)
1731 {
1732   const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1733   if(!meshC)
1734     throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1735   if(_type.isNull())
1736     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes !");
1737   MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1738   bool ret;
1739   int ret2;
1740   MCAuto<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2);
1741   if(!ret)//no nodes have been merged.
1742     return ret;
1743   std::vector<DataArrayDouble *> arrays;
1744   timeDiscr()->getArrays(arrays);
1745   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1746     if(*iter)
1747       _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1748   setMesh(meshC2);
1749   return true;
1750 }
1751
1752 /*!
1753  * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the
1754  * underlying mesh is replaced by a new mesh instance where the coincident nodes are
1755  * merged.<br>
1756  * In contrast to mergeNodes(), location of merged nodes is changed to be at their barycenter.
1757  *  \param [in] eps - a precision used to compare nodes of the two meshes.
1758  *  \param [in] epsOnVals - a precision used to compare field
1759  *         values at merged nodes. If the values differ more than \a epsOnVals, an
1760  *         exception is thrown.
1761  *  \return bool - \c true if some nodes have been merged and hence \a this field lies
1762  *         on another mesh.
1763  *  \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1764  *  \throw If the mesh is not well defined.
1765  *  \throw If the spatial discretization of \a this field is NULL.
1766  *  \throw If the data array is not set.
1767  *  \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
1768  */
1769 bool MEDCouplingFieldDouble::mergeNodesCenter(double eps, double epsOnVals)
1770 {
1771   const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1772   if(!meshC)
1773     throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1774   if(_type.isNull())
1775     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodesCenter !");
1776   MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1777   bool ret;
1778   int ret2;
1779   MCAuto<DataArrayInt> arr=meshC2->mergeNodesCenter(eps,ret,ret2);
1780   if(!ret)//no nodes have been merged.
1781     return ret;
1782   std::vector<DataArrayDouble *> arrays;
1783   timeDiscr()->getArrays(arrays);
1784   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1785     if(*iter)
1786       _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1787   setMesh(meshC2);
1788   return true;
1789 }
1790
1791 /*!
1792  * Removes from the underlying mesh nodes not used in any cell. If some nodes are
1793  * removed, the underlying mesh is replaced by a new mesh instance where the unused
1794  * nodes are removed.<br>
1795  *  \param [in] epsOnVals - a precision used to compare field
1796  *         values at merged nodes. If the values differ more than \a epsOnVals, an
1797  *         exception is thrown.
1798  *  \return bool - \c true if some nodes have been removed and hence \a this field lies
1799  *         on another mesh.
1800  *  \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1801  *  \throw If the mesh is not well defined.
1802  *  \throw If the spatial discretization of \a this field is NULL.
1803  *  \throw If the data array is not set.
1804  *  \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
1805  */
1806 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals)
1807 {
1808   const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1809   if(!meshC)
1810     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1811   if(_type.isNull())
1812     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipCoords !");
1813   MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1814   int oldNbOfNodes=meshC2->getNumberOfNodes();
1815   MCAuto<DataArrayInt> arr=meshC2->zipCoordsTraducer();
1816   if(meshC2->getNumberOfNodes()!=oldNbOfNodes)
1817     {
1818       std::vector<DataArrayDouble *> arrays;
1819       timeDiscr()->getArrays(arrays);
1820       for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1821         if(*iter)
1822           _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1823       setMesh(meshC2);
1824       return true;
1825     }
1826   return false;
1827 }
1828
1829 /*!
1830  * Removes duplicates of cells from the understanding mesh. If some cells are
1831  * removed, the underlying mesh is replaced by a new mesh instance where the cells
1832  * duplicates are removed.<br>
1833  *  \param [in] compType - specifies a cell comparison technique. Meaning of its
1834  *          valid values [0,1,2] is explained in the description of
1835  *          MEDCouplingPointSet::zipConnectivityTraducer() which is called by this method.
1836  *  \param [in] epsOnVals - a precision used to compare field
1837  *         values at merged cells. If the values differ more than \a epsOnVals, an
1838  *         exception is thrown.
1839  *  \return bool - \c true if some cells have been removed and hence \a this field lies
1840  *         on another mesh.
1841  *  \throw If the mesh is not an instance of MEDCouplingUMesh.
1842  *  \throw If the mesh is not well defined.
1843  *  \throw If the spatial discretization of \a this field is NULL.
1844  *  \throw If the data array is not set.
1845  *  \throw If field values at merged cells (if any) deffer more than \a epsOnVals.
1846  */
1847 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals)
1848 {
1849   const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
1850   if(!meshC)
1851     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipConnectivity : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1852   if(_type.isNull())
1853     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipConnectivity !");
1854   MCAuto<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCopy());
1855   int oldNbOfCells=meshC2->getNumberOfCells();
1856   MCAuto<DataArrayInt> arr=meshC2->zipConnectivityTraducer(compType);
1857   if(meshC2->getNumberOfCells()!=oldNbOfCells)
1858     {
1859       std::vector<DataArrayDouble *> arrays;
1860       timeDiscr()->getArrays(arrays);
1861       for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1862         if(*iter)
1863           _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter);
1864       setMesh(meshC2);
1865       return true;
1866     }
1867   return false;
1868 }
1869
1870 /*!
1871  * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists.
1872  * For the moment, this method is implemented for fields on cells.
1873  * 
1874  * \return a newly allocated field double containing the result that the user should deallocate.
1875  */
1876 MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const
1877 {
1878   const MEDCouplingMesh *mesh=getMesh();
1879   if(!mesh)
1880     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !");
1881   if(getTypeOfField()!=ON_CELLS)
1882     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !");
1883   const MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1884   MCAuto<MEDCouplingFieldDouble> ret(clone(false));
1885   ret->setMesh(umesh);
1886   DataArrayInt *cellIds=0;
1887   MCAuto<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds);
1888   MCAuto<DataArrayInt> cellIds2=cellIds;
1889   ret->setMesh(mesh2);
1890   MCAuto<DataArrayInt> tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end());
1891   std::vector<DataArrayDouble *> arrays;
1892   timeDiscr()->getArrays(arrays);
1893   int i=0;
1894   std::vector<DataArrayDouble *> newArr(arrays.size());
1895   std::vector< MCAuto<DataArrayDouble> > newArr2(arrays.size());
1896   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++)
1897     {
1898       if(*iter)
1899         {
1900           newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
1901           newArr[i]=newArr2[i];
1902         }
1903     }
1904   ret->setArrays(newArr);
1905   return ret.retn();
1906 }
1907
1908 /*!
1909  * Divides every cell of the underlying mesh into simplices (triangles in 2D and
1910  * tetrahedra in 3D). If some cells are divided, the underlying mesh is replaced by a new
1911  * mesh instance containing the simplices.<br> 
1912  *  \param [in] policy - specifies a pattern used for splitting. For its description, see
1913  *          MEDCouplingUMesh::simplexize().
1914  *  \return bool - \c true if some cells have been divided and hence \a this field lies
1915  *         on another mesh.
1916  *  \throw If \a policy has an invalid value. For valid values, see the description of 
1917  *         MEDCouplingUMesh::simplexize().
1918  *  \throw If MEDCouplingMesh::simplexize() is not applicable to the underlying mesh.
1919  *  \throw If the mesh is not well defined.
1920  *  \throw If the spatial discretization of \a this field is NULL.
1921  *  \throw If the data array is not set.
1922  */
1923 bool MEDCouplingFieldDouble::simplexize(int policy)
1924 {
1925   if(!_mesh)
1926     throw INTERP_KERNEL::Exception("No underlying mesh on this field to perform simplexize !");
1927   if(_type.isNull())
1928     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform simplexize !");
1929   int oldNbOfCells=_mesh->getNumberOfCells();
1930   MCAuto<MEDCouplingMesh> meshC2(_mesh->deepCopy());
1931   MCAuto<DataArrayInt> arr=meshC2->simplexize(policy);
1932   int newNbOfCells=meshC2->getNumberOfCells();
1933   if(oldNbOfCells==newNbOfCells)
1934     return false;
1935   std::vector<DataArrayDouble *> arrays;
1936   timeDiscr()->getArrays(arrays);
1937   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1938     if(*iter)
1939       _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter);
1940   setMesh(meshC2);
1941   return true;
1942 }
1943
1944 /*!
1945  * This method makes the hypothesis that \a this is a Gauss field. This method returns a newly created field on cells with same number of tuples than \a this.
1946  * Each Gauss points in \a this is replaced by a polygon or polyhedron cell with associated region following Voronoi algorithm.
1947  */
1948 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoize(double eps) const
1949 {
1950   checkConsistencyLight();
1951   const MEDCouplingMesh *mesh(getMesh());
1952   INTERP_KERNEL::AutoCppPtr<Voronizer> vor;
1953   int meshDim(mesh->getMeshDimension()),spaceDim(mesh->getSpaceDimension());
1954   if(meshDim==1 && (spaceDim==1 || spaceDim==2 || spaceDim==3))
1955     vor=new Voronizer1D;
1956   else if(meshDim==2 && (spaceDim==2 || spaceDim==3))
1957     vor=new Voronizer2D;
1958   else if(meshDim==3 && spaceDim==3)
1959     vor=new Voronizer3D;
1960   else
1961     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize : only 2D, 3D surf, and 3D are supported for the moment !");
1962   return voronoizeGen(vor,eps);
1963 }
1964
1965 /*!
1966  * \sa MEDCouplingUMesh::convertQuadraticCellsToLinear
1967  */
1968 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::convertQuadraticCellsToLinear() const
1969 {
1970   checkConsistencyLight();
1971   switch(getTypeOfField())
1972     {
1973     case ON_NODES:
1974       {
1975         const MEDCouplingMesh *mesh(getMesh());
1976         if(!mesh)
1977           throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
1978         MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1979         umesh=umesh->clone(false);
1980         umesh->convertQuadraticCellsToLinear();
1981         MCAuto<DataArrayInt> o2n(umesh->zipCoordsTraducer());
1982         MCAuto<DataArrayInt> n2o(o2n->invertArrayO2N2N2O(umesh->getNumberOfNodes()));
1983         MCAuto<DataArrayDouble> arr(getArray()->selectByTupleIdSafe(n2o->begin(),n2o->end()));
1984         MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_NODES));
1985         ret->setArray(arr);
1986         ret->setMesh(umesh);
1987         ret->copyAllTinyAttrFrom(this);
1988         return ret;
1989       }
1990     case ON_CELLS:
1991       {
1992         const MEDCouplingMesh *mesh(getMesh());
1993         if(!mesh)
1994           throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
1995         MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1996         umesh=umesh->clone(false);
1997         umesh->convertQuadraticCellsToLinear();
1998         umesh->zipCoords();
1999         MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
2000         ret->setArray(const_cast<DataArrayDouble *>(getArray()));
2001         ret->setMesh(umesh);
2002         ret->copyAllTinyAttrFrom(this);
2003         return ret;
2004       }
2005     case ON_GAUSS_PT:
2006       {
2007         const MEDCouplingMesh *mesh(getMesh());
2008         if(!mesh)
2009           throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
2010         MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
2011         std::set<INTERP_KERNEL::NormalizedCellType> gt(umesh->getAllGeoTypes());
2012         MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_GAUSS_PT));
2013         //
2014         const MEDCouplingFieldDiscretization *disc(getDiscretization());
2015         const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
2016         if(!disc2)
2017           throw INTERP_KERNEL::Exception("convertQuadraticCellsToLinear : Not a ON_GAUSS_PT field");
2018         std::set<INTERP_KERNEL::NormalizedCellType> gt2(umesh->getAllGeoTypes());
2019         std::vector< MCAuto<DataArrayInt> > cellIdsV;
2020         std::vector< MCAuto<MEDCouplingUMesh> > meshesV;
2021         std::vector< MEDCouplingGaussLocalization > glV;
2022         bool isZipReq(false);
2023         for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=gt.begin();it!=gt.end();it++)
2024           {
2025             const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it));
2026             MCAuto<DataArrayInt> cellIds(umesh->giveCellsWithType(*it));
2027             cellIdsV.push_back(cellIds);
2028             MCAuto<MEDCouplingUMesh> part(umesh->buildPartOfMySelf(cellIds->begin(),cellIds->end()));
2029             int id(disc2->getGaussLocalizationIdOfOneType(*it));
2030             const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(id));
2031             if(!cm.isQuadratic())
2032               {
2033                 glV.push_back(gl);
2034               }
2035             else
2036               {
2037                 isZipReq=true;
2038                 part->convertQuadraticCellsToLinear();
2039                 INTERP_KERNEL::GaussInfo gi(*it,gl.getGaussCoords(),gl.getNumberOfGaussPt(),gl.getRefCoords(),gl.getNumberOfPtsInRefCell());
2040                 INTERP_KERNEL::GaussInfo gi2(gi.convertToLinear());
2041                 MEDCouplingGaussLocalization gl2(gi2.getGeoType(),gi2.getRefCoords(),gi2.getGaussCoords(),gl.getWeights());
2042                 glV.push_back(gl2);
2043               }
2044             meshesV.push_back(part);
2045           }
2046         //
2047         {
2048           std::vector< const MEDCouplingUMesh * > meshesPtr(VecAutoToVecOfCstPt(meshesV));
2049           umesh=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshesPtr);
2050           std::vector< const DataArrayInt * > zeCellIds(VecAutoToVecOfCstPt(cellIdsV));
2051           MCAuto<DataArrayInt> zeIds(DataArrayInt::Aggregate(zeCellIds));
2052           umesh->renumberCells(zeIds->begin());
2053           umesh->setName(mesh->getName());
2054         }
2055         //
2056         if(isZipReq)
2057           umesh->zipCoords();
2058         ret->setArray(const_cast<DataArrayDouble *>(getArray()));
2059         ret->setMesh(umesh);
2060         for(std::vector< MEDCouplingGaussLocalization >::const_iterator it=glV.begin();it!=glV.end();it++)
2061           ret->setGaussLocalizationOnType((*it).getType(),(*it).getRefCoords(),(*it).getGaussCoords(),(*it).getWeights());
2062         ret->copyAllTinyAttrFrom(this);
2063         ret->checkConsistencyLight();
2064         return ret;
2065       }
2066     default:
2067       throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : Only available for fields on nodes and on cells !");
2068     }
2069 }
2070
2071 /*!
2072  * This is expected to be a 3 components vector field on nodes (if not an exception will be thrown). \a this is also expected to lie on a MEDCouplingPointSet mesh.
2073  * Finaly \a this is also expected to be consistent.
2074  * In these conditions this method returns a newly created field (to be dealed by the caller).
2075  * The returned field will also 3 compo vector field be on nodes lying on the same mesh than \a this.
2076  * 
2077  * For each 3 compo tuple \a tup in \a this the returned tuple is the result of the transformation of \a tup in the new referential. This referential is defined by \a Ur, \a Uteta, \a Uz.
2078  * \a Ur is the vector between \a center point and the associated node with \a tuple. \a Uz is \a vect normalized. And Uteta is the cross product of \a Uz with \a Ur.
2079  *
2080  * \sa DataArrayDouble::fromCartToCylGiven
2081  */
2082 MEDCouplingFieldDouble *MEDCouplingFieldDouble::computeVectorFieldCyl(const double center[3], const double vect[3]) const
2083 {
2084   checkConsistencyLight();
2085   const DataArrayDouble *coo(getMesh()->getDirectAccessOfCoordsArrIfInStructure());
2086   MEDCouplingTimeDiscretization *td(timeDiscr()->computeVectorFieldCyl(coo,center,vect));
2087   td->copyTinyAttrFrom(*timeDiscr());
2088   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2089   ret->setMesh(getMesh());
2090   ret->setName(getName());
2091   return ret.retn();
2092 }
2093
2094 /*!
2095  * Creates a new MEDCouplingFieldDouble filled with the doubly contracted product of
2096  * every tensor of \a this 6-componental field.
2097  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2098  *          each tuple is calculated from the tuple <em>(t)</em> of \a this field as
2099  *          follows: \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$. 
2100  *          This new field lies on the same mesh as \a this one. The caller is to delete
2101  *          this field using decrRef() as it is no more needed.
2102  *  \throw If \a this->getNumberOfComponents() != 6.
2103  *  \throw If the spatial discretization of \a this field is NULL.
2104  */
2105 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const
2106 {
2107   if(_type.isNull())
2108     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform doublyContractedProduct !");
2109   MEDCouplingTimeDiscretization *td(timeDiscr()->doublyContractedProduct());
2110   td->copyTinyAttrFrom(*timeDiscr());
2111   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2112   ret->setName("DoublyContractedProduct");
2113   ret->setMesh(getMesh());
2114   return ret.retn();
2115 }
2116
2117 /*!
2118  * Creates a new MEDCouplingFieldDouble filled with the determinant of a square
2119  * matrix defined by every tuple of \a this field, having either 4, 6 or 9 components.
2120  * The case of 6 components corresponds to that of the upper triangular matrix. 
2121  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2122  *          each tuple is the determinant of matrix of the corresponding tuple of \a this 
2123  *          field. This new field lies on the same mesh as \a this one. The caller is to 
2124  *          delete this field using decrRef() as it is no more needed.
2125  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2126  *  \throw If the spatial discretization of \a this field is NULL.
2127  */
2128 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const
2129 {
2130   if(_type.isNull())
2131     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform determinant !");
2132   MEDCouplingTimeDiscretization *td(timeDiscr()->determinant());
2133   td->copyTinyAttrFrom(*timeDiscr());
2134   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2135   ret->setName("Determinant");
2136   ret->setMesh(getMesh());
2137   return ret.retn();
2138 }
2139
2140
2141 /*!
2142  * Creates a new MEDCouplingFieldDouble with 3 components filled with 3 eigenvalues of
2143  * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2144  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2145  *          having 3 components, whose each tuple contains the eigenvalues of the matrix of
2146  *          corresponding tuple of \a this field. This new field lies on the same mesh as
2147  *          \a this one. The caller is to delete this field using decrRef() as it is no
2148  *          more needed.  
2149  *  \throw If \a this->getNumberOfComponents() != 6.
2150  *  \throw If the spatial discretization of \a this field is NULL.
2151  */
2152 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const
2153 {
2154   if(_type.isNull())
2155     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenValues !");
2156   MEDCouplingTimeDiscretization *td(timeDiscr()->eigenValues());
2157   td->copyTinyAttrFrom(*timeDiscr());
2158   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2159   ret->setName("EigenValues");
2160   ret->setMesh(getMesh());
2161   return ret.retn();
2162 }
2163
2164 /*!
2165  * Creates a new MEDCouplingFieldDouble with 9 components filled with 3 eigenvectors of
2166  * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2167  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2168  *          having 9 components, whose each tuple contains the eigenvectors of the matrix of
2169  *          corresponding tuple of \a this field. This new field lies on the same mesh as
2170  *          \a this one. The caller is to delete this field using decrRef() as it is no
2171  *          more needed.  
2172  *  \throw If \a this->getNumberOfComponents() != 6.
2173  *  \throw If the spatial discretization of \a this field is NULL.
2174  */
2175 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const
2176 {
2177   if(_type.isNull())
2178     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenVectors !");
2179   MEDCouplingTimeDiscretization *td(timeDiscr()->eigenVectors());
2180   td->copyTinyAttrFrom(*timeDiscr());
2181   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2182   ret->setName("EigenVectors");
2183   ret->setMesh(getMesh());
2184   return ret.retn();
2185 }
2186
2187 /*!
2188  * Creates a new MEDCouplingFieldDouble filled with the inverse matrix of
2189  * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2190  * components. The case of 6 components corresponds to that of the upper triangular
2191  * matrix.
2192  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2193  *          having the same number of components as \a this one, whose each tuple
2194  *          contains the inverse matrix of the matrix of corresponding tuple of \a this
2195  *          field. This new field lies on the same mesh as \a this one. The caller is to
2196  *          delete this field using decrRef() as it is no more needed.  
2197  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2198  *  \throw If the spatial discretization of \a this field is NULL.
2199  */
2200 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const
2201 {
2202   if(_type.isNull())
2203     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform inverse !");
2204   MEDCouplingTimeDiscretization *td(timeDiscr()->inverse());
2205   td->copyTinyAttrFrom(*timeDiscr());
2206   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2207   ret->setName("Inversion");
2208   ret->setMesh(getMesh());
2209   return ret.retn();
2210 }
2211
2212 /*!
2213  * Creates a new MEDCouplingFieldDouble filled with the trace of
2214  * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2215  * components. The case of 6 components corresponds to that of the upper triangular
2216  * matrix.
2217  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2218  *          having 1 component, whose each tuple is the trace of the matrix of
2219  *          corresponding tuple of \a this field.
2220  *          This new field lies on the same mesh as \a this one. The caller is to
2221  *          delete this field using decrRef() as it is no more needed.  
2222  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2223  *  \throw If the spatial discretization of \a this field is NULL.
2224  */
2225 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const
2226 {
2227   if(_type.isNull())
2228     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform trace !");
2229   MEDCouplingTimeDiscretization *td(timeDiscr()->trace());
2230   td->copyTinyAttrFrom(*timeDiscr());
2231   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2232   ret->setName("Trace");
2233   ret->setMesh(getMesh());
2234   return ret.retn();
2235 }
2236
2237 /*!
2238  * Creates a new MEDCouplingFieldDouble filled with the stress deviator tensor of
2239  * a stress tensor defined by every tuple of \a this 6-componental field.
2240  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2241  *          having same number of components and tuples as \a this field,
2242  *          whose each tuple contains the stress deviator tensor of the stress tensor of
2243  *          corresponding tuple of \a this field. This new field lies on the same mesh as
2244  *          \a this one. The caller is to delete this field using decrRef() as it is no
2245  *          more needed.  
2246  *  \throw If \a this->getNumberOfComponents() != 6.
2247  *  \throw If the spatial discretization of \a this field is NULL.
2248  */
2249 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const
2250 {
2251   if(_type.isNull())
2252     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform deviator !");
2253   MEDCouplingTimeDiscretization *td(timeDiscr()->deviator());
2254   td->copyTinyAttrFrom(*timeDiscr());
2255   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2256   ret->setName("Deviator");
2257   ret->setMesh(getMesh());
2258   return ret.retn();
2259 }
2260
2261 /*!
2262  * Creates a new MEDCouplingFieldDouble filled with the magnitude of
2263  * every vector of \a this field.
2264  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2265  *          having one component, whose each tuple is the magnitude of the vector
2266  *          of corresponding tuple of \a this field. This new field lies on the
2267  *          same mesh as \a this one. The caller is to
2268  *          delete this field using decrRef() as it is no more needed.  
2269  *  \throw If the spatial discretization of \a this field is NULL.
2270  */
2271 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const
2272 {
2273   if(_type.isNull())
2274     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform magnitude !");
2275   MEDCouplingTimeDiscretization *td(timeDiscr()->magnitude());
2276   td->copyTinyAttrFrom(*timeDiscr());
2277   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2278   ret->setName("Magnitude");
2279   ret->setMesh(getMesh());
2280   return ret.retn();
2281 }
2282
2283 /*!
2284  * Creates a new scalar MEDCouplingFieldDouble filled with the maximal value among
2285  * values of every tuple of \a this field.
2286  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2287  *          This new field lies on the same mesh as \a this one. The caller is to
2288  *          delete this field using decrRef() as it is no more needed.  
2289  *  \throw If the spatial discretization of \a this field is NULL.
2290  */
2291 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const
2292 {
2293   if(_type.isNull())
2294     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform maxPerTuple !");
2295   MEDCouplingTimeDiscretization *td(timeDiscr()->maxPerTuple());
2296   td->copyTinyAttrFrom(*timeDiscr());
2297   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2298   std::ostringstream oss;
2299   oss << "Max_" << getName();
2300   ret->setName(oss.str());
2301   ret->setMesh(getMesh());
2302   return ret.retn();
2303 }
2304
2305 /*!
2306  * Changes number of components in \a this field. If \a newNbOfComp is less
2307  * than \a this->getNumberOfComponents() then each tuple
2308  * is truncated to have \a newNbOfComp components, keeping first components. If \a
2309  * newNbOfComp is more than \a this->getNumberOfComponents() then 
2310  * each tuple is populated with \a dftValue to have \a newNbOfComp components.  
2311  *  \param [in] newNbOfComp - number of components for the new field to have.
2312  *  \param [in] dftValue - value assigned to new values added to \a this field.
2313  *  \throw If \a this is not allocated.
2314  */
2315 void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue)
2316 {
2317   timeDiscr()->changeNbOfComponents(newNbOfComp,dftValue);
2318 }
2319
2320 /*!
2321  * Creates a new MEDCouplingFieldDouble composed of selected components of \a this field.
2322  * The new MEDCouplingFieldDouble has the same number of tuples but includes components
2323  * specified by \a compoIds parameter. So that getNbOfElems() of the result field
2324  * can be either less, same or more than \a this->getNumberOfValues().
2325  *  \param [in] compoIds - sequence of zero based indices of components to include
2326  *              into the new field.
2327  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble that the caller
2328  *          is to delete using decrRef() as it is no more needed.
2329  *  \throw If a component index (\a i) is not valid: 
2330  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
2331  */
2332 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
2333 {
2334   if(_type.isNull())
2335     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform keepSelectedComponents !");
2336   MEDCouplingTimeDiscretization *td(timeDiscr()->keepSelectedComponents(compoIds));
2337   td->copyTinyAttrFrom(*timeDiscr());
2338   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2339   ret->setName(getName());
2340   ret->setMesh(getMesh());
2341   return ret.retn();
2342 }
2343
2344
2345 /*!
2346  * Copy all components in a specified order from another field.
2347  * The number of tuples in \a this and the other field can be different.
2348  *  \param [in] f - the field to copy data from.
2349  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2350  *              to be copied.
2351  *  \throw If the two fields have different number of data arrays.
2352  *  \throw If a data array is set in one of fields and is not set in the other.
2353  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2354  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2355  */
2356 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds)
2357 {
2358   timeDiscr()->setSelectedComponents(f->timeDiscr(),compoIds);
2359 }
2360
2361 /*!
2362  * Sorts value within every tuple of \a this field.
2363  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2364  *              in descending order.
2365  *  \throw If a data array is not allocated.
2366  */
2367 void MEDCouplingFieldDouble::sortPerTuple(bool asc)
2368 {
2369   timeDiscr()->sortPerTuple(asc);
2370 }
2371
2372 /*!
2373  * Creates a new MEDCouplingFieldDouble by concatenating two given fields.
2374  * Values of
2375  * the first field precede values of the second field within the result field.
2376  *  \param [in] f1 - the first field.
2377  *  \param [in] f2 - the second field.
2378  *  \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2379  *          MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() 
2380  *          as it is no more needed.
2381  *  \throw If the fields are not compatible for the merge.
2382  *  \throw If the spatial discretization of \a f1 is NULL.
2383  *  \throw If the time discretization of \a f1 is NULL.
2384  *
2385  *  \if ENABLE_EXAMPLES
2386  *  \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2387  *  \ref  py_mcfielddouble_MergeFields "Here is a Python example".
2388  *  \endif
2389  */
2390 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2391 {
2392   if(!f1->areCompatibleForMerge(f2))
2393     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
2394   const MEDCouplingMesh *m1(f1->getMesh()),*m2(f2->getMesh());
2395   if(!f1->timeDiscr())
2396     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no time discr of f1 !");
2397   if(!f1->_type)
2398     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no spatial discr of f1 !");
2399   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->aggregate(f2->timeDiscr()));
2400   td->copyTinyAttrFrom(*f1->timeDiscr());
2401   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2402   ret->setName(f1->getName());
2403   ret->setDescription(f1->getDescription());
2404   if(m1)
2405     {
2406       MCAuto<MEDCouplingMesh> m=m1->mergeMyselfWith(m2);
2407       ret->setMesh(m);
2408     }
2409   return ret.retn();
2410 }
2411
2412 /*!
2413  * Creates a new MEDCouplingFieldDouble by concatenating all given fields.
2414  * Values of the *i*-th field precede values of the (*i*+1)-th field within the result.
2415  * If there is only one field in \a a, a deepCopy() (except time information of mesh and
2416  * field) of the field is returned. 
2417  * Generally speaking the first field in \a a is used to assign tiny attributes of the
2418  * returned field. 
2419  *  \param [in] a - a vector of fields (MEDCouplingFieldDouble) to concatenate.
2420  *  \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2421  *          MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() 
2422  *          as it is no more needed.
2423  *  \throw If \a a is empty.
2424  *  \throw If the fields are not compatible for the merge.
2425  *
2426  *  \if ENABLE_EXAMPLES
2427  *  \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2428  *  \ref  py_mcfielddouble_MergeFields "Here is a Python example".
2429  *  \endif
2430  */
2431 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a)
2432 {
2433   if(a.size()<1)
2434     throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !");
2435   std::vector< MCAuto<MEDCouplingUMesh> > ms(a.size());
2436   std::vector< const MEDCouplingUMesh *> ms2(a.size());
2437   std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
2438   std::vector<const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
2439   const MEDCouplingFieldDouble *ref=(*it++);
2440   if(!ref)
2441     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of NULL instance in first place of input vector !");
2442   for(;it!=a.end();it++)
2443     if(!ref->areCompatibleForMerge(*it))
2444       throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2445   for(int i=0;i<(int)a.size();i++)
2446     {
2447       if(a[i]->getMesh())
2448         { ms[i]=a[i]->getMesh()->buildUnstructured(); ms2[i]=ms[i]; }
2449       else
2450         { ms[i]=0; ms2[i]=0; }
2451       tds[i]=a[i]->timeDiscr();
2452     }
2453   MEDCouplingTimeDiscretization *td(tds[0]->aggregate(tds));
2454   td->copyTinyAttrFrom(*(a[0]->timeDiscr()));
2455   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()));
2456   ret->setName(a[0]->getName());
2457   ret->setDescription(a[0]->getDescription());
2458   if(ms2[0])
2459     {
2460       MCAuto<MEDCouplingUMesh> m(MEDCouplingUMesh::MergeUMeshes(ms2));
2461       m->copyTinyInfoFrom(ms2[0]);
2462       ret->setMesh(m);
2463     }
2464   return ret.retn();
2465 }
2466
2467 /*!
2468  * Creates a new MEDCouplingFieldDouble by concatenating components of two given fields.
2469  * The number of components in the result field is a sum of the number of components of
2470  * given fields. The number of tuples in the result field is same as that of each of given
2471  * arrays.
2472  * Number of tuples in the given fields must be the same.
2473  *  \param [in] f1 - a field to include in the result field.
2474  *  \param [in] f2 - another field to include in the result field.
2475  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2476  *          The caller is to delete this result field using decrRef() as it is no more
2477  *          needed.
2478  *  \throw If the fields are not compatible for a meld (areCompatibleForMeld()).
2479  *  \throw If any of data arrays is not allocated.
2480  *  \throw If \a f1->getNumberOfTuples() != \a f2->getNumberOfTuples()
2481  */
2482 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2483 {
2484   if(!f1 || !f2)
2485     throw INTERP_KERNEL::Exception("MeldFields : null input pointer !");
2486   if(!f1->areCompatibleForMeld(f2))
2487     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
2488   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->meld(f2->timeDiscr()));
2489   td->copyTinyAttrFrom(*f1->timeDiscr());
2490   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2491   ret->setMesh(f1->getMesh());
2492   return ret.retn();
2493 }
2494
2495 /*!
2496  * Returns a new MEDCouplingFieldDouble containing a dot product of two given fields, 
2497  * so that the i-th tuple of the result field is a sum of products of j-th components of
2498  * i-th tuples of given fields (\f$ f_i = \sum_{j=1}^n f1_j * f2_j \f$). 
2499  * Number of tuples and components in the given fields must be the same.
2500  *  \param [in] f1 - a given field.
2501  *  \param [in] f2 - another given field.
2502  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2503  *          The caller is to delete this result field using decrRef() as it is no more
2504  *          needed.
2505  *  \throw If either \a f1 or \a f2 is NULL.
2506  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2507  *         differ not only in values.
2508  */
2509 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2510 {
2511   if(!f1)
2512     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !");
2513   if(!f1->areStrictlyCompatibleForMulDiv(f2))
2514     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them!  Check support mesh, and spatial and time discretisation.");
2515   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->dot(f2->timeDiscr()));
2516   td->copyTinyAttrFrom(*f1->timeDiscr());
2517   MEDCouplingFieldDouble *ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2518   ret->setMesh(f1->getMesh());
2519   return ret;
2520 }
2521
2522 /*!
2523  * Returns a new MEDCouplingFieldDouble containing a cross product of two given fields, 
2524  * so that
2525  * the i-th tuple of the result field is a 3D vector which is a cross
2526  * product of two vectors defined by the i-th tuples of given fields.
2527  * Number of tuples in the given fields must be the same.
2528  * Number of components in the given fields must be 3.
2529  *  \param [in] f1 - a given field.
2530  *  \param [in] f2 - another given field.
2531  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2532  *          The caller is to delete this result field using decrRef() as it is no more
2533  *          needed.
2534  *  \throw If either \a f1 or \a f2 is NULL.
2535  *  \throw If \a f1->getNumberOfComponents() != 3
2536  *  \throw If \a f2->getNumberOfComponents() != 3
2537  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2538  *         differ not only in values.
2539  */
2540 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2541 {
2542   if(!f1)
2543     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !");
2544   if(!f1->areStrictlyCompatibleForMulDiv(f2))
2545     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation.");
2546   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->crossProduct(f2->timeDiscr()));
2547   td->copyTinyAttrFrom(*f1->timeDiscr());
2548   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2549   ret->setMesh(f1->getMesh());
2550   return ret.retn();
2551 }
2552
2553 /*!
2554  * Returns a new MEDCouplingFieldDouble containing maximal values of two given fields.
2555  * Number of tuples and components in the given fields must be the same.
2556  *  \param [in] f1 - a field to compare values with another one.
2557  *  \param [in] f2 - another field to compare values with the first one.
2558  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2559  *          The caller is to delete this result field using decrRef() as it is no more
2560  *          needed.
2561  *  \throw If either \a f1 or \a f2 is NULL.
2562  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2563  *         differ not only in values.
2564  *
2565  *  \if ENABLE_EXAMPLES
2566  *  \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2567  *  \ref  py_mcfielddouble_MaxFields "Here is a Python example".
2568  *  \endif
2569  */
2570 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2571 {
2572   if(!f1)
2573     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MaxFields : input field is NULL !");
2574   if(!f1->areStrictlyCompatible(f2))
2575     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MaxFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2576   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->max(f2->timeDiscr()));
2577   td->copyTinyAttrFrom(*f1->timeDiscr());
2578   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2579   ret->setMesh(f1->getMesh());
2580   return ret.retn();
2581 }
2582
2583 /*!
2584  * Returns a new MEDCouplingFieldDouble containing minimal values of two given fields.
2585  * Number of tuples and components in the given fields must be the same.
2586  *  \param [in] f1 - a field to compare values with another one.
2587  *  \param [in] f2 - another field to compare values with the first one.
2588  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2589  *          The caller is to delete this result field using decrRef() as it is no more
2590  *          needed.
2591  *  \throw If either \a f1 or \a f2 is NULL.
2592  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2593  *         differ not only in values.
2594  *
2595  *  \if ENABLE_EXAMPLES
2596  *  \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2597  *  \ref  py_mcfielddouble_MaxFields "Here is a Python example".
2598  *  \endif
2599  */
2600 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2601 {
2602   if(!f1)
2603     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MinFields : input field is NULL !");
2604   if(!f1->areStrictlyCompatible(f2))
2605     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MinFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2606   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->min(f2->timeDiscr()));
2607   td->copyTinyAttrFrom(*f1->timeDiscr());
2608   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2609   ret->setMesh(f1->getMesh());
2610   return ret.retn();
2611 }
2612
2613 /*!
2614  * Returns a copy of \a this field in which sign of all values is reversed.
2615  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble
2616  *         containing the same number of tuples and components as \a this field. 
2617  *         The caller is to delete this result field using decrRef() as it is no more
2618  *         needed. 
2619  *  \throw If the spatial discretization of \a this field is NULL.
2620  *  \throw If a data array is not allocated.
2621  */
2622 MEDCouplingFieldDouble *MEDCouplingFieldDouble::negate() const
2623 {
2624   if(_type.isNull())
2625     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform negate !");
2626   MEDCouplingTimeDiscretization *td(timeDiscr()->negate());
2627   td->copyTinyAttrFrom(*timeDiscr());
2628   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2629   ret->setMesh(getMesh());
2630   return ret.retn();
2631 }
2632
2633 /*!
2634  * Returns a new MEDCouplingFieldDouble containing sum values of corresponding values of
2635  * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] + _f2_ [ i, j ] ).
2636  * Number of tuples and components in the given fields must be the same.
2637  *  \param [in] f1 - a field to sum up.
2638  *  \param [in] f2 - another field to sum up.
2639  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2640  *          The caller is to delete this result field using decrRef() as it is no more
2641  *          needed.
2642  *  \throw If either \a f1 or \a f2 is NULL.
2643  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2644  *         differ not only in values.
2645  */
2646 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2647 {
2648   if(!f1)
2649     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::AddFields : input field is NULL !");
2650   if(!f1->areStrictlyCompatible(f2))
2651     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply AddFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2652   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->add(f2->timeDiscr()));
2653   td->copyTinyAttrFrom(*f1->timeDiscr());
2654   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2655   ret->setMesh(f1->getMesh());
2656   return ret.retn();
2657 }
2658
2659 /*!
2660  * Adds values of another MEDCouplingFieldDouble to values of \a this one
2661  * ( _this_ [ i, j ] += _other_ [ i, j ] ) using DataArrayDouble::addEqual().
2662  * The two fields must have same number of tuples, components and same underlying mesh.
2663  *  \param [in] other - the field to add to \a this one.
2664  *  \return const MEDCouplingFieldDouble & - a reference to \a this field.
2665  *  \throw If \a other is NULL.
2666  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2667  *         differ not only in values.
2668  */
2669 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other)
2670 {
2671   if(!areStrictlyCompatible(&other))
2672     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply += on them! Check support mesh, field nature, and spatial and time discretisation.");
2673   timeDiscr()->addEqual(other.timeDiscr());
2674   return *this;
2675 }
2676
2677 /*!
2678  * Returns a new MEDCouplingFieldDouble containing subtraction of corresponding values of
2679  * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] - _f2_ [ i, j ] ).
2680  * Number of tuples and components in the given fields must be the same.
2681  *  \param [in] f1 - a field to subtract from.
2682  *  \param [in] f2 - a field to subtract.
2683  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2684  *          The caller is to delete this result field using decrRef() as it is no more
2685  *          needed.
2686  *  \throw If either \a f1 or \a f2 is NULL.
2687  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2688  *         differ not only in values.
2689  */
2690 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2691 {
2692   if(!f1)
2693     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::SubstractFields : input field is NULL !");
2694   if(!f1->areStrictlyCompatible(f2))
2695     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply SubstractFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2696   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->substract(f2->timeDiscr()));
2697   td->copyTinyAttrFrom(*f1->timeDiscr());
2698   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2699   ret->setMesh(f1->getMesh());
2700   return ret.retn();
2701 }
2702
2703 /*!
2704  * Subtract values of another MEDCouplingFieldDouble from values of \a this one
2705  * ( _this_ [ i, j ] -= _other_ [ i, j ] ) using DataArrayDouble::substractEqual().
2706  * The two fields must have same number of tuples, components and same underlying mesh.
2707  *  \param [in] other - the field to subtract from \a this one.
2708  *  \return const MEDCouplingFieldDouble & - a reference to \a this field.
2709  *  \throw If \a other is NULL.
2710  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2711  *         differ not only in values.
2712  */
2713 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other)
2714 {
2715   if(!areStrictlyCompatible(&other))
2716     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply -= on them! Check support mesh, field nature, and spatial and time discretisation.");
2717   timeDiscr()->substractEqual(other.timeDiscr());
2718   return *this;
2719 }
2720
2721 /*!
2722  * Returns a new MEDCouplingFieldDouble containing product values of
2723  * two given fields. There are 2 valid cases.
2724  * 1.  The fields have same number of tuples and components. Then each value of
2725  *   the result field (_f_) is a product of the corresponding values of _f1_ and
2726  *   _f2_, i.e. _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, j ].
2727  * 2.  The fields have same number of tuples and one field, say _f2_, has one
2728  *   component. Then
2729  *   _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, 0 ].
2730  *
2731  * The two fields must have same number of tuples and same underlying mesh.
2732  *  \param [in] f1 - a factor field.
2733  *  \param [in] f2 - another factor field.
2734  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2735  *          The caller is to delete this result field using decrRef() as it is no more
2736  *          needed.
2737  *  \throw If either \a f1 or \a f2 is NULL.
2738  *  \throw If the fields are not compatible for multiplication (areCompatibleForMul()),
2739  *         i.e. they differ not only in values and possibly number of components.
2740  */
2741 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2742 {
2743   if(!f1)
2744     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MultiplyFields : input field is NULL !");
2745   if(!f1->areCompatibleForMul(f2))
2746     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MultiplyFields on them! Check support mesh, and spatial and time discretisation.");
2747   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->multiply(f2->timeDiscr()));
2748   td->copyTinyAttrFrom(*f1->timeDiscr());
2749   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2750   ret->setMesh(f1->getMesh());
2751   return ret.retn();
2752 }
2753
2754 /*!
2755  * Multiply values of another MEDCouplingFieldDouble to values of \a this one
2756  * using DataArrayDouble::multiplyEqual().
2757  * The two fields must have same number of tuples and same underlying mesh.
2758  * There are 2 valid cases.
2759  * 1.  The fields have same number of components. Then each value of
2760  *   \a other is multiplied to the corresponding value of \a this field, i.e.
2761  *   _this_ [ i, j ] *= _other_ [ i, j ].
2762  * 2. The _other_ field has one component. Then
2763  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
2764  *
2765  * The two fields must have same number of tuples and same underlying mesh.
2766  *  \param [in] other - an field to multiply to \a this one.
2767  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2768  *          The caller is to delete this result field using decrRef() as it is no more
2769  *          needed.
2770  *  \throw If \a other is NULL.
2771  *  \throw If the fields are not strictly compatible for multiplication
2772  *         (areCompatibleForMul()),
2773  *         i.e. they differ not only in values and possibly in number of components.
2774  */
2775 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other)
2776 {
2777   if(!areCompatibleForMul(&other))
2778     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply *= on them! Check support mesh, and spatial and time discretisation.");
2779   timeDiscr()->multiplyEqual(other.timeDiscr());
2780   _nature = NoNature;
2781   return *this;
2782 }
2783
2784 /*!
2785  * Returns a new MEDCouplingFieldDouble containing division of two given fields.
2786  * There are 2 valid cases.
2787  * 1.  The fields have same number of tuples and components. Then each value of
2788  *   the result field (_f_) is a division of the corresponding values of \a f1 and
2789  *   \a f2, i.e. _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, j ].
2790  * 2.  The fields have same number of tuples and _f2_ has one component. Then
2791  *   _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, 0 ].
2792  *
2793  *  \param [in] f1 - a numerator field.
2794  *  \param [in] f2 - a denominator field.
2795  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2796  *          The caller is to delete this result field using decrRef() as it is no more
2797  *          needed.
2798  *  \throw If either \a f1 or \a f2 is NULL.
2799  *  \throw If the fields are not compatible for division (areCompatibleForDiv()),
2800  *         i.e. they differ not only in values and possibly in number of components.
2801  */
2802 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2803 {
2804   if(!f1)
2805     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DivideFields : input field is NULL !");
2806   if(!f1->areCompatibleForDiv(f2))
2807     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DivideFields on them! Check support mesh, and spatial and time discretisation.");
2808   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->divide(f2->timeDiscr()));
2809   td->copyTinyAttrFrom(*f1->timeDiscr());
2810   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2811   ret->setMesh(f1->getMesh());
2812   return ret.retn();
2813 }
2814
2815 /*!
2816  * Divide values of \a this field by values of another MEDCouplingFieldDouble
2817  * using DataArrayDouble::divideEqual().
2818  * The two fields must have same number of tuples and same underlying mesh.
2819  * There are 2 valid cases.
2820  * 1.  The fields have same number of components. Then each value of
2821  *    \a this field is divided by the corresponding value of \a other one, i.e.
2822  *   _this_ [ i, j ] /= _other_ [ i, j ].
2823  * 2.  The \a other field has one component. Then
2824  *   _this_ [ i, j ] /= _other_ [ i, 0 ].
2825  *
2826  *  \warning No check of division by zero is performed!
2827  *  \param [in] other - an field to divide \a this one by.
2828  *  \throw If \a other is NULL.
2829  *  \throw If the fields are not compatible for division (areCompatibleForDiv()),
2830  *         i.e. they differ not only in values and possibly in number of components.
2831  */
2832 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other)
2833 {
2834   if(!areCompatibleForDiv(&other))
2835     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply /= on them! Check support mesh, and spatial and time discretisation.");
2836   timeDiscr()->divideEqual(other.timeDiscr());
2837   _nature = NoNature;
2838   return *this;
2839 }
2840
2841 /*!
2842  * Directly called by MEDCouplingFieldDouble::operator^.
2843  * 
2844  * \sa MEDCouplingFieldDouble::operator^
2845  */
2846 MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2847 {
2848   if(!f1)
2849     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::PowFields : input field is NULL !");
2850   if(!f1->areCompatibleForMul(f2))
2851     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply PowFields on them! Check support mesh, and spatial and time discretisation.");
2852   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->pow(f2->timeDiscr()));
2853   td->copyTinyAttrFrom(*f1->timeDiscr());
2854   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2855   ret->setMesh(f1->getMesh());
2856   return ret.retn();
2857 }
2858
2859 /*!
2860  * Directly call MEDCouplingFieldDouble::PowFields static method.
2861  * 
2862  * \sa MEDCouplingFieldDouble::PowFields
2863  */
2864 MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const
2865 {
2866   return PowFields(this,&other);
2867 }
2868
2869 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other)
2870 {
2871   if(!areCompatibleForDiv(&other))
2872     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply ^= on them!  Check support mesh, and spatial and time discretisation.");
2873   timeDiscr()->powEqual(other.timeDiscr());
2874   _nature = NoNature;
2875   return *this;
2876 }
2877
2878 /*!
2879  * Writes the field series \a fs and the mesh the fields lie on in the VTK file \a fileName.
2880  * If \a fs is empty no file is written.
2881  * The result file is valid provided that no exception is thrown.
2882  * \warning All the fields must be named and lie on the same non NULL mesh.
2883  *  \param [in] fileName - the name of a VTK file to write in.
2884  *  \param [in] fs - the fields to write.
2885  *  \param [in] isBinary - specifies the VTK format of the written file. By default true (Binary mode)
2886  *  \throw If \a fs[ 0 ] == NULL.
2887  *  \throw If the fields lie not on the same mesh.
2888  *  \throw If the mesh is not set.
2889  *  \throw If any of the fields has no name.
2890  *
2891  *  \if ENABLE_EXAMPLES
2892  *  \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".<br>
2893  *  \ref  py_mcfielddouble_WriteVTK "Here is a Python example".
2894  *  \endif
2895  */
2896 std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector<const MEDCouplingFieldDouble *>& fs, bool isBinary)
2897 {
2898   if(fs.empty())
2899     return std::string();
2900   std::size_t nfs=fs.size();
2901   if(!fs[0])
2902     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field is NULL !");
2903   const MEDCouplingMesh *m=fs[0]->getMesh();
2904   if(!m)
2905     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field lies on NULL mesh !");
2906   for(std::size_t i=1;i<nfs;i++)
2907     if(fs[i]->getMesh()!=m)
2908       throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are not lying on a same mesh ! Expected by VTK ! MEDCouplingFieldDouble::setMesh or MEDCouplingFieldDouble::changeUnderlyingMesh can help to that.");
2909   if(!m)
2910     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !");
2911   std::string ret(m->getVTKFileNameOf(fileName));
2912   MCAuto<DataArrayByte> byteArr;
2913   if(isBinary)
2914     { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); }
2915   std::ostringstream coss,noss;
2916   for(std::size_t i=0;i<nfs;i++)
2917     {
2918       const MEDCouplingFieldDouble *cur=fs[i];
2919       std::string name(cur->getName());
2920       if(name.empty())
2921         {
2922           std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
2923           throw INTERP_KERNEL::Exception(oss.str());
2924         }
2925       TypeOfField typ=cur->getTypeOfField();
2926       if(typ==ON_CELLS)
2927         cur->getArray()->writeVTK(coss,8,cur->getName(),byteArr);
2928       else if(typ==ON_NODES)
2929         cur->getArray()->writeVTK(noss,8,cur->getName(),byteArr);
2930       else
2931         throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : only node and cell fields supported for the moment !");
2932     }
2933   m->writeVTKAdvanced(ret,coss.str(),noss.str(),byteArr);
2934   return ret;
2935 }
2936
2937 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoizeGen(const Voronizer *vor, double eps) const
2938 {
2939   checkConsistencyLight();
2940   if(!vor)
2941     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoizeGen : null pointer !");
2942   MCAuto<MEDCouplingFieldDouble> fieldToWO;
2943   const MEDCouplingMesh *inpMeshBase(getMesh());
2944   MCAuto<MEDCouplingUMesh> inpMesh(inpMeshBase->buildUnstructured());
2945   std::string meshName(inpMesh->getName());
2946   if(!inpMesh->isPresenceOfQuadratic())
2947     fieldToWO=clone(false);
2948   else
2949     {
2950       fieldToWO=convertQuadraticCellsToLinear();
2951       inpMeshBase=fieldToWO->getMesh();
2952       inpMesh=inpMeshBase->buildUnstructured();
2953     }
2954   int nbCells(inpMesh->getNumberOfCells());
2955   const MEDCouplingFieldDiscretization *disc(fieldToWO->getDiscretization());
2956   const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
2957   if(!disc2)
2958     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : Not a ON_GAUSS_PT field");
2959   int nbLocs(disc2->getNbOfGaussLocalization());
2960   std::vector< MCAuto<MEDCouplingUMesh> > cells(nbCells);
2961   for(int i=0;i<nbLocs;i++)
2962     {
2963       const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(i));
2964       if(gl.getDimension()!=vor->getDimension())
2965         throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : not a 2D one !");
2966       MCAuto<MEDCouplingUMesh> mesh(gl.buildRefCell());
2967       const std::vector<double>& coo(gl.getGaussCoords());
2968       MCAuto<DataArrayDouble> coo2(DataArrayDouble::NewFromStdVector(coo));
2969       coo2->rearrange(vor->getDimension());
2970       //
2971       MCAuto<MEDCouplingUMesh> coo3(MEDCouplingUMesh::Build0DMeshFromCoords(coo2));
2972       //
2973       MCAuto<MEDCouplingUMesh> vorCellsForCurDisc(vor->doIt(mesh,coo2,eps));
2974       std::vector<int> ids;
2975       MCAuto<DataArrayDouble> ptsInReal;
2976       disc2->getCellIdsHavingGaussLocalization(i,ids);
2977       {
2978         MCAuto<MEDCouplingUMesh> subMesh(inpMesh->buildPartOfMySelf(&ids[0],&ids[0]+ids.size()));
2979         ptsInReal=gl.localizePtsInRefCooForEachCell(vorCellsForCurDisc->getCoords(),subMesh);
2980       }
2981       int nbPtsPerCell(vorCellsForCurDisc->getNumberOfNodes());
2982       for(std::size_t j=0;j<ids.size();j++)
2983         {
2984           MCAuto<MEDCouplingUMesh> elt(vorCellsForCurDisc->clone(false));
2985           MCAuto<DataArrayDouble> coo4(ptsInReal->selectByTupleIdSafeSlice(j*nbPtsPerCell,(j+1)*nbPtsPerCell,1));
2986           elt->setCoords(coo4);
2987           cells[ids[j]]=elt;
2988         }
2989     }
2990   std::vector< const MEDCouplingUMesh * > cellsPtr(VecAutoToVecOfCstPt(cells));
2991   MCAuto<MEDCouplingUMesh> outMesh(MEDCouplingUMesh::MergeUMeshes(cellsPtr));
2992   outMesh->setName(meshName);
2993   MCAuto<MEDCouplingFieldDouble> onCells(MEDCouplingFieldDouble::New(ON_CELLS));
2994   onCells->setMesh(outMesh);
2995   {
2996     MCAuto<DataArrayDouble> arr(fieldToWO->getArray()->deepCopy());
2997     onCells->setArray(arr);
2998   }
2999   onCells->setTimeUnit(getTimeUnit());
3000   {
3001     int b,c;
3002     double a(getTime(b,c));
3003     onCells->setTime(a,b,c);
3004   }
3005   onCells->setName(getName());
3006   return onCells;
3007 }
3008
3009 MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr()
3010 {
3011   MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
3012   if(!ret)
3013     return 0;
3014   MEDCouplingTimeDiscretization *retc(dynamic_cast<MEDCouplingTimeDiscretization *>(ret));
3015   if(!retc)
3016     throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");
3017   return retc;
3018 }
3019
3020 const MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr() const
3021 {
3022   const MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
3023   if(!ret)
3024     return 0;
3025   const MEDCouplingTimeDiscretization *retc(dynamic_cast<const MEDCouplingTimeDiscretization *>(ret));
3026   if(!retc)
3027     throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");
3028   return retc;
3029 }