Salome HOME
Small but useful DataArrayInt::checkUniformAndGuess
[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 deepCopy) const
178 {
179   MEDCouplingTimeDiscretization *tdo=timeDiscr()->buildNewTimeReprFromThis(td,deepCopy);
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 deepCopy):MEDCouplingFieldT<double>(other,deepCopy)
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         const DataArrayDouble *arr(getArray());
2020         std::vector< MCAuto<DataArrayInt> > cellIdsV;
2021         std::vector< MCAuto<MEDCouplingUMesh> > meshesV;
2022         std::vector< MEDCouplingGaussLocalization > glV;
2023         bool isZipReq(false);
2024         for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=gt.begin();it!=gt.end();it++)
2025           {
2026             const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it));
2027             MCAuto<DataArrayInt> cellIds(umesh->giveCellsWithType(*it));
2028             cellIdsV.push_back(cellIds);
2029             MCAuto<MEDCouplingUMesh> part(umesh->buildPartOfMySelf(cellIds->begin(),cellIds->end()));
2030             int id(disc2->getGaussLocalizationIdOfOneType(*it));
2031             const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(id));
2032             if(!cm.isQuadratic())
2033               {
2034                 glV.push_back(gl);
2035               }
2036             else
2037               {
2038                 isZipReq=true;
2039                 part->convertQuadraticCellsToLinear();
2040                 INTERP_KERNEL::GaussInfo gi(*it,gl.getGaussCoords(),gl.getNumberOfGaussPt(),gl.getRefCoords(),gl.getNumberOfPtsInRefCell());
2041                 INTERP_KERNEL::GaussInfo gi2(gi.convertToLinear());
2042                 MEDCouplingGaussLocalization gl2(gi2.getGeoType(),gi2.getRefCoords(),gi2.getGaussCoords(),gl.getWeights());
2043                 glV.push_back(gl2);
2044               }
2045             meshesV.push_back(part);
2046           }
2047         //
2048         {
2049           std::vector< const MEDCouplingUMesh * > meshesPtr(VecAutoToVecOfCstPt(meshesV));
2050           umesh=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshesPtr);
2051           std::vector< const DataArrayInt * > zeCellIds(VecAutoToVecOfCstPt(cellIdsV));
2052           MCAuto<DataArrayInt> zeIds(DataArrayInt::Aggregate(zeCellIds));
2053           umesh->renumberCells(zeIds->begin());
2054           umesh->setName(mesh->getName());
2055         }
2056         //
2057         if(isZipReq)
2058           umesh->zipCoords();
2059         ret->setArray(const_cast<DataArrayDouble *>(getArray()));
2060         ret->setMesh(umesh);
2061         for(std::vector< MEDCouplingGaussLocalization >::const_iterator it=glV.begin();it!=glV.end();it++)
2062           ret->setGaussLocalizationOnType((*it).getType(),(*it).getRefCoords(),(*it).getGaussCoords(),(*it).getWeights());
2063         ret->copyAllTinyAttrFrom(this);
2064         ret->checkConsistencyLight();
2065         return ret;
2066       }
2067     default:
2068       throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : Only available for fields on nodes and on cells !");
2069     }
2070 }
2071
2072 /*!
2073  * 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.
2074  * Finaly \a this is also expected to be consistent.
2075  * In these conditions this method returns a newly created field (to be dealed by the caller).
2076  * The returned field will also 3 compo vector field be on nodes lying on the same mesh than \a this.
2077  * 
2078  * 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.
2079  * \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.
2080  *
2081  * \sa DataArrayDouble::fromCartToCylGiven
2082  */
2083 MEDCouplingFieldDouble *MEDCouplingFieldDouble::computeVectorFieldCyl(const double center[3], const double vect[3]) const
2084 {
2085   checkConsistencyLight();
2086   const DataArrayDouble *coo(getMesh()->getDirectAccessOfCoordsArrIfInStructure());
2087   MEDCouplingTimeDiscretization *td(timeDiscr()->computeVectorFieldCyl(coo,center,vect));
2088   td->copyTinyAttrFrom(*timeDiscr());
2089   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2090   ret->setMesh(getMesh());
2091   ret->setName(getName());
2092   return ret.retn();
2093 }
2094
2095 /*!
2096  * Creates a new MEDCouplingFieldDouble filled with the doubly contracted product of
2097  * every tensor of \a this 6-componental field.
2098  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2099  *          each tuple is calculated from the tuple <em>(t)</em> of \a this field as
2100  *          follows: \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$. 
2101  *          This new field lies on the same mesh as \a this one. The caller is to delete
2102  *          this field using decrRef() as it is no more needed.
2103  *  \throw If \a this->getNumberOfComponents() != 6.
2104  *  \throw If the spatial discretization of \a this field is NULL.
2105  */
2106 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const
2107 {
2108   if(_type.isNull())
2109     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform doublyContractedProduct !");
2110   MEDCouplingTimeDiscretization *td(timeDiscr()->doublyContractedProduct());
2111   td->copyTinyAttrFrom(*timeDiscr());
2112   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2113   ret->setName("DoublyContractedProduct");
2114   ret->setMesh(getMesh());
2115   return ret.retn();
2116 }
2117
2118 /*!
2119  * Creates a new MEDCouplingFieldDouble filled with the determinant of a square
2120  * matrix defined by every tuple of \a this field, having either 4, 6 or 9 components.
2121  * The case of 6 components corresponds to that of the upper triangular matrix. 
2122  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2123  *          each tuple is the determinant of matrix of the corresponding tuple of \a this 
2124  *          field. This new field lies on the same mesh as \a this one. The caller is to 
2125  *          delete this field using decrRef() as it is no more needed.
2126  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2127  *  \throw If the spatial discretization of \a this field is NULL.
2128  */
2129 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const
2130 {
2131   if(_type.isNull())
2132     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform determinant !");
2133   MEDCouplingTimeDiscretization *td(timeDiscr()->determinant());
2134   td->copyTinyAttrFrom(*timeDiscr());
2135   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2136   ret->setName("Determinant");
2137   ret->setMesh(getMesh());
2138   return ret.retn();
2139 }
2140
2141
2142 /*!
2143  * Creates a new MEDCouplingFieldDouble with 3 components filled with 3 eigenvalues of
2144  * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2145  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2146  *          having 3 components, whose each tuple contains the eigenvalues of the matrix of
2147  *          corresponding tuple of \a this field. This new field lies on the same mesh as
2148  *          \a this one. The caller is to delete this field using decrRef() as it is no
2149  *          more needed.  
2150  *  \throw If \a this->getNumberOfComponents() != 6.
2151  *  \throw If the spatial discretization of \a this field is NULL.
2152  */
2153 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const
2154 {
2155   if(_type.isNull())
2156     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenValues !");
2157   MEDCouplingTimeDiscretization *td(timeDiscr()->eigenValues());
2158   td->copyTinyAttrFrom(*timeDiscr());
2159   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2160   ret->setName("EigenValues");
2161   ret->setMesh(getMesh());
2162   return ret.retn();
2163 }
2164
2165 /*!
2166  * Creates a new MEDCouplingFieldDouble with 9 components filled with 3 eigenvectors of
2167  * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2168  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2169  *          having 9 components, whose each tuple contains the eigenvectors of the matrix of
2170  *          corresponding tuple of \a this field. This new field lies on the same mesh as
2171  *          \a this one. The caller is to delete this field using decrRef() as it is no
2172  *          more needed.  
2173  *  \throw If \a this->getNumberOfComponents() != 6.
2174  *  \throw If the spatial discretization of \a this field is NULL.
2175  */
2176 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const
2177 {
2178   if(_type.isNull())
2179     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenVectors !");
2180   MEDCouplingTimeDiscretization *td(timeDiscr()->eigenVectors());
2181   td->copyTinyAttrFrom(*timeDiscr());
2182   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2183   ret->setName("EigenVectors");
2184   ret->setMesh(getMesh());
2185   return ret.retn();
2186 }
2187
2188 /*!
2189  * Creates a new MEDCouplingFieldDouble filled with the inverse matrix of
2190  * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2191  * components. The case of 6 components corresponds to that of the upper triangular
2192  * matrix.
2193  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2194  *          having the same number of components as \a this one, whose each tuple
2195  *          contains the inverse matrix of the matrix of corresponding tuple of \a this
2196  *          field. This new field lies on the same mesh as \a this one. The caller is to
2197  *          delete this field using decrRef() as it is no more needed.  
2198  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2199  *  \throw If the spatial discretization of \a this field is NULL.
2200  */
2201 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const
2202 {
2203   if(_type.isNull())
2204     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform inverse !");
2205   MEDCouplingTimeDiscretization *td(timeDiscr()->inverse());
2206   td->copyTinyAttrFrom(*timeDiscr());
2207   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2208   ret->setName("Inversion");
2209   ret->setMesh(getMesh());
2210   return ret.retn();
2211 }
2212
2213 /*!
2214  * Creates a new MEDCouplingFieldDouble filled with the trace of
2215  * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2216  * components. The case of 6 components corresponds to that of the upper triangular
2217  * matrix.
2218  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2219  *          having 1 component, whose each tuple is the trace of the matrix of
2220  *          corresponding tuple of \a this field.
2221  *          This new field lies on the same mesh as \a this one. The caller is to
2222  *          delete this field using decrRef() as it is no more needed.  
2223  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2224  *  \throw If the spatial discretization of \a this field is NULL.
2225  */
2226 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const
2227 {
2228   if(_type.isNull())
2229     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform trace !");
2230   MEDCouplingTimeDiscretization *td(timeDiscr()->trace());
2231   td->copyTinyAttrFrom(*timeDiscr());
2232   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2233   ret->setName("Trace");
2234   ret->setMesh(getMesh());
2235   return ret.retn();
2236 }
2237
2238 /*!
2239  * Creates a new MEDCouplingFieldDouble filled with the stress deviator tensor of
2240  * a stress tensor defined by every tuple of \a this 6-componental field.
2241  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2242  *          having same number of components and tuples as \a this field,
2243  *          whose each tuple contains the stress deviator tensor of the stress tensor of
2244  *          corresponding tuple of \a this field. This new field lies on the same mesh as
2245  *          \a this one. The caller is to delete this field using decrRef() as it is no
2246  *          more needed.  
2247  *  \throw If \a this->getNumberOfComponents() != 6.
2248  *  \throw If the spatial discretization of \a this field is NULL.
2249  */
2250 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const
2251 {
2252   if(_type.isNull())
2253     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform deviator !");
2254   MEDCouplingTimeDiscretization *td(timeDiscr()->deviator());
2255   td->copyTinyAttrFrom(*timeDiscr());
2256   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2257   ret->setName("Deviator");
2258   ret->setMesh(getMesh());
2259   return ret.retn();
2260 }
2261
2262 /*!
2263  * Creates a new MEDCouplingFieldDouble filled with the magnitude of
2264  * every vector of \a this field.
2265  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2266  *          having one component, whose each tuple is the magnitude of the vector
2267  *          of corresponding tuple of \a this field. This new field lies on the
2268  *          same mesh as \a this one. The caller is to
2269  *          delete this field using decrRef() as it is no more needed.  
2270  *  \throw If the spatial discretization of \a this field is NULL.
2271  */
2272 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const
2273 {
2274   if(_type.isNull())
2275     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform magnitude !");
2276   MEDCouplingTimeDiscretization *td(timeDiscr()->magnitude());
2277   td->copyTinyAttrFrom(*timeDiscr());
2278   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2279   ret->setName("Magnitude");
2280   ret->setMesh(getMesh());
2281   return ret.retn();
2282 }
2283
2284 /*!
2285  * Creates a new scalar MEDCouplingFieldDouble filled with the maximal value among
2286  * values of every tuple of \a this field.
2287  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2288  *          This new field lies on the same mesh as \a this one. The caller is to
2289  *          delete this field using decrRef() as it is no more needed.  
2290  *  \throw If the spatial discretization of \a this field is NULL.
2291  */
2292 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const
2293 {
2294   if(_type.isNull())
2295     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform maxPerTuple !");
2296   MEDCouplingTimeDiscretization *td(timeDiscr()->maxPerTuple());
2297   td->copyTinyAttrFrom(*timeDiscr());
2298   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2299   std::ostringstream oss;
2300   oss << "Max_" << getName();
2301   ret->setName(oss.str());
2302   ret->setMesh(getMesh());
2303   return ret.retn();
2304 }
2305
2306 /*!
2307  * Changes number of components in \a this field. If \a newNbOfComp is less
2308  * than \a this->getNumberOfComponents() then each tuple
2309  * is truncated to have \a newNbOfComp components, keeping first components. If \a
2310  * newNbOfComp is more than \a this->getNumberOfComponents() then 
2311  * each tuple is populated with \a dftValue to have \a newNbOfComp components.  
2312  *  \param [in] newNbOfComp - number of components for the new field to have.
2313  *  \param [in] dftValue - value assigned to new values added to \a this field.
2314  *  \throw If \a this is not allocated.
2315  */
2316 void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue)
2317 {
2318   timeDiscr()->changeNbOfComponents(newNbOfComp,dftValue);
2319 }
2320
2321 /*!
2322  * Creates a new MEDCouplingFieldDouble composed of selected components of \a this field.
2323  * The new MEDCouplingFieldDouble has the same number of tuples but includes components
2324  * specified by \a compoIds parameter. So that getNbOfElems() of the result field
2325  * can be either less, same or more than \a this->getNumberOfValues().
2326  *  \param [in] compoIds - sequence of zero based indices of components to include
2327  *              into the new field.
2328  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble that the caller
2329  *          is to delete using decrRef() as it is no more needed.
2330  *  \throw If a component index (\a i) is not valid: 
2331  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
2332  */
2333 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
2334 {
2335   if(_type.isNull())
2336     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform keepSelectedComponents !");
2337   MEDCouplingTimeDiscretization *td(timeDiscr()->keepSelectedComponents(compoIds));
2338   td->copyTinyAttrFrom(*timeDiscr());
2339   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2340   ret->setName(getName());
2341   ret->setMesh(getMesh());
2342   return ret.retn();
2343 }
2344
2345
2346 /*!
2347  * Copy all components in a specified order from another field.
2348  * The number of tuples in \a this and the other field can be different.
2349  *  \param [in] f - the field to copy data from.
2350  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2351  *              to be copied.
2352  *  \throw If the two fields have different number of data arrays.
2353  *  \throw If a data array is set in one of fields and is not set in the other.
2354  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2355  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2356  */
2357 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds)
2358 {
2359   timeDiscr()->setSelectedComponents(f->timeDiscr(),compoIds);
2360 }
2361
2362 /*!
2363  * Sorts value within every tuple of \a this field.
2364  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2365  *              in descending order.
2366  *  \throw If a data array is not allocated.
2367  */
2368 void MEDCouplingFieldDouble::sortPerTuple(bool asc)
2369 {
2370   timeDiscr()->sortPerTuple(asc);
2371 }
2372
2373 /*!
2374  * Creates a new MEDCouplingFieldDouble by concatenating two given fields.
2375  * Values of
2376  * the first field precede values of the second field within the result field.
2377  *  \param [in] f1 - the first field.
2378  *  \param [in] f2 - the second field.
2379  *  \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2380  *          MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() 
2381  *          as it is no more needed.
2382  *  \throw If the fields are not compatible for the merge.
2383  *  \throw If the spatial discretization of \a f1 is NULL.
2384  *  \throw If the time discretization of \a f1 is NULL.
2385  *
2386  *  \if ENABLE_EXAMPLES
2387  *  \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2388  *  \ref  py_mcfielddouble_MergeFields "Here is a Python example".
2389  *  \endif
2390  */
2391 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2392 {
2393   if(!f1->areCompatibleForMerge(f2))
2394     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
2395   const MEDCouplingMesh *m1(f1->getMesh()),*m2(f2->getMesh());
2396   if(!f1->timeDiscr())
2397     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no time discr of f1 !");
2398   if(!f1->_type)
2399     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no spatial discr of f1 !");
2400   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->aggregate(f2->timeDiscr()));
2401   td->copyTinyAttrFrom(*f1->timeDiscr());
2402   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2403   ret->setName(f1->getName());
2404   ret->setDescription(f1->getDescription());
2405   if(m1)
2406     {
2407       MCAuto<MEDCouplingMesh> m=m1->mergeMyselfWith(m2);
2408       ret->setMesh(m);
2409     }
2410   return ret.retn();
2411 }
2412
2413 /*!
2414  * Creates a new MEDCouplingFieldDouble by concatenating all given fields.
2415  * Values of the *i*-th field precede values of the (*i*+1)-th field within the result.
2416  * If there is only one field in \a a, a deepCopy() (except time information of mesh and
2417  * field) of the field is returned. 
2418  * Generally speaking the first field in \a a is used to assign tiny attributes of the
2419  * returned field. 
2420  *  \param [in] a - a vector of fields (MEDCouplingFieldDouble) to concatenate.
2421  *  \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2422  *          MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() 
2423  *          as it is no more needed.
2424  *  \throw If \a a is empty.
2425  *  \throw If the fields are not compatible for the merge.
2426  *
2427  *  \if ENABLE_EXAMPLES
2428  *  \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2429  *  \ref  py_mcfielddouble_MergeFields "Here is a Python example".
2430  *  \endif
2431  */
2432 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a)
2433 {
2434   if(a.size()<1)
2435     throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !");
2436   std::vector< MCAuto<MEDCouplingUMesh> > ms(a.size());
2437   std::vector< const MEDCouplingUMesh *> ms2(a.size());
2438   std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
2439   std::vector<const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
2440   const MEDCouplingFieldDouble *ref=(*it++);
2441   if(!ref)
2442     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of NULL instance in first place of input vector !");
2443   for(;it!=a.end();it++)
2444     if(!ref->areCompatibleForMerge(*it))
2445       throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2446   for(int i=0;i<(int)a.size();i++)
2447     {
2448       if(a[i]->getMesh())
2449         { ms[i]=a[i]->getMesh()->buildUnstructured(); ms2[i]=ms[i]; }
2450       else
2451         { ms[i]=0; ms2[i]=0; }
2452       tds[i]=a[i]->timeDiscr();
2453     }
2454   MEDCouplingTimeDiscretization *td(tds[0]->aggregate(tds));
2455   td->copyTinyAttrFrom(*(a[0]->timeDiscr()));
2456   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()));
2457   ret->setName(a[0]->getName());
2458   ret->setDescription(a[0]->getDescription());
2459   if(ms2[0])
2460     {
2461       MCAuto<MEDCouplingUMesh> m(MEDCouplingUMesh::MergeUMeshes(ms2));
2462       m->copyTinyInfoFrom(ms2[0]);
2463       ret->setMesh(m);
2464     }
2465   return ret.retn();
2466 }
2467
2468 /*!
2469  * Creates a new MEDCouplingFieldDouble by concatenating components of two given fields.
2470  * The number of components in the result field is a sum of the number of components of
2471  * given fields. The number of tuples in the result field is same as that of each of given
2472  * arrays.
2473  * Number of tuples in the given fields must be the same.
2474  *  \param [in] f1 - a field to include in the result field.
2475  *  \param [in] f2 - another field to include in the result field.
2476  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2477  *          The caller is to delete this result field using decrRef() as it is no more
2478  *          needed.
2479  *  \throw If the fields are not compatible for a meld (areCompatibleForMeld()).
2480  *  \throw If any of data arrays is not allocated.
2481  *  \throw If \a f1->getNumberOfTuples() != \a f2->getNumberOfTuples()
2482  */
2483 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2484 {
2485   if(!f1 || !f2)
2486     throw INTERP_KERNEL::Exception("MeldFields : null input pointer !");
2487   if(!f1->areCompatibleForMeld(f2))
2488     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
2489   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->meld(f2->timeDiscr()));
2490   td->copyTinyAttrFrom(*f1->timeDiscr());
2491   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2492   ret->setMesh(f1->getMesh());
2493   return ret.retn();
2494 }
2495
2496 /*!
2497  * Returns a new MEDCouplingFieldDouble containing a dot product of two given fields, 
2498  * so that the i-th tuple of the result field is a sum of products of j-th components of
2499  * i-th tuples of given fields (\f$ f_i = \sum_{j=1}^n f1_j * f2_j \f$). 
2500  * Number of tuples and components in the given fields must be the same.
2501  *  \param [in] f1 - a given field.
2502  *  \param [in] f2 - another given field.
2503  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2504  *          The caller is to delete this result field using decrRef() as it is no more
2505  *          needed.
2506  *  \throw If either \a f1 or \a f2 is NULL.
2507  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2508  *         differ not only in values.
2509  */
2510 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2511 {
2512   if(!f1)
2513     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !");
2514   if(!f1->areStrictlyCompatibleForMulDiv(f2))
2515     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them!  Check support mesh, and spatial and time discretisation.");
2516   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->dot(f2->timeDiscr()));
2517   td->copyTinyAttrFrom(*f1->timeDiscr());
2518   MEDCouplingFieldDouble *ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2519   ret->setMesh(f1->getMesh());
2520   return ret;
2521 }
2522
2523 /*!
2524  * Returns a new MEDCouplingFieldDouble containing a cross product of two given fields, 
2525  * so that
2526  * the i-th tuple of the result field is a 3D vector which is a cross
2527  * product of two vectors defined by the i-th tuples of given fields.
2528  * Number of tuples in the given fields must be the same.
2529  * Number of components in the given fields must be 3.
2530  *  \param [in] f1 - a given field.
2531  *  \param [in] f2 - another given field.
2532  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2533  *          The caller is to delete this result field using decrRef() as it is no more
2534  *          needed.
2535  *  \throw If either \a f1 or \a f2 is NULL.
2536  *  \throw If \a f1->getNumberOfComponents() != 3
2537  *  \throw If \a f2->getNumberOfComponents() != 3
2538  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2539  *         differ not only in values.
2540  */
2541 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2542 {
2543   if(!f1)
2544     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !");
2545   if(!f1->areStrictlyCompatibleForMulDiv(f2))
2546     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation.");
2547   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->crossProduct(f2->timeDiscr()));
2548   td->copyTinyAttrFrom(*f1->timeDiscr());
2549   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2550   ret->setMesh(f1->getMesh());
2551   return ret.retn();
2552 }
2553
2554 /*!
2555  * Returns a new MEDCouplingFieldDouble containing maximal values of two given fields.
2556  * Number of tuples and components in the given fields must be the same.
2557  *  \param [in] f1 - a field to compare values with another one.
2558  *  \param [in] f2 - another field to compare values with the first one.
2559  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2560  *          The caller is to delete this result field using decrRef() as it is no more
2561  *          needed.
2562  *  \throw If either \a f1 or \a f2 is NULL.
2563  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2564  *         differ not only in values.
2565  *
2566  *  \if ENABLE_EXAMPLES
2567  *  \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2568  *  \ref  py_mcfielddouble_MaxFields "Here is a Python example".
2569  *  \endif
2570  */
2571 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2572 {
2573   if(!f1)
2574     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MaxFields : input field is NULL !");
2575   if(!f1->areStrictlyCompatible(f2))
2576     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MaxFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2577   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->max(f2->timeDiscr()));
2578   td->copyTinyAttrFrom(*f1->timeDiscr());
2579   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2580   ret->setMesh(f1->getMesh());
2581   return ret.retn();
2582 }
2583
2584 /*!
2585  * Returns a new MEDCouplingFieldDouble containing minimal values of two given fields.
2586  * Number of tuples and components in the given fields must be the same.
2587  *  \param [in] f1 - a field to compare values with another one.
2588  *  \param [in] f2 - another field to compare values with the first one.
2589  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2590  *          The caller is to delete this result field using decrRef() as it is no more
2591  *          needed.
2592  *  \throw If either \a f1 or \a f2 is NULL.
2593  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2594  *         differ not only in values.
2595  *
2596  *  \if ENABLE_EXAMPLES
2597  *  \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2598  *  \ref  py_mcfielddouble_MaxFields "Here is a Python example".
2599  *  \endif
2600  */
2601 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2602 {
2603   if(!f1)
2604     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MinFields : input field is NULL !");
2605   if(!f1->areStrictlyCompatible(f2))
2606     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MinFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2607   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->min(f2->timeDiscr()));
2608   td->copyTinyAttrFrom(*f1->timeDiscr());
2609   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2610   ret->setMesh(f1->getMesh());
2611   return ret.retn();
2612 }
2613
2614 /*!
2615  * Returns a copy of \a this field in which sign of all values is reversed.
2616  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble
2617  *         containing the same number of tuples and components as \a this field. 
2618  *         The caller is to delete this result field using decrRef() as it is no more
2619  *         needed. 
2620  *  \throw If the spatial discretization of \a this field is NULL.
2621  *  \throw If a data array is not allocated.
2622  */
2623 MEDCouplingFieldDouble *MEDCouplingFieldDouble::negate() const
2624 {
2625   if(_type.isNull())
2626     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform negate !");
2627   MEDCouplingTimeDiscretization *td(timeDiscr()->negate());
2628   td->copyTinyAttrFrom(*timeDiscr());
2629   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2630   ret->setMesh(getMesh());
2631   return ret.retn();
2632 }
2633
2634 /*!
2635  * Returns a new MEDCouplingFieldDouble containing sum values of corresponding values of
2636  * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] + _f2_ [ i, j ] ).
2637  * Number of tuples and components in the given fields must be the same.
2638  *  \param [in] f1 - a field to sum up.
2639  *  \param [in] f2 - another field to sum up.
2640  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2641  *          The caller is to delete this result field using decrRef() as it is no more
2642  *          needed.
2643  *  \throw If either \a f1 or \a f2 is NULL.
2644  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2645  *         differ not only in values.
2646  */
2647 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2648 {
2649   if(!f1)
2650     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::AddFields : input field is NULL !");
2651   if(!f1->areStrictlyCompatible(f2))
2652     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply AddFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2653   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->add(f2->timeDiscr()));
2654   td->copyTinyAttrFrom(*f1->timeDiscr());
2655   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2656   ret->setMesh(f1->getMesh());
2657   return ret.retn();
2658 }
2659
2660 /*!
2661  * Adds values of another MEDCouplingFieldDouble to values of \a this one
2662  * ( _this_ [ i, j ] += _other_ [ i, j ] ) using DataArrayDouble::addEqual().
2663  * The two fields must have same number of tuples, components and same underlying mesh.
2664  *  \param [in] other - the field to add to \a this one.
2665  *  \return const MEDCouplingFieldDouble & - a reference to \a this field.
2666  *  \throw If \a other is NULL.
2667  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2668  *         differ not only in values.
2669  */
2670 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other)
2671 {
2672   if(!areStrictlyCompatible(&other))
2673     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply += on them! Check support mesh, field nature, and spatial and time discretisation.");
2674   timeDiscr()->addEqual(other.timeDiscr());
2675   return *this;
2676 }
2677
2678 /*!
2679  * Returns a new MEDCouplingFieldDouble containing subtraction of corresponding values of
2680  * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] - _f2_ [ i, j ] ).
2681  * Number of tuples and components in the given fields must be the same.
2682  *  \param [in] f1 - a field to subtract from.
2683  *  \param [in] f2 - a field to subtract.
2684  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2685  *          The caller is to delete this result field using decrRef() as it is no more
2686  *          needed.
2687  *  \throw If either \a f1 or \a f2 is NULL.
2688  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2689  *         differ not only in values.
2690  */
2691 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2692 {
2693   if(!f1)
2694     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::SubstractFields : input field is NULL !");
2695   if(!f1->areStrictlyCompatible(f2))
2696     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply SubstractFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2697   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->substract(f2->timeDiscr()));
2698   td->copyTinyAttrFrom(*f1->timeDiscr());
2699   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2700   ret->setMesh(f1->getMesh());
2701   return ret.retn();
2702 }
2703
2704 /*!
2705  * Subtract values of another MEDCouplingFieldDouble from values of \a this one
2706  * ( _this_ [ i, j ] -= _other_ [ i, j ] ) using DataArrayDouble::substractEqual().
2707  * The two fields must have same number of tuples, components and same underlying mesh.
2708  *  \param [in] other - the field to subtract from \a this one.
2709  *  \return const MEDCouplingFieldDouble & - a reference to \a this field.
2710  *  \throw If \a other is NULL.
2711  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2712  *         differ not only in values.
2713  */
2714 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other)
2715 {
2716   if(!areStrictlyCompatible(&other))
2717     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply -= on them! Check support mesh, field nature, and spatial and time discretisation.");
2718   timeDiscr()->substractEqual(other.timeDiscr());
2719   return *this;
2720 }
2721
2722 /*!
2723  * Returns a new MEDCouplingFieldDouble containing product values of
2724  * two given fields. There are 2 valid cases.
2725  * 1.  The fields have same number of tuples and components. Then each value of
2726  *   the result field (_f_) is a product of the corresponding values of _f1_ and
2727  *   _f2_, i.e. _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, j ].
2728  * 2.  The fields have same number of tuples and one field, say _f2_, has one
2729  *   component. Then
2730  *   _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, 0 ].
2731  *
2732  * The two fields must have same number of tuples and same underlying mesh.
2733  *  \param [in] f1 - a factor field.
2734  *  \param [in] f2 - another factor field.
2735  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2736  *          The caller is to delete this result field using decrRef() as it is no more
2737  *          needed.
2738  *  \throw If either \a f1 or \a f2 is NULL.
2739  *  \throw If the fields are not compatible for multiplication (areCompatibleForMul()),
2740  *         i.e. they differ not only in values and possibly number of components.
2741  */
2742 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2743 {
2744   if(!f1)
2745     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MultiplyFields : input field is NULL !");
2746   if(!f1->areCompatibleForMul(f2))
2747     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MultiplyFields on them! Check support mesh, and spatial and time discretisation.");
2748   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->multiply(f2->timeDiscr()));
2749   td->copyTinyAttrFrom(*f1->timeDiscr());
2750   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2751   ret->setMesh(f1->getMesh());
2752   return ret.retn();
2753 }
2754
2755 /*!
2756  * Multiply values of another MEDCouplingFieldDouble to values of \a this one
2757  * using DataArrayDouble::multiplyEqual().
2758  * The two fields must have same number of tuples and same underlying mesh.
2759  * There are 2 valid cases.
2760  * 1.  The fields have same number of components. Then each value of
2761  *   \a other is multiplied to the corresponding value of \a this field, i.e.
2762  *   _this_ [ i, j ] *= _other_ [ i, j ].
2763  * 2. The _other_ field has one component. Then
2764  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
2765  *
2766  * The two fields must have same number of tuples and same underlying mesh.
2767  *  \param [in] other - an field to multiply to \a this one.
2768  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2769  *          The caller is to delete this result field using decrRef() as it is no more
2770  *          needed.
2771  *  \throw If \a other is NULL.
2772  *  \throw If the fields are not strictly compatible for multiplication
2773  *         (areCompatibleForMul()),
2774  *         i.e. they differ not only in values and possibly in number of components.
2775  */
2776 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other)
2777 {
2778   if(!areCompatibleForMul(&other))
2779     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply *= on them! Check support mesh, and spatial and time discretisation.");
2780   timeDiscr()->multiplyEqual(other.timeDiscr());
2781   _nature = NoNature;
2782   return *this;
2783 }
2784
2785 /*!
2786  * Returns a new MEDCouplingFieldDouble containing division of two given fields.
2787  * There are 2 valid cases.
2788  * 1.  The fields have same number of tuples and components. Then each value of
2789  *   the result field (_f_) is a division of the corresponding values of \a f1 and
2790  *   \a f2, i.e. _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, j ].
2791  * 2.  The fields have same number of tuples and _f2_ has one component. Then
2792  *   _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, 0 ].
2793  *
2794  *  \param [in] f1 - a numerator field.
2795  *  \param [in] f2 - a denominator field.
2796  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2797  *          The caller is to delete this result field using decrRef() as it is no more
2798  *          needed.
2799  *  \throw If either \a f1 or \a f2 is NULL.
2800  *  \throw If the fields are not compatible for division (areCompatibleForDiv()),
2801  *         i.e. they differ not only in values and possibly in number of components.
2802  */
2803 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2804 {
2805   if(!f1)
2806     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DivideFields : input field is NULL !");
2807   if(!f1->areCompatibleForDiv(f2))
2808     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DivideFields on them! Check support mesh, and spatial and time discretisation.");
2809   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->divide(f2->timeDiscr()));
2810   td->copyTinyAttrFrom(*f1->timeDiscr());
2811   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2812   ret->setMesh(f1->getMesh());
2813   return ret.retn();
2814 }
2815
2816 /*!
2817  * Divide values of \a this field by values of another MEDCouplingFieldDouble
2818  * using DataArrayDouble::divideEqual().
2819  * The two fields must have same number of tuples and same underlying mesh.
2820  * There are 2 valid cases.
2821  * 1.  The fields have same number of components. Then each value of
2822  *    \a this field is divided by the corresponding value of \a other one, i.e.
2823  *   _this_ [ i, j ] /= _other_ [ i, j ].
2824  * 2.  The \a other field has one component. Then
2825  *   _this_ [ i, j ] /= _other_ [ i, 0 ].
2826  *
2827  *  \warning No check of division by zero is performed!
2828  *  \param [in] other - an field to divide \a this one by.
2829  *  \throw If \a other is NULL.
2830  *  \throw If the fields are not compatible for division (areCompatibleForDiv()),
2831  *         i.e. they differ not only in values and possibly in number of components.
2832  */
2833 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other)
2834 {
2835   if(!areCompatibleForDiv(&other))
2836     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply /= on them! Check support mesh, and spatial and time discretisation.");
2837   timeDiscr()->divideEqual(other.timeDiscr());
2838   _nature = NoNature;
2839   return *this;
2840 }
2841
2842 /*!
2843  * Directly called by MEDCouplingFieldDouble::operator^.
2844  * 
2845  * \sa MEDCouplingFieldDouble::operator^
2846  */
2847 MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2848 {
2849   if(!f1)
2850     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::PowFields : input field is NULL !");
2851   if(!f1->areCompatibleForMul(f2))
2852     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply PowFields on them! Check support mesh, and spatial and time discretisation.");
2853   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->pow(f2->timeDiscr()));
2854   td->copyTinyAttrFrom(*f1->timeDiscr());
2855   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2856   ret->setMesh(f1->getMesh());
2857   return ret.retn();
2858 }
2859
2860 /*!
2861  * Directly call MEDCouplingFieldDouble::PowFields static method.
2862  * 
2863  * \sa MEDCouplingFieldDouble::PowFields
2864  */
2865 MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const
2866 {
2867   return PowFields(this,&other);
2868 }
2869
2870 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other)
2871 {
2872   if(!areCompatibleForDiv(&other))
2873     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply ^= on them!  Check support mesh, and spatial and time discretisation.");
2874   timeDiscr()->powEqual(other.timeDiscr());
2875   _nature = NoNature;
2876   return *this;
2877 }
2878
2879 /*!
2880  * Writes the field series \a fs and the mesh the fields lie on in the VTK file \a fileName.
2881  * If \a fs is empty no file is written.
2882  * The result file is valid provided that no exception is thrown.
2883  * \warning All the fields must be named and lie on the same non NULL mesh.
2884  *  \param [in] fileName - the name of a VTK file to write in.
2885  *  \param [in] fs - the fields to write.
2886  *  \param [in] isBinary - specifies the VTK format of the written file. By default true (Binary mode)
2887  *  \throw If \a fs[ 0 ] == NULL.
2888  *  \throw If the fields lie not on the same mesh.
2889  *  \throw If the mesh is not set.
2890  *  \throw If any of the fields has no name.
2891  *
2892  *  \if ENABLE_EXAMPLES
2893  *  \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".<br>
2894  *  \ref  py_mcfielddouble_WriteVTK "Here is a Python example".
2895  *  \endif
2896  */
2897 std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector<const MEDCouplingFieldDouble *>& fs, bool isBinary)
2898 {
2899   if(fs.empty())
2900     return std::string();
2901   std::size_t nfs=fs.size();
2902   if(!fs[0])
2903     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field is NULL !");
2904   const MEDCouplingMesh *m=fs[0]->getMesh();
2905   if(!m)
2906     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field lies on NULL mesh !");
2907   for(std::size_t i=1;i<nfs;i++)
2908     if(fs[i]->getMesh()!=m)
2909       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.");
2910   if(!m)
2911     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !");
2912   std::string ret(m->getVTKFileNameOf(fileName));
2913   MCAuto<DataArrayByte> byteArr;
2914   if(isBinary)
2915     { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); }
2916   std::ostringstream coss,noss;
2917   for(std::size_t i=0;i<nfs;i++)
2918     {
2919       const MEDCouplingFieldDouble *cur=fs[i];
2920       std::string name(cur->getName());
2921       if(name.empty())
2922         {
2923           std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
2924           throw INTERP_KERNEL::Exception(oss.str());
2925         }
2926       TypeOfField typ=cur->getTypeOfField();
2927       if(typ==ON_CELLS)
2928         cur->getArray()->writeVTK(coss,8,cur->getName(),byteArr);
2929       else if(typ==ON_NODES)
2930         cur->getArray()->writeVTK(noss,8,cur->getName(),byteArr);
2931       else
2932         throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : only node and cell fields supported for the moment !");
2933     }
2934   m->writeVTKAdvanced(ret,coss.str(),noss.str(),byteArr);
2935   return ret;
2936 }
2937
2938 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoizeGen(const Voronizer *vor, double eps) const
2939 {
2940   checkConsistencyLight();
2941   if(!vor)
2942     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoizeGen : null pointer !");
2943   MCAuto<MEDCouplingFieldDouble> fieldToWO;
2944   const MEDCouplingMesh *inpMeshBase(getMesh());
2945   MCAuto<MEDCouplingUMesh> inpMesh(inpMeshBase->buildUnstructured());
2946   std::string meshName(inpMesh->getName());
2947   if(!inpMesh->isPresenceOfQuadratic())
2948     fieldToWO=clone(false);
2949   else
2950     {
2951       fieldToWO=convertQuadraticCellsToLinear();
2952       inpMeshBase=fieldToWO->getMesh();
2953       inpMesh=inpMeshBase->buildUnstructured();
2954     }
2955   int nbCells(inpMesh->getNumberOfCells());
2956   const MEDCouplingFieldDiscretization *disc(fieldToWO->getDiscretization());
2957   const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
2958   if(!disc2)
2959     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : Not a ON_GAUSS_PT field");
2960   int nbLocs(disc2->getNbOfGaussLocalization());
2961   std::vector< MCAuto<MEDCouplingUMesh> > cells(nbCells);
2962   for(int i=0;i<nbLocs;i++)
2963     {
2964       const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(i));
2965       if(gl.getDimension()!=vor->getDimension())
2966         throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : not a 2D one !");
2967       MCAuto<MEDCouplingUMesh> mesh(gl.buildRefCell());
2968       const std::vector<double>& coo(gl.getGaussCoords());
2969       MCAuto<DataArrayDouble> coo2(DataArrayDouble::NewFromStdVector(coo));
2970       coo2->rearrange(vor->getDimension());
2971       //
2972       MCAuto<MEDCouplingUMesh> coo3(MEDCouplingUMesh::Build0DMeshFromCoords(coo2));
2973       //
2974       MCAuto<MEDCouplingUMesh> vorCellsForCurDisc(vor->doIt(mesh,coo2,eps));
2975       std::vector<int> ids;
2976       MCAuto<DataArrayDouble> ptsInReal;
2977       disc2->getCellIdsHavingGaussLocalization(i,ids);
2978       {
2979         MCAuto<MEDCouplingUMesh> subMesh(inpMesh->buildPartOfMySelf(&ids[0],&ids[0]+ids.size()));
2980         ptsInReal=gl.localizePtsInRefCooForEachCell(vorCellsForCurDisc->getCoords(),subMesh);
2981       }
2982       int nbPtsPerCell(vorCellsForCurDisc->getNumberOfNodes());
2983       for(std::size_t i=0;i<ids.size();i++)
2984         {
2985           MCAuto<MEDCouplingUMesh> elt(vorCellsForCurDisc->clone(false));
2986           MCAuto<DataArrayDouble> coo(ptsInReal->selectByTupleIdSafeSlice(i*nbPtsPerCell,(i+1)*nbPtsPerCell,1));
2987           elt->setCoords(coo);
2988           cells[ids[i]]=elt;
2989         }
2990     }
2991   std::vector< const MEDCouplingUMesh * > cellsPtr(VecAutoToVecOfCstPt(cells));
2992   MCAuto<MEDCouplingUMesh> outMesh(MEDCouplingUMesh::MergeUMeshes(cellsPtr));
2993   outMesh->setName(meshName);
2994   MCAuto<MEDCouplingFieldDouble> onCells(MEDCouplingFieldDouble::New(ON_CELLS));
2995   onCells->setMesh(outMesh);
2996   {
2997     MCAuto<DataArrayDouble> arr(fieldToWO->getArray()->deepCopy());
2998     onCells->setArray(arr);
2999   }
3000   onCells->setTimeUnit(getTimeUnit());
3001   {
3002     int b,c;
3003     double a(getTime(b,c));
3004     onCells->setTime(a,b,c);
3005   }
3006   onCells->setName(getName());
3007   return onCells;
3008 }
3009
3010 MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr()
3011 {
3012   MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
3013   if(!ret)
3014     return 0;
3015   MEDCouplingTimeDiscretization *retc(dynamic_cast<MEDCouplingTimeDiscretization *>(ret));
3016   if(!retc)
3017     throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");
3018   return retc;
3019 }
3020
3021 const MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr() const
3022 {
3023   const MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
3024   if(!ret)
3025     return 0;
3026   const MEDCouplingTimeDiscretization *retc(dynamic_cast<const MEDCouplingTimeDiscretization *>(ret));
3027   if(!retc)
3028     throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");
3029   return retc;
3030 }