Salome HOME
Improve swig generation process on Windows platform.
[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 /*!
526  * Builds a newly created field, that the caller will have the responsability to deal with (decrRef()).
527  * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done.
528  * This method returns a restriction of \a this so that only tuples with ids specified in \a part will be contained in the returned field.
529  * Parameter \a part specifies **cell ids whatever the spatial discretization of this** (
530  * \ref MEDCoupling::ON_CELLS "ON_CELLS", 
531  * \ref MEDCoupling::ON_NODES "ON_NODES",
532  * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT", 
533  * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE",
534  * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR").
535  *
536  * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a part contains following cell ids [3,7,6].
537  * Then the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.<br>
538  * Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh().<br>
539  * Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh().<br>
540  * Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh().
541  *
542  * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a part contains following cellIds [3,7,6].
543  * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field
544  * will contain 6 tuples and \a this field will lie on this restricted mesh. 
545  *
546  *  \param [in] part - an array of cell ids to include to the result field.
547  *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The caller is to delete this field using decrRef() as it is no more needed.
548  *
549  *  \if ENABLE_EXAMPLES
550  *  \ref cpp_mcfielddouble_subpart1 "Here is a C++ example".<br>
551  *  \ref  py_mcfielddouble_subpart1 "Here is a Python example".
552  *  \endif
553  *  \sa MEDCouplingFieldDouble::buildSubPartRange
554  */
555
556 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const
557 {
558   if(part==0)
559     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !");
560   return buildSubPart(part->begin(),part->end());
561 }
562
563 /*!
564  * Builds a newly created field, that the caller will have the responsability to deal with.
565  * \n This method makes the assumption that \a this field is correctly defined when this method is called (\a this->checkConsistencyLight() returns without any exception thrown), **no check of this will be done**.
566  * \n This method returns a restriction of \a this so that only tuple ids specified in [ \a partBg , \a partEnd ) will be contained in the returned field.
567  * \n Parameter [\a partBg, \a partEnd ) specifies **cell ids whatever the spatial discretization** of \a this (
568  * \ref MEDCoupling::ON_CELLS "ON_CELLS", 
569  * \ref MEDCoupling::ON_NODES "ON_NODES",
570  * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT", 
571  * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE",
572  * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR").
573  *
574  * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a partBg contains the following cell ids [3,7,6].
575  * Then the returned field will lie on mesh having 3 cells and will contain 3 tuples.
576  *- Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh().
577  *- Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh().
578  *- Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh().
579  *
580  * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a partBg contains following cellIds [3,7,6].
581  * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field
582  * will contain 6 tuples and \a this field will lie on this restricted mesh. 
583  *
584  * \param [in] partBg - start (included) of input range of cell ids to select [ \a partBg, \a partEnd )
585  * \param [in] partEnd - end (not included) of input range of cell ids to select [ \a partBg, \a partEnd )
586  * \return a newly allocated field the caller should deal with.
587  * 
588  * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \a this->getMesh().
589  *
590  * \if ENABLE_EXAMPLES
591  * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."<br>
592  * \ref py_mcfielddouble_subpart1 "Here a Python example."
593  * \endif
594  * \sa MEDCoupling::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange
595  */
596 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const
597 {
598   if(_type.isNull())
599     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !");
600   DataArrayInt *arrSelect;
601   MCAuto<MEDCouplingMesh> m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect);
602   MCAuto<DataArrayInt> arrSelect2(arrSelect);
603   MCAuto<MEDCouplingFieldDouble> ret(clone(false));//quick shallow copy.
604   const MEDCouplingFieldDiscretization *disc=getDiscretization();
605   if(disc)
606     ret->setDiscretization(MCAuto<MEDCouplingFieldDiscretization>(disc->clonePart(partBg,partEnd)));
607   ret->setMesh(m);
608   std::vector<DataArrayDouble *> arrays;
609   timeDiscr()->getArrays(arrays);
610   std::vector<DataArrayDouble *> arrs;
611   std::vector< MCAuto<DataArrayDouble> > arrsSafe;
612   const int *arrSelBg=arrSelect->begin();
613   const int *arrSelEnd=arrSelect->end();
614   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
615     {
616       DataArrayDouble *arr=0;
617       if(*iter)
618         arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd);
619       arrs.push_back(arr); arrsSafe.push_back(arr);
620     }
621   ret->timeDiscr()->setArrays(arrs,0);
622   return ret.retn();
623 }
624
625 /*!
626  * This method is equivalent to MEDCouplingFieldDouble::buildSubPart, the only difference is that the input range of cell ids is
627  * given using a range given \a begin, \a end and \a step to optimize the part computation.
628  * 
629  * \sa MEDCouplingFieldDouble::buildSubPart
630  */
631 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPartRange(int begin, int end, int step) const
632 {
633   if(_type.isNull())
634     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !");
635   DataArrayInt *arrSelect;
636   int beginOut,endOut,stepOut;
637   MCAuto<MEDCouplingMesh> m(_type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,arrSelect));
638   MCAuto<DataArrayInt> arrSelect2(arrSelect);
639   MCAuto<MEDCouplingFieldDouble> ret(clone(false));//quick shallow copy.
640   const MEDCouplingFieldDiscretization *disc=getDiscretization();
641   if(disc)
642     ret->setDiscretization(MCAuto<MEDCouplingFieldDiscretization>(disc->clonePartRange(begin,end,step)));
643   ret->setMesh(m);
644   std::vector<DataArrayDouble *> arrays;
645   timeDiscr()->getArrays(arrays);
646   std::vector<DataArrayDouble *> arrs;
647   std::vector< MCAuto<DataArrayDouble> > arrsSafe;
648   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
649     {
650       DataArrayDouble *arr=0;
651       if(*iter)
652         {
653           if(arrSelect)
654             {
655               const int *arrSelBg=arrSelect->begin();
656               const int *arrSelEnd=arrSelect->end();
657               arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd);
658             }
659           else
660             arr=(*iter)->selectByTupleIdSafeSlice(beginOut,endOut,stepOut);
661         }
662       arrs.push_back(arr); arrsSafe.push_back(arr);
663     }
664   ret->timeDiscr()->setArrays(arrs,0);
665   return ret.retn();
666 }
667
668 MEDCouplingFieldInt *MEDCouplingFieldDouble::convertToIntField() const
669 {
670   MCAuto<MEDCouplingFieldTemplate> tmp(MEDCouplingFieldTemplate::New(*this));
671   int t1,t2;
672   double t0(getTime(t1,t2));
673   MCAuto<MEDCouplingFieldInt> ret(MEDCouplingFieldInt::New(*tmp,getTimeDiscretization()));
674   ret->setTime(t0,t1,t2);
675   if(getArray())
676     {
677       MCAuto<DataArrayInt> arr(getArray()->convertToIntArr());
678       ret->setArray(arr);
679     }
680   return ret.retn();
681 }
682
683 MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(type,MEDCouplingTimeDiscretization::New(td))
684 {
685 }
686
687 /*!
688  * ** WARINING : This method do not deeply copy neither mesh nor spatial discretization. Only a shallow copy (reference) is done for mesh and spatial discretization ! **
689  */
690 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(ft,MEDCouplingTimeDiscretization::New(td),false)
691 {
692 }
693
694 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingFieldT<double>(other,deepCopy)
695 {
696 }
697
698 MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingFieldT<double>(type,n,td)
699 {
700 }
701
702 /*!
703  * Accumulate values of a given component of \a this field.
704  *  \param [in] compId - the index of the component of interest.
705  *  \return double - a sum value of *compId*-th component.
706  *  \throw If the data array is not set.
707  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
708  *         not respected.
709  */
710 double MEDCouplingFieldDouble::accumulate(int compId) const
711 {
712   if(getArray()==0)
713     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
714   return getArray()->accumulate(compId);
715 }
716
717 /*!
718  * Accumulates values of each component of \a this array.
719  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
720  *         by the caller, that is filled by this method with sum value for each
721  *         component.
722  *  \throw If the data array is not set.
723  */
724 void MEDCouplingFieldDouble::accumulate(double *res) const
725 {
726   if(getArray()==0)
727     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
728   getArray()->accumulate(res);
729 }
730
731 /*!
732  * Returns the maximal value within \a this scalar field. Values of all arrays stored
733  * in \a this->_time_discr are checked.
734  *  \return double - the maximal value among all values of \a this field.
735  *  \throw If \a this->getNumberOfComponents() != 1
736  *  \throw If the data array is not set.
737  *  \throw If there is an empty data array in \a this field.
738  */
739 double MEDCouplingFieldDouble::getMaxValue() const
740 {
741   std::vector<DataArrayDouble *> arrays;
742   timeDiscr()->getArrays(arrays);
743   double ret(-std::numeric_limits<double>::max());
744   bool isExistingArr=false;
745   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
746     {
747       if(*iter)
748         {
749           isExistingArr=true;
750           int loc;
751           ret=std::max(ret,(*iter)->getMaxValue(loc));
752         }
753     }
754   if(!isExistingArr)
755     throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !");
756   return ret;
757 }
758
759 /*!
760  * Returns the maximal value and all its locations within \a this scalar field.
761  * Only the first of available data arrays is checked.
762  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
763  *               tuples holding the maximal value. The caller is to delete it using
764  *               decrRef() as it is no more needed.
765  *  \return double - the maximal value among all values of the first array of \a this filed.
766  *  \throw If \a this->getNumberOfComponents() != 1.
767  *  \throw If there is an empty data array in \a this field.
768  */
769 double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const
770 {
771   std::vector<DataArrayDouble *> arrays;
772   timeDiscr()->getArrays(arrays);
773   double ret(-std::numeric_limits<double>::max());
774   bool isExistingArr=false;
775   tupleIds=0;
776   MCAuto<DataArrayInt> ret1;
777   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
778     {
779       if(*iter)
780         {
781           isExistingArr=true;
782           DataArrayInt *tmp;
783           ret=std::max(ret,(*iter)->getMaxValue2(tmp));
784           MCAuto<DataArrayInt> tmpSafe(tmp);
785           if(!((const DataArrayInt *)ret1))
786             ret1=tmpSafe;
787         }
788     }
789   if(!isExistingArr)
790     throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !");
791   tupleIds=ret1.retn();
792   return ret;
793 }
794
795 /*!
796  * Returns the minimal value within \a this scalar field. Values of all arrays stored
797  * in \a this->_time_discr are checked.
798  *  \return double - the minimal value among all values of \a this field.
799  *  \throw If \a this->getNumberOfComponents() != 1
800  *  \throw If the data array is not set.
801  *  \throw If there is an empty data array in \a this field.
802  */
803 double MEDCouplingFieldDouble::getMinValue() const
804 {
805   std::vector<DataArrayDouble *> arrays;
806   timeDiscr()->getArrays(arrays);
807   double ret(std::numeric_limits<double>::max());
808   bool isExistingArr=false;
809   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
810     {
811       if(*iter)
812         {
813           isExistingArr=true;
814           int loc;
815           ret=std::min(ret,(*iter)->getMinValue(loc));
816         }
817     }
818   if(!isExistingArr)
819     throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !");
820   return ret;
821 }
822
823 /*!
824  * Returns the minimal value and all its locations within \a this scalar field.
825  * Only the first of available data arrays is checked.
826  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
827  *               tuples holding the minimal value. The caller is to delete it using
828  *               decrRef() as it is no more needed.
829  *  \return double - the minimal value among all values of the first array of \a this filed.
830  *  \throw If \a this->getNumberOfComponents() != 1.
831  *  \throw If there is an empty data array in \a this field.
832  */
833 double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const
834 {
835   std::vector<DataArrayDouble *> arrays;
836   timeDiscr()->getArrays(arrays);
837   double ret(-std::numeric_limits<double>::max());
838   bool isExistingArr=false;
839   tupleIds=0;
840   MCAuto<DataArrayInt> ret1;
841   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
842     {
843       if(*iter)
844         {
845           isExistingArr=true;
846           DataArrayInt *tmp;
847           ret=std::max(ret,(*iter)->getMinValue2(tmp));
848           MCAuto<DataArrayInt> tmpSafe(tmp);
849           if(!((const DataArrayInt *)ret1))
850             ret1=tmpSafe;
851         }
852     }
853   if(!isExistingArr)
854     throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !");
855   tupleIds=ret1.retn();
856   return ret;
857 }
858
859 /*!
860  * Returns the average value of \a this scalar field.
861  *  \return double - the average value over all values of the data array.
862  *  \throw If \a this->getNumberOfComponents() != 1
863  *  \throw If the data array is not set or it is empty.
864  */
865 double MEDCouplingFieldDouble::getAverageValue() const
866 {
867   if(getArray()==0)
868     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !");
869   return getArray()->getAverageValue();
870 }
871
872 /*!
873  * This method returns the euclidean norm of \a this field.
874  * \f[
875  * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]}
876  * \f]
877  *  \throw If the data array is not set.
878  */
879 double MEDCouplingFieldDouble::norm2() const
880 {
881   if(getArray()==0)
882     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !");
883   return getArray()->norm2();
884 }
885
886 /*!
887  * This method returns the max norm of \a this field.
888  * \f[
889  * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
890  * \f]
891  *  \throw If the data array is not set.
892  */
893 double MEDCouplingFieldDouble::normMax() const
894 {
895   if(getArray()==0)
896     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
897   return getArray()->normMax();
898 }
899
900 /*!
901  * Computes the weighted average of values of each component of \a this field, the weights being the
902  * values returned by buildMeasureField().  
903  *  \param [out] res - pointer to an array of result sum values, of size at least \a
904  *         this->getNumberOfComponents(), that is to be allocated by the caller.
905  *  \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by
906  *         buildMeasureField(). It makes this method slower. If you are sure that all
907  *         the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs ==
908  *         \c false to speed up the method.
909  *  \throw If the mesh is not set.
910  *  \throw If the data array is not set.
911  */
912 void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const
913 {
914   if(getArray()==0)
915     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
916   MCAuto<MEDCouplingFieldDouble> w=buildMeasureField(isWAbs);
917   double deno=w->getArray()->accumulate(0);
918   MCAuto<DataArrayDouble> arr=getArray()->deepCopy();
919   arr->multiplyEqual(w->getArray());
920   arr->accumulate(res);
921   int nCompo = getArray()->getNumberOfComponents();
922   std::transform(res,res+nCompo,res,std::bind2nd(std::multiplies<double>(),1./deno));
923 }
924
925 /*!
926  * Computes the weighted average of values of a given component of \a this field, the weights being the
927  * values returned by buildMeasureField().
928  *  \param [in] compId - an index of the component of interest.
929  *  \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by
930  *         buildMeasureField(). It makes this method slower. If you are sure that all
931  *         the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs ==
932  *         \c false to speed up the method.
933  *  \throw If the mesh is not set.
934  *  \throw If the data array is not set.
935  *  \throw If \a compId is not valid.
936            A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
937  */
938 double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const
939 {
940   int nbComps=getArray()->getNumberOfComponents();
941   if(compId<0 || compId>=nbComps)
942     {
943       std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
944       throw INTERP_KERNEL::Exception(oss.str());
945     }
946   INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
947   getWeightedAverageValue(res,isWAbs);
948   return res[compId];
949 }
950
951 /*!
952  * Returns the \c normL1 of values of a given component of \a this field:
953  * \f[
954  * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
955  * \f]
956  *  \param [in] compId - an index of the component of interest.
957  *  \throw If the mesh is not set.
958  *  \throw If the spatial discretization of \a this field is NULL.
959  *  \throw If \a compId is not valid.
960            A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
961  */
962 double MEDCouplingFieldDouble::normL1(int compId) const
963 {
964   if(!_mesh)
965     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1 !");
966   if(_type.isNull())
967     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
968   int nbComps=getArray()->getNumberOfComponents();
969   if(compId<0 || compId>=nbComps)
970     {
971       std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
972       throw INTERP_KERNEL::Exception(oss.str());
973     }
974   INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
975   _type->normL1(_mesh,getArray(),res);
976   return res[compId];
977 }
978
979 /*!
980  * Returns the \c normL1 of values of each component of \a this field:
981  * \f[
982  * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
983  * \f]
984  *  \param [out] res - pointer to an array of result values, of size at least \a
985  *         this->getNumberOfComponents(), that is to be allocated by the caller.
986  *  \throw If the mesh is not set.
987  *  \throw If the spatial discretization of \a this field is NULL.
988  */
989 void MEDCouplingFieldDouble::normL1(double *res) const
990 {
991   if(!_mesh)
992     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
993   if(_type.isNull())
994     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
995   _type->normL1(_mesh,getArray(),res);
996 }
997
998 /*!
999  * Returns the \c normL2 of values of a given component of \a this field:
1000  * \f[
1001  * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
1002  * \f]
1003  *  \param [in] compId - an index of the component of interest.
1004  *  \throw If the mesh is not set.
1005  *  \throw If the spatial discretization of \a this field is NULL.
1006  *  \throw If \a compId is not valid.
1007            A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
1008  */
1009 double MEDCouplingFieldDouble::normL2(int compId) const
1010 {
1011   if(!_mesh)
1012     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
1013   if(_type.isNull())
1014     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
1015   int nbComps=getArray()->getNumberOfComponents();
1016   if(compId<0 || compId>=nbComps)
1017     {
1018       std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
1019       throw INTERP_KERNEL::Exception(oss.str());
1020     }
1021   INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
1022   _type->normL2(_mesh,getArray(),res);
1023   return res[compId];
1024 }
1025
1026 /*!
1027  * Returns the \c normL2 of values of each component of \a this field:
1028  * \f[
1029  * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
1030  * \f]
1031  *  \param [out] res - pointer to an array of result values, of size at least \a
1032  *         this->getNumberOfComponents(), that is to be allocated by the caller.
1033  *  \throw If the mesh is not set.
1034  *  \throw If the spatial discretization of \a this field is NULL.
1035  */
1036 void MEDCouplingFieldDouble::normL2(double *res) const
1037 {
1038   if(!_mesh)
1039     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
1040   if(_type.isNull())
1041     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
1042   _type->normL2(_mesh,getArray(),res);
1043 }
1044
1045 /*!
1046  * Computes a sum of values of a given component of \a this field multiplied by
1047  * values returned by buildMeasureField().
1048  * This method is useful to check the conservativity of interpolation method.
1049  *  \param [in] compId - an index of the component of interest.
1050  *  \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by
1051  *         buildMeasureField() that makes this method slower. If a user is sure that all
1052  *         cells of the underlying mesh have correct orientation, he can put \a isWAbs ==
1053  *         \c false that speeds up this method.
1054  *  \throw If the mesh is not set.
1055  *  \throw If the data array is not set.
1056  *  \throw If \a compId is not valid.
1057            A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
1058  */
1059 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const
1060 {
1061   if(!_mesh)
1062     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
1063   if(_type.isNull())
1064     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral !");
1065   int nbComps=getArray()->getNumberOfComponents();
1066   if(compId<0 || compId>=nbComps)
1067     {
1068       std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
1069       throw INTERP_KERNEL::Exception(oss.str());
1070     }
1071   INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
1072   _type->integral(_mesh,getArray(),isWAbs,res);
1073   return res[compId];
1074 }
1075
1076 /*!
1077  * Computes a sum of values of each component of \a this field multiplied by
1078  * values returned by buildMeasureField().
1079  * This method is useful to check the conservativity of interpolation method.
1080  *  \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by
1081  *         buildMeasureField() that makes this method slower. If a user is sure that all
1082  *         cells of the underlying mesh have correct orientation, he can put \a isWAbs ==
1083  *         \c false that speeds up this method.
1084  *  \param [out] res - pointer to an array of result sum values, of size at least \a
1085  *         this->getNumberOfComponents(), that is to be allocated by the caller.
1086  *  \throw If the mesh is not set.
1087  *  \throw If the data array is not set.
1088  *  \throw If the spatial discretization of \a this field is NULL.
1089  */
1090 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const
1091 {
1092   if(!_mesh)
1093     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
1094   if(_type.isNull())
1095     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral2 !");
1096   _type->integral(_mesh,getArray(),isWAbs,res);
1097 }
1098
1099 /*!
1100  * Returns a value at a given cell of a structured mesh. The cell is specified by its
1101  * (i,j,k) index.
1102  *  \param [in] i - a index of node coordinates array along X axis. The cell is
1103  *         located between the i-th and ( i + 1 )-th nodes along X axis.
1104  *  \param [in] j - a index of node coordinates array along Y axis. The cell is
1105  *         located between the j-th and ( j + 1 )-th nodes along Y axis.
1106  *  \param [in] k - a index of node coordinates array along Z axis. The cell is
1107  *         located between the k-th and ( k + 1 )-th nodes along Z axis.
1108  *  \param [out] res - pointer to an array returning a feild value, of size at least
1109  *         \a this->getNumberOfComponents(), that is to be allocated by the caller.
1110  *  \throw If the spatial discretization of \a this field is NULL.
1111  *  \throw If the mesh is not set.
1112  *  \throw If the mesh is not a structured one.
1113  *
1114  *  \if ENABLE_EXAMPLES
1115  *  \ref cpp_mcfielddouble_getValueOnPos "Here is a C++ example".<br>
1116  *  \ref  py_mcfielddouble_getValueOnPos "Here is a Python example".
1117  *  \endif
1118  */
1119 void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const
1120 {
1121   const DataArrayDouble *arr=timeDiscr()->getArray();
1122   if(!_mesh)
1123     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
1124   if(_type.isNull())
1125     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
1126   _type->getValueOnPos(arr,_mesh,i,j,k,res);
1127 }
1128
1129 /*!
1130  * Returns a value of \a this at a given point using spatial discretization.
1131  *  \param [in] spaceLoc - the point of interest.
1132  *  \param [out] res - pointer to an array returning a feild value, of size at least
1133  *         \a this->getNumberOfComponents(), that is to be allocated by the caller.
1134  *  \throw If the spatial discretization of \a this field is NULL.
1135  *  \throw If the mesh is not set.
1136  *  \throw If \a spaceLoc is out of the spatial discretization.
1137  *
1138  *  \if ENABLE_EXAMPLES
1139  *  \ref cpp_mcfielddouble_getValueOn "Here is a C++ example".<br>
1140  *  \ref  py_mcfielddouble_getValueOn "Here is a Python example".
1141  *  \endif
1142  */
1143 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const
1144 {
1145   const DataArrayDouble *arr=timeDiscr()->getArray();
1146   if(!_mesh)
1147     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
1148   if(_type.isNull())
1149     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
1150   _type->getValueOn(arr,_mesh,spaceLoc,res);
1151 }
1152
1153 /*!
1154  * Returns values of \a this at given points using spatial discretization.
1155  *  \param [in] spaceLoc - coordinates of points of interest in full-interlace
1156  *          mode. This array is to be of size ( \a nbOfPoints * \a this->getNumberOfComponents() ).
1157  *  \param [in] nbOfPoints - number of points of interest.
1158  *  \return DataArrayDouble * - a new instance of DataArrayDouble holding field
1159  *         values relating to the input points. This array is of size \a nbOfPoints
1160  *         tuples per \a this->getNumberOfComponents() components. The caller is to 
1161  *         delete this array using decrRef() as it is no more needed.
1162  *  \throw If the spatial discretization of \a this field is NULL.
1163  *  \throw If the mesh is not set.
1164  *  \throw If any point in \a spaceLoc is out of the spatial discretization.
1165  *
1166  *  \if ENABLE_EXAMPLES
1167  *  \ref cpp_mcfielddouble_getValueOnMulti "Here is a C++ example".<br>
1168  *  \ref  py_mcfielddouble_getValueOnMulti "Here is a Python example".
1169  *  \endif
1170  */
1171 DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const
1172 {
1173   const DataArrayDouble *arr=timeDiscr()->getArray();
1174   if(!_mesh)
1175     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
1176   if(_type.isNull())
1177     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnMulti !");
1178   return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
1179 }
1180
1181 /*!
1182  * Returns a value of \a this field at a given point at a given time using spatial discretization.
1183  * If the time is not covered by \a this->_time_discr, an exception is thrown.
1184  *  \param [in] spaceLoc - the point of interest.
1185  *  \param [in] time - the time of interest.
1186  *  \param [out] res - pointer to an array returning a feild value, of size at least
1187  *         \a this->getNumberOfComponents(), that is to be allocated by the caller.
1188  *  \throw If the spatial discretization of \a this field is NULL.
1189  *  \throw If the mesh is not set.
1190  *  \throw If \a spaceLoc is out of the spatial discretization.
1191  *  \throw If \a time is not covered by \a this->_time_discr.
1192  *
1193  *  \if ENABLE_EXAMPLES
1194  *  \ref cpp_mcfielddouble_getValueOn_time "Here is a C++ example".<br>
1195  *  \ref  py_mcfielddouble_getValueOn_time "Here is a Python example".
1196  *  \endif
1197  */
1198 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const
1199 {
1200   std::vector< const DataArrayDouble *> arrs=timeDiscr()->getArraysForTime(time);
1201   if(!_mesh)
1202     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
1203   if(_type.isNull())
1204     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOn !");
1205   std::vector<double> res2;
1206   for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
1207     {
1208       int sz=(int)res2.size();
1209       res2.resize(sz+(*iter)->getNumberOfComponents());
1210       _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]);
1211     }
1212   timeDiscr()->getValueForTime(time,res2,res);
1213 }
1214
1215 /*!
1216  * Apply a linear function to a given component of \a this field, so that
1217  * a component value <em>(x)</em> becomes \f$ a * x + b \f$.
1218  *  \param [in] a - the first coefficient of the function.
1219  *  \param [in] b - the second coefficient of the function.
1220  *  \param [in] compoId - the index of component to modify.
1221  *  \throw If the data array(s) is(are) not set.
1222  */
1223 void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
1224 {
1225   timeDiscr()->applyLin(a,b,compoId);
1226 }
1227
1228 /*!
1229  * Apply a linear function to all components of \a this field, so that
1230  * values <em>(x)</em> becomes \f$ a * x + b \f$.
1231  *  \param [in] a - the first coefficient of the function.
1232  *  \param [in] b - the second coefficient of the function.
1233  *  \throw If the data array(s) is(are) not set.
1234  */
1235 void MEDCouplingFieldDouble::applyLin(double a, double b)
1236 {
1237   timeDiscr()->applyLin(a,b);
1238 }
1239
1240 /*!
1241  * This method sets \a this to a uniform scalar field with one component.
1242  * All tuples will have the same value 'value'.
1243  * An exception is thrown if no underlying mesh is defined.
1244  */
1245 MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value)
1246 {
1247   if(!_mesh)
1248     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
1249   if(_type.isNull())
1250     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform operator = !");
1251   int nbOfTuple=_type->getNumberOfTuples(_mesh);
1252   timeDiscr()->setOrCreateUniformValueOnAllComponents(nbOfTuple,value);
1253   return *this;
1254 }
1255
1256 /*!
1257  * Creates data array(s) of \a this field by using a C function for value generation.
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 to compute a field value basing on coordinates of value
1261  *         location point.
1262  *  \throw If the mesh is not set.
1263  *  \throw If \a func returns \c false.
1264  *  \throw If the spatial discretization of \a this field is NULL.
1265  *
1266  *  \if ENABLE_EXAMPLES
1267  *  \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example".
1268  *  \endif
1269  */
1270 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func)
1271 {
1272   if(!_mesh)
1273     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1274   if(_type.isNull())
1275     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
1276   MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1277   timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
1278 }
1279
1280 /*!
1281  * Creates data array(s) of \a this field by using a function for value generation.<br>
1282  * The function is applied to coordinates of value location points. For example, if
1283  * \a this field is on cells, the function is applied to cell barycenters.
1284  * For more info on supported expressions that can be used in the function, see \ref
1285  * MEDCouplingArrayApplyFuncExpr. <br>
1286  * The function can include arbitrary named variables
1287  * (e.g. "x","y" or "va44") to refer to components of point coordinates. Names of
1288  * variables are sorted in \b alphabetical \b order to associate a variable name with a
1289  * component. For example, in the expression "2*x+z", "x" stands for the component #0
1290  * and "z" stands for the component #1 (\b not #2)!<br>
1291  * In a general case, a value resulting from the function evaluation is assigned to all
1292  * components of a field value. But there is a possibility to have its own expression for
1293  * each component within one function. For this purpose, there are predefined variable
1294  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1295  * the component #0 etc). A factor of such a variable is added to the
1296  * corresponding component only.<br>
1297  * For example, \a nbOfComp == 4, coordinates of a 3D point are (1.,3.,7.), then
1298  *   - "2*x + z"               produces (5.,5.,5.,5.)
1299  *   - "2*x + 0*y + z"         produces (9.,9.,9.,9.)
1300  *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1301  *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1302  *
1303  *  \param [in] nbOfComp - the number of components for \a this field to have.
1304  *  \param [in] func - the function used to compute values of \a this field.
1305  *         This function is used to compute a field value basing on coordinates of value
1306  *         location point. For example, if \a this field is on cells, the function
1307  *         is applied to cell barycenters.
1308  *  \throw If the mesh is not set.
1309  *  \throw If the spatial discretization of \a this field is NULL.
1310  *  \throw If computing \a func fails.
1311  *
1312  *  \if ENABLE_EXAMPLES
1313  *  \ref cpp_mcfielddouble_fillFromAnalytic "Here is a C++ example".<br>
1314  *  \ref  py_mcfielddouble_fillFromAnalytic "Here is a Python example".
1315  *  \endif
1316  */
1317 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func)
1318 {
1319   if(!_mesh)
1320     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1321   if(_type.isNull())
1322     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
1323   MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1324   timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
1325 }
1326
1327 /*!
1328  * Creates data array(s) of \a this field by using a function for value generation.<br>
1329  * The function is applied to coordinates of value location points. For example, if
1330  * \a this field is on cells, the function is applied to cell barycenters.<br>
1331  * This method differs from
1332  * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()"
1333  * by the way how variable
1334  * names, used in the function, are associated with components of coordinates of field
1335  * location points; here, a variable name corresponding to a component is retrieved from
1336  * a corresponding node coordinates array (where it is set via
1337  * DataArrayDouble::setInfoOnComponent()).<br>
1338  * For more info on supported expressions that can be used in the function, see \ref
1339  * MEDCouplingArrayApplyFuncExpr. <br> 
1340  * In a general case, a value resulting from the function evaluation is assigned to all
1341  * components of a field value. But there is a possibility to have its own expression for
1342  * each component within one function. For this purpose, there are predefined variable
1343  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1344  * the component #0 etc). A factor of such a variable is added to the
1345  * corresponding component only.<br>
1346  * For example, \a nbOfComp == 4, names of spatial components are "x", "y" and "z",
1347  * coordinates of a 3D point are (1.,3.,7.), then
1348  *   - "2*x + z"               produces (9.,9.,9.,9.)
1349  *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1350  *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1351  *
1352  *  \param [in] nbOfComp - the number of components for \a this field to have.
1353  *  \param [in] func - the function used to compute values of \a this field.
1354  *         This function is used to compute a field value basing on coordinates of value
1355  *         location point. For example, if \a this field is on cells, the function
1356  *         is applied to cell barycenters.
1357  *  \throw If the mesh is not set.
1358  *  \throw If the spatial discretization of \a this field is NULL.
1359  *  \throw If computing \a func fails.
1360  *
1361  *  \if ENABLE_EXAMPLES
1362  *  \ref cpp_mcfielddouble_fillFromAnalytic2 "Here is a C++ example".<br>
1363  *  \ref  py_mcfielddouble_fillFromAnalytic2 "Here is a Python example".
1364  *  \endif
1365  */
1366 void MEDCouplingFieldDouble::fillFromAnalyticCompo(int nbOfComp, const std::string& func)
1367 {
1368   if(!_mesh)
1369     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
1370   if(_type.isNull())
1371     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticCompo !");
1372   MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1373   timeDiscr()->fillFromAnalyticCompo(loc,nbOfComp,func);
1374 }
1375
1376 /*!
1377  * Creates data array(s) of \a this field by using a function for value generation.<br>
1378  * The function is applied to coordinates of value location points. For example, if
1379  * \a this field is on cells, the function is applied to cell barycenters.<br>
1380  * This method differs from
1381  * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()"
1382  * by the way how variable
1383  * names, used in the function, are associated with components of coordinates of field
1384  * location points; here, a component index of a variable is defined by a
1385  * rank of the variable within the input array \a varsOrder.<br>
1386  * For more info on supported expressions that can be used in the function, see \ref
1387  * MEDCouplingArrayApplyFuncExpr.
1388  * In a general case, a value resulting from the function evaluation is assigned to all
1389  * components of a field value. But there is a possibility to have its own expression for
1390  * each component within one function. For this purpose, there are predefined variable
1391  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1392  * the component #0 etc). A factor of such a variable is added to the
1393  * corresponding component only.<br>
1394  * For example, \a nbOfComp == 4, names of
1395  * spatial components are given in \a varsOrder: ["x", "y","z"], coordinates of a
1396  * 3D point are (1.,3.,7.), then
1397  *   - "2*x + z"               produces (9.,9.,9.,9.)
1398  *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1399  *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1400  *
1401  *  \param [in] nbOfComp - the number of components for \a this field to have.
1402  *  \param [in] func - the function used to compute values of \a this field.
1403  *         This function is used to compute a field value basing on coordinates of value
1404  *         location point. For example, if \a this field is on cells, the function
1405  *         is applied to cell barycenters.
1406  *  \throw If the mesh is not set.
1407  *  \throw If the spatial discretization of \a this field is NULL.
1408  *  \throw If computing \a func fails.
1409  *
1410  *  \if ENABLE_EXAMPLES
1411  *  \ref cpp_mcfielddouble_fillFromAnalytic3 "Here is a C++ example".<br>
1412  *  \ref  py_mcfielddouble_fillFromAnalytic3 "Here is a Python example".
1413  *  \endif
1414  */
1415 void MEDCouplingFieldDouble::fillFromAnalyticNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1416 {
1417   if(!_mesh)
1418     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
1419   if(_type.isNull())
1420     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticNamedCompo !");
1421   MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1422   timeDiscr()->fillFromAnalyticNamedCompo(loc,nbOfComp,varsOrder,func);
1423 }
1424
1425 /*!
1426  * Modifies values of \a this field by applying a C function to each tuple of all
1427  * data arrays.
1428  *  \param [in] nbOfComp - the number of components for \a this field to have.
1429  *  \param [in] func - the function used to compute values of \a this field.
1430  *         This function is to compute a field value basing on a current field value.
1431  *  \throw If \a func returns \c false.
1432  *
1433  *  \if ENABLE_EXAMPLES
1434  *  \ref cpp_mcfielddouble_applyFunc_c_func "Here is a C++ example".
1435  *  \endif
1436  */
1437 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
1438 {
1439   timeDiscr()->applyFunc(nbOfComp,func);
1440 }
1441
1442 /*!
1443  * Fill \a this field with a given value.<br>
1444  * This method is a specialization of other overloaded methods. When \a nbOfComp == 1
1445  * this method is equivalent to MEDCoupling::MEDCouplingFieldDouble::operator=().
1446  *  \param [in] nbOfComp - the number of components for \a this field to have.
1447  *  \param [in] val - the value to assign to every atomic value of \a this field.
1448  *  \throw If the spatial discretization of \a this field is NULL.
1449  *  \throw If the mesh is not set.
1450  *
1451  *  \if ENABLE_EXAMPLES
1452  *  \ref cpp_mcfielddouble_applyFunc_val "Here is a C++ example".<br>
1453  *  \ref  py_mcfielddouble_applyFunc_val "Here is a Python example".
1454  *  \endif
1455  */
1456 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
1457 {
1458   if(!_mesh)
1459     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
1460   if(_type.isNull())
1461     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform applyFunc !");
1462   int nbOfTuple=_type->getNumberOfTuples(_mesh);
1463   timeDiscr()->setUniformValue(nbOfTuple,nbOfComp,val);
1464 }
1465
1466 /*!
1467  * Modifies values of \a this field by applying a function to each tuple of all
1468  * data arrays.
1469  * For more info on supported expressions that can be used in the function, see \ref
1470  * MEDCouplingArrayApplyFuncExpr. <br>
1471  * The function can include arbitrary named variables
1472  * (e.g. "x","y" or "va44") to refer to components of a field value. Names of
1473  * variables are sorted in \b alphabetical \b order to associate a variable name with a
1474  * component. For example, in the expression "2*x+z", "x" stands for the component #0
1475  * and "z" stands for the component #1 (\b not #2)!<br>
1476  * In a general case, a value resulting from the function evaluation is assigned to all
1477  * components of a field value. But there is a possibility to have its own expression for
1478  * each component within one function. For this purpose, there are predefined variable
1479  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1480  * the component #0 etc). A factor of such a variable is added to the
1481  * corresponding component only.<br>
1482  * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then
1483  *   - "2*x + z"               produces (5.,5.,5.,5.)
1484  *   - "2*x + 0*y + z"         produces (9.,9.,9.,9.)
1485  *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1486  *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1487  *
1488  *  \param [in] nbOfComp - the number of components for \a this field to have.
1489  *  \param [in] func - the function used to compute values of \a this field.
1490  *         This function is to compute a field value basing on a current field value.
1491  *  \throw If computing \a func fails.
1492  *
1493  *  \if ENABLE_EXAMPLES
1494  *  \ref cpp_mcfielddouble_applyFunc "Here is a C++ example".<br>
1495  *  \ref  py_mcfielddouble_applyFunc "Here is a Python example".
1496  *  \endif
1497  */
1498 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func)
1499 {
1500   timeDiscr()->applyFunc(nbOfComp,func);
1501 }
1502
1503
1504 /*!
1505  * Modifies values of \a this field by applying a function to each tuple of all
1506  * data arrays.
1507  * For more info on supported expressions that can be used in the function, see \ref
1508  * MEDCouplingArrayApplyFuncExpr. <br>
1509  * This method differs from
1510  * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()"
1511  * by the way how variable
1512  * names, used in the function, are associated with components of field values;
1513  * here, a variable name corresponding to a component is retrieved from
1514  * component information of an array (where it is set via
1515  * DataArrayDouble::setInfoOnComponent()).<br>
1516  * In a general case, a value resulting from the function evaluation is assigned to all
1517  * components of a field value. But there is a possibility to have its own expression for
1518  * each component within one function. For this purpose, there are predefined variable
1519  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1520  * the component #0 etc). A factor of such a variable is added to the
1521  * corresponding component only.<br>
1522  * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then
1523  *   - "2*x + z"               produces (5.,5.,5.,5.)
1524  *   - "2*x + 0*y + z"         produces (9.,9.,9.,9.)
1525  *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1526  *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1527  *
1528  *  \param [in] nbOfComp - the number of components for \a this field to have.
1529  *  \param [in] func - the function used to compute values of \a this field.
1530  *         This function is to compute a new field value basing on a current field value.
1531  *  \throw If computing \a func fails.
1532  *
1533  *  \if ENABLE_EXAMPLES
1534  *  \ref cpp_mcfielddouble_applyFunc2 "Here is a C++ example".<br>
1535  *  \ref  py_mcfielddouble_applyFunc2 "Here is a Python example".
1536  *  \endif
1537  */
1538 void MEDCouplingFieldDouble::applyFuncCompo(int nbOfComp, const std::string& func)
1539 {
1540   timeDiscr()->applyFuncCompo(nbOfComp,func);
1541 }
1542
1543 /*!
1544  * Modifies values of \a this field by applying a function to each tuple of all
1545  * data arrays.
1546  * This method differs from
1547  * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()"
1548  * by the way how variable
1549  * names, used in the function, are associated with components of field values;
1550  * here, a component index of a variable is defined by a
1551  * rank of the variable within the input array \a varsOrder.<br>
1552  * For more info on supported expressions that can be used in the function, see \ref
1553  * MEDCouplingArrayApplyFuncExpr.
1554  * In a general case, a value resulting from the function evaluation is assigned to all
1555  * components of a field value. But there is a possibility to have its own expression for
1556  * each component within one function. For this purpose, there are predefined variable
1557  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1558  * the component #0 etc). A factor of such a variable is added to the
1559  * corresponding component only.<br>
1560  * For example, \a nbOfComp == 4, names of
1561  * components are given in \a varsOrder: ["x", "y","z"], components of a
1562  * 3D vector are (1.,3.,7.), then
1563  *   - "2*x + z"               produces (9.,9.,9.,9.)
1564  *   - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1565  *   - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1566  *
1567  *  \param [in] nbOfComp - the number of components for \a this field to have.
1568  *  \param [in] func - the function used to compute values of \a this field.
1569  *         This function is to compute a new field value basing on a current field value.
1570  *  \throw If computing \a func fails.
1571  *
1572  *  \if ENABLE_EXAMPLES
1573  *  \ref cpp_mcfielddouble_applyFunc3 "Here is a C++ example".<br>
1574  *  \ref  py_mcfielddouble_applyFunc3 "Here is a Python example".
1575  *  \endif
1576  */
1577 void MEDCouplingFieldDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1578 {
1579   timeDiscr()->applyFuncNamedCompo(nbOfComp,varsOrder,func);
1580 }
1581
1582 /*!
1583  * Modifies values of \a this field by applying a function to each atomic value of all
1584  * data arrays. The function computes a new single value basing on an old single value.
1585  * For more info on supported expressions that can be used in the function, see \ref
1586  * MEDCouplingArrayApplyFuncExpr. <br>
1587  * The function can include **only one** arbitrary named variable
1588  * (e.g. "x","y" or "va44") to refer to a field atomic value. <br>
1589  * In a general case, a value resulting from the function evaluation is assigned to 
1590  * a single field value. But there is a possibility to have its own expression for
1591  * each component within one function. For this purpose, there are predefined variable
1592  * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1593  * the component #0 etc). A factor of such a variable is added to the
1594  * corresponding component only.<br>
1595  * For example, components of a field value are (1.,3.,7.), then
1596  *   - "2*x - 1"               produces (1.,5.,13.)
1597  *   - "2*x*IVec + (x+3)*KVec" produces (2.,0.,10.)
1598  *   - "2*x*IVec + (x+3)*KVec + 1" produces (3.,1.,11.)
1599  *
1600  *  \param [in] func - the function used to compute values of \a this field.
1601  *         This function is to compute a field value basing on a current field value.
1602  *  \throw If computing \a func fails.
1603  *
1604  *  \if ENABLE_EXAMPLES
1605  *  \ref cpp_mcfielddouble_applyFunc_same_nb_comp "Here is a C++ example".<br>
1606  *  \ref  py_mcfielddouble_applyFunc_same_nb_comp "Here is a Python example".
1607  *  \endif
1608  */
1609 void MEDCouplingFieldDouble::applyFunc(const std::string& func)
1610 {
1611   timeDiscr()->applyFunc(func);
1612 }
1613
1614 /*!
1615  * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1616  * The field will contain exactly the same number of components after the call.
1617  * Use is not warranted for the moment !
1618  */
1619 void MEDCouplingFieldDouble::applyFuncFast32(const std::string& func)
1620 {
1621   timeDiscr()->applyFuncFast32(func);
1622 }
1623
1624 /*!
1625  * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1626  * The field will contain exactly the same number of components after the call.
1627  * Use is not warranted for the moment !
1628  */
1629 void MEDCouplingFieldDouble::applyFuncFast64(const std::string& func)
1630 {
1631   timeDiscr()->applyFuncFast64(func);
1632 }
1633
1634 /*!
1635  * Returns number of components in the data array. For more info on the data arrays,
1636  * see \ref arrays.
1637  *  \return int - the number of components in the data array.
1638  *  \throw If the data array is not set.
1639  */
1640 std::size_t MEDCouplingFieldDouble::getNumberOfComponents() const
1641 {
1642   if(getArray()==0)
1643     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
1644   return getArray()->getNumberOfComponents();
1645 }
1646
1647 /*!
1648  * Use MEDCouplingField::getNumberOfTuplesExpected instead of this method. This method will be removed soon, because it is
1649  * confusing compared to getNumberOfComponents() and getNumberOfValues() behaviour.
1650  *
1651  * Returns number of tuples in \a this field, that depends on 
1652  * - the number of entities in the underlying mesh
1653  * - \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field (e.g. number
1654  * of Gauss points if \a this->getTypeOfField() == 
1655  * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT").
1656  *
1657  * The returned value does \b not \b depend on the number of tuples in the data array
1658  * (which has to be equal to the returned value), \b contrary to
1659  * getNumberOfComponents() and getNumberOfValues() that retrieve information from the
1660  * data array (Sorry, it is confusing !).
1661  * So \b this \b method \b behaves \b exactly \b as MEDCouplingField::getNumberOfTuplesExpected \b method.
1662  *
1663  * \warning No checkConsistencyLight() is done here.
1664  * For more info on the data arrays, see \ref arrays.
1665  *  \return int - the number of tuples.
1666  *  \throw If the mesh is not set.
1667  *  \throw If the spatial discretization of \a this field is NULL.
1668  *  \throw If the spatial discretization is not fully defined.
1669  *  \sa MEDCouplingField::getNumberOfTuplesExpected
1670  */
1671 std::size_t MEDCouplingFieldDouble::getNumberOfTuples() const
1672 {
1673   if(!_mesh)
1674     throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
1675   if(_type.isNull())
1676     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getNumberOfTuples !");
1677   return _type->getNumberOfTuples(_mesh);
1678 }
1679
1680 /*!
1681  * Returns number of atomic double values in the data array of \a this field.
1682  * For more info on the data arrays, see \ref arrays.
1683  *  \return int - (number of tuples) * (number of components) of the
1684  *  data array.
1685  *  \throw If the data array is not set.
1686  */
1687 std::size_t MEDCouplingFieldDouble::getNumberOfValues() const
1688 {
1689   if(getArray()==0)
1690     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
1691   return getArray()->getNbOfElems();
1692 }
1693
1694 /*!
1695  * Sets own modification time by the most recently modified element of data (the mesh,
1696  * the data array etc). For more info, see \ref MEDCouplingTimeLabelPage.
1697  */
1698 void MEDCouplingFieldDouble::updateTime() const
1699 {
1700   MEDCouplingField::updateTime();
1701   updateTimeWith(*timeDiscr());
1702 }
1703
1704 std::size_t MEDCouplingFieldDouble::getHeapMemorySizeWithoutChildren() const
1705 {
1706   return MEDCouplingField::getHeapMemorySizeWithoutChildren();
1707 }
1708
1709 std::vector<const BigMemoryObject *> MEDCouplingFieldDouble::getDirectChildrenWithNull() const
1710 {
1711   std::vector<const BigMemoryObject *> ret(MEDCouplingField::getDirectChildrenWithNull());
1712   if(timeDiscr())
1713     {
1714       std::vector<const BigMemoryObject *> ret2(timeDiscr()->getDirectChildrenWithNull());
1715       ret.insert(ret.end(),ret2.begin(),ret2.end());
1716     }
1717   return ret;
1718 }
1719
1720 /*!
1721  * Returns a value of \a this field of type either
1722  * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or
1723  * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE".
1724  *  \param [in] cellId - an id of cell of interest.
1725  *  \param [in] nodeIdInCell - a node index within the cell.
1726  *  \param [in] compoId - an index of component.
1727  *  \return double - the field value corresponding to the specified parameters.
1728  *  \throw If the data array is not set.
1729  *  \throw If the mesh is not set.
1730  *  \throw If the spatial discretization of \a this field is NULL.
1731  *  \throw If \a this field if of type other than 
1732  *         \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or
1733  *         \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE".
1734  */
1735 double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
1736 {
1737   if(_type.isNull())
1738     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getIJK !");
1739   return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
1740 }
1741
1742 /*!
1743  * Sets the data array. 
1744  *  \param [in] array - the data array holding values of \a this field. It's size
1745  *         should correspond to the mesh and
1746  *         \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1747  *         (see getNumberOfTuples()), but this size is not checked here.
1748  */
1749 //void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
1750
1751 /*!
1752  * Sets the data array holding values corresponding to an end of a time interval
1753  * for which \a this field is defined.
1754  *  \param [in] array - the data array holding values of \a this field. It's size
1755  *         should correspond to the mesh and
1756  *         \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1757  *         (see getNumberOfTuples()), but this size is not checked here.
1758  */
1759 //void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
1760
1761 /*!
1762  * Sets all data arrays needed to define the field values.
1763  *  \param [in] arrs - a vector of DataArrayDouble's holding values of \a this
1764  *         field. Size of each array should correspond to the mesh and
1765  *         \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1766  *         (see getNumberOfTuples()), but this size is not checked here.
1767  *  \throw If number of arrays in \a arrs does not correspond to type of
1768  *         \ref MEDCouplingTemporalDisc "temporal discretization" of \a this field.
1769  */
1770 //void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs)
1771
1772 void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
1773 {
1774   tinyInfo.clear();
1775   timeDiscr()->getTinySerializationStrInformation(tinyInfo);
1776   tinyInfo.push_back(_name);
1777   tinyInfo.push_back(_desc);
1778   tinyInfo.push_back(getTimeUnit());
1779 }
1780
1781 /*!
1782  * This method retrieves some critical values to resize and prepare remote instance.
1783  * The first two elements returned in tinyInfo correspond to the parameters to give in constructor.
1784  * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1785  */
1786 void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
1787 {
1788   if(_type.isNull())
1789     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationIntInformation !");
1790   tinyInfo.clear();
1791   tinyInfo.push_back((int)_type->getEnum());
1792   tinyInfo.push_back((int)timeDiscr()->getEnum());
1793   tinyInfo.push_back((int)_nature);
1794   timeDiscr()->getTinySerializationIntInformation(tinyInfo);
1795   std::vector<int> tinyInfo2;
1796   _type->getTinySerializationIntInformation(tinyInfo2);
1797   tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1798   tinyInfo.push_back((int)tinyInfo2.size());
1799 }
1800
1801 /*!
1802  * This method retrieves some critical values to resize and prepare remote instance.
1803  * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1804  */
1805 void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
1806 {
1807   if(_type.isNull())
1808     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationDbleInformation !");
1809   tinyInfo.clear();
1810   timeDiscr()->getTinySerializationDbleInformation(tinyInfo);
1811   std::vector<double> tinyInfo2;
1812   _type->getTinySerializationDbleInformation(tinyInfo2);
1813   tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1814   tinyInfo.push_back((int)tinyInfo2.size());//very bad, lack of time to improve it
1815 }
1816
1817 /*!
1818  * This method has to be called to the new instance filled by CORBA, MPI, File...
1819  * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied.
1820  * @param dataInt out parameter. If not null the pointer is already owned by \a this after the call of this method. In this case no decrRef must be applied.
1821  * @param arrays out parameter is a vector resized to the right size. The pointers in the vector is already owned by \a this after the call of this method.
1822  *               No decrRef must be applied to every instances in returned vector.
1823  * \sa checkForUnserialization
1824  */
1825 void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays)
1826 {
1827   if(_type.isNull())
1828     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !");
1829   dataInt=0;
1830   std::vector<int> tinyInfoITmp(tinyInfoI);
1831   int sz=tinyInfoITmp.back();
1832   tinyInfoITmp.pop_back();
1833   std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz);
1834   std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end());
1835   timeDiscr()->resizeForUnserialization(tinyInfoI2,arrays);
1836   std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end());
1837   _type->resizeForUnserialization(tinyInfoITmp3,dataInt);
1838 }
1839
1840 /*!
1841  * This method is extremely close to resizeForUnserialization except that here the arrays in \a dataInt and in \a arrays are attached in \a this
1842  * after having checked that size is correct. This method is used in python pickeling context to avoid copy of data.
1843  * \sa resizeForUnserialization
1844  */
1845 void MEDCouplingFieldDouble::checkForUnserialization(const std::vector<int>& tinyInfoI, const DataArrayInt *dataInt, const std::vector<DataArrayDouble *>& arrays)
1846 {
1847   if(_type.isNull())
1848     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !");
1849   std::vector<int> tinyInfoITmp(tinyInfoI);
1850   int sz=tinyInfoITmp.back();
1851   tinyInfoITmp.pop_back();
1852   std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz);
1853   std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end());
1854   timeDiscr()->checkForUnserialization(tinyInfoI2,arrays);
1855   std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end());
1856   _type->checkForUnserialization(tinyInfoITmp3,dataInt);
1857 }
1858
1859 void MEDCouplingFieldDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS)
1860 {
1861   if(_type.isNull())
1862     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform finishUnserialization !");
1863   std::vector<int> tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end());
1864   //
1865   std::vector<double> tmp(tinyInfoD);
1866   int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it
1867   tmp.pop_back();
1868   std::vector<double> tmp1(tmp.begin(),tmp.end()-sz);
1869   std::vector<double> tmp2(tmp.end()-sz,tmp.end());
1870   //
1871   timeDiscr()->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS);
1872   _nature=(NatureOfField)tinyInfoI[2];
1873   _type->finishUnserialization(tmp2);
1874   int nbOfElemS=(int)tinyInfoS.size();
1875   _name=tinyInfoS[nbOfElemS-3];
1876   _desc=tinyInfoS[nbOfElemS-2];
1877   setTimeUnit(tinyInfoS[nbOfElemS-1]);
1878 }
1879
1880 /*!
1881  * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller.
1882  * The values returned must be consulted only in readonly mode.
1883  */
1884 void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) const
1885 {
1886   if(_type.isNull())
1887     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform serialize !");
1888   timeDiscr()->getArrays(arrays);
1889   _type->getSerializationIntArray(dataInt);
1890 }
1891
1892 /*!
1893  * Tries to set an \a other mesh as the support of \a this field. An attempt fails, if
1894  * a current and the \a other meshes are different with use of specified equality
1895  * criteria, and then an exception is thrown.
1896  *  \param [in] other - the mesh to use as the field support if this mesh can be
1897  *         considered equal to the current mesh.
1898  *  \param [in] levOfCheck - defines equality criteria used for mesh comparison. For
1899  *         it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which
1900  *         is used for mesh comparison.
1901  *  \param [in] precOnMesh - a precision used to compare nodes of the two meshes.
1902  *         It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith().
1903  *  \param [in] eps - a precision used at node renumbering (if needed) to compare field
1904  *         values at merged nodes. If the values differ more than \a eps, an
1905  *         exception is thrown.
1906  *  \throw If the mesh is not set.
1907  *  \throw If \a other == NULL.
1908  *  \throw If any of the meshes is not well defined.
1909  *  \throw If the two meshes do not match.
1910  *  \throw If field values at merged nodes (if any) deffer more than \a eps.
1911  *
1912  *  \if ENABLE_EXAMPLES
1913  *  \ref cpp_mcfielddouble_changeUnderlyingMesh "Here is a C++ example".<br>
1914  *  \ref  py_mcfielddouble_changeUnderlyingMesh "Here is a Python example".
1915  *  \endif
1916  */
1917 void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps)
1918 {
1919   if(_mesh==0 || other==0)
1920     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
1921   DataArrayInt *cellCor=0,*nodeCor=0;
1922   other->checkGeoEquivalWith(_mesh,levOfCheck,precOnMesh,cellCor,nodeCor);
1923   MCAuto<DataArrayInt> cellCor2(cellCor),nodeCor2(nodeCor);
1924   if(cellCor)
1925     renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
1926   if(nodeCor)
1927     renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps);
1928   setMesh(other);
1929 }
1930
1931 /*!
1932  * Subtracts another field from \a this one in case when the two fields have different
1933  * supporting meshes. The subtraction is performed provided that the tho meshes can be
1934  * considered equal with use of specified equality criteria, else an exception is thrown.
1935  * If the meshes match, the mesh of \a f is set to \a this field (\a this is permuted if 
1936  * necessary) and field values are subtracted. No interpolation is done here, only an
1937  * analysis of two underlying mesh is done to see if the meshes are geometrically
1938  * equivalent.<br>
1939  * The job of this method consists in calling
1940  * \a this->changeUnderlyingMesh() with \a f->getMesh() as the first parameter, and then
1941  * \a this -= \a f.<br>
1942  * This method requires that \a f and \a this are coherent (checkConsistencyLight()) and that \a f
1943  * and \a this are coherent for a merge.<br>
1944  * "DM" in the method name stands for "different meshes".
1945  *  \param [in] f - the field to subtract from this.
1946  *  \param [in] levOfCheck - defines equality criteria used for mesh comparison. For
1947  *         it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which
1948  *         is used for mesh comparison.
1949  *  \param [in] precOnMesh - a precision used to compare nodes of the two meshes.
1950  *         It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith().
1951  *  \param [in] eps - a precision used at node renumbering (if needed) to compare field
1952  *         values at merged nodes. If the values differ more than \a eps, an
1953  *         exception is thrown.
1954  *  \throw If \a f == NULL.
1955  *  \throw If any of the meshes is not set or is not well defined.
1956  *  \throw If the two meshes do not match.
1957  *  \throw If the two fields are not coherent for merge.
1958  *  \throw If field values at merged nodes (if any) deffer more than \a eps.
1959  *
1960  *  \if ENABLE_EXAMPLES
1961  *  \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".<br>
1962  *  \ref  py_mcfielddouble_substractInPlaceDM "Here is a Python example".
1963  *  \endif
1964  *  \sa changeUnderlyingMesh().
1965  */
1966 void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps)
1967 {
1968   checkConsistencyLight();
1969   if(!f)
1970     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : input field is NULL !");
1971   f->checkConsistencyLight();
1972   if(!areCompatibleForMerge(f))
1973     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : Fields are not compatible ; unable to apply mergeFields on them !");
1974   changeUnderlyingMesh(f->getMesh(),levOfCheck,precOnMesh,eps);
1975   operator-=(*f);
1976 }
1977
1978 /*!
1979  * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the
1980  * underlying mesh is replaced by a new mesh instance where the coincident nodes are merged.
1981  *  \param [in] eps - a precision used to compare nodes of the two meshes.
1982  *  \param [in] epsOnVals - a precision used to compare field
1983  *         values at merged nodes. If the values differ more than \a epsOnVals, an
1984  *         exception is thrown.
1985  *  \return bool - \c true if some nodes have been merged and hence \a this field lies
1986  *         on another mesh.
1987  *  \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1988  *  \throw If the mesh is not well defined.
1989  *  \throw If the spatial discretization of \a this field is NULL.
1990  *  \throw If the data array is not set.
1991  *  \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
1992  */
1993 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals)
1994 {
1995   const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1996   if(!meshC)
1997     throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1998   if(_type.isNull())
1999     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes !");
2000   MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
2001   bool ret;
2002   int ret2;
2003   MCAuto<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2);
2004   if(!ret)//no nodes have been merged.
2005     return ret;
2006   std::vector<DataArrayDouble *> arrays;
2007   timeDiscr()->getArrays(arrays);
2008   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
2009     if(*iter)
2010       _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
2011   setMesh(meshC2);
2012   return true;
2013 }
2014
2015 /*!
2016  * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the
2017  * underlying mesh is replaced by a new mesh instance where the coincident nodes are
2018  * merged.<br>
2019  * In contrast to mergeNodes(), location of merged nodes is changed to be at their barycenter.
2020  *  \param [in] eps - a precision used to compare nodes of the two meshes.
2021  *  \param [in] epsOnVals - a precision used to compare field
2022  *         values at merged nodes. If the values differ more than \a epsOnVals, an
2023  *         exception is thrown.
2024  *  \return bool - \c true if some nodes have been merged and hence \a this field lies
2025  *         on another mesh.
2026  *  \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
2027  *  \throw If the mesh is not well defined.
2028  *  \throw If the spatial discretization of \a this field is NULL.
2029  *  \throw If the data array is not set.
2030  *  \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
2031  */
2032 bool MEDCouplingFieldDouble::mergeNodesCenter(double eps, double epsOnVals)
2033 {
2034   const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
2035   if(!meshC)
2036     throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
2037   if(_type.isNull())
2038     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodesCenter !");
2039   MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
2040   bool ret;
2041   int ret2;
2042   MCAuto<DataArrayInt> arr=meshC2->mergeNodesCenter(eps,ret,ret2);
2043   if(!ret)//no nodes have been merged.
2044     return ret;
2045   std::vector<DataArrayDouble *> arrays;
2046   timeDiscr()->getArrays(arrays);
2047   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
2048     if(*iter)
2049       _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
2050   setMesh(meshC2);
2051   return true;
2052 }
2053
2054 /*!
2055  * Removes from the underlying mesh nodes not used in any cell. If some nodes are
2056  * removed, the underlying mesh is replaced by a new mesh instance where the unused
2057  * nodes are removed.<br>
2058  *  \param [in] epsOnVals - a precision used to compare field
2059  *         values at merged nodes. If the values differ more than \a epsOnVals, an
2060  *         exception is thrown.
2061  *  \return bool - \c true if some nodes have been removed and hence \a this field lies
2062  *         on another mesh.
2063  *  \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
2064  *  \throw If the mesh is not well defined.
2065  *  \throw If the spatial discretization of \a this field is NULL.
2066  *  \throw If the data array is not set.
2067  *  \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
2068  */
2069 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals)
2070 {
2071   const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
2072   if(!meshC)
2073     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
2074   if(_type.isNull())
2075     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipCoords !");
2076   MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
2077   int oldNbOfNodes=meshC2->getNumberOfNodes();
2078   MCAuto<DataArrayInt> arr=meshC2->zipCoordsTraducer();
2079   if(meshC2->getNumberOfNodes()!=oldNbOfNodes)
2080     {
2081       std::vector<DataArrayDouble *> arrays;
2082       timeDiscr()->getArrays(arrays);
2083       for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
2084         if(*iter)
2085           _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
2086       setMesh(meshC2);
2087       return true;
2088     }
2089   return false;
2090 }
2091
2092 /*!
2093  * Removes duplicates of cells from the understanding mesh. If some cells are
2094  * removed, the underlying mesh is replaced by a new mesh instance where the cells
2095  * duplicates are removed.<br>
2096  *  \param [in] compType - specifies a cell comparison technique. Meaning of its
2097  *          valid values [0,1,2] is explained in the description of
2098  *          MEDCouplingPointSet::zipConnectivityTraducer() which is called by this method.
2099  *  \param [in] epsOnVals - a precision used to compare field
2100  *         values at merged cells. If the values differ more than \a epsOnVals, an
2101  *         exception is thrown.
2102  *  \return bool - \c true if some cells have been removed and hence \a this field lies
2103  *         on another mesh.
2104  *  \throw If the mesh is not an instance of MEDCouplingUMesh.
2105  *  \throw If the mesh is not well defined.
2106  *  \throw If the spatial discretization of \a this field is NULL.
2107  *  \throw If the data array is not set.
2108  *  \throw If field values at merged cells (if any) deffer more than \a epsOnVals.
2109  */
2110 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals)
2111 {
2112   const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
2113   if(!meshC)
2114     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipConnectivity : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
2115   if(_type.isNull())
2116     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipConnectivity !");
2117   MCAuto<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCopy());
2118   int oldNbOfCells=meshC2->getNumberOfCells();
2119   MCAuto<DataArrayInt> arr=meshC2->zipConnectivityTraducer(compType);
2120   if(meshC2->getNumberOfCells()!=oldNbOfCells)
2121     {
2122       std::vector<DataArrayDouble *> arrays;
2123       timeDiscr()->getArrays(arrays);
2124       for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
2125         if(*iter)
2126           _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter);
2127       setMesh(meshC2);
2128       return true;
2129     }
2130   return false;
2131 }
2132
2133 /*!
2134  * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists.
2135  * For the moment, this method is implemented for fields on cells.
2136  * 
2137  * \return a newly allocated field double containing the result that the user should deallocate.
2138  */
2139 MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const
2140 {
2141   const MEDCouplingMesh *mesh=getMesh();
2142   if(!mesh)
2143     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !");
2144   if(getTypeOfField()!=ON_CELLS)
2145     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !");
2146   const MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
2147   MCAuto<MEDCouplingFieldDouble> ret(clone(false));
2148   ret->setMesh(umesh);
2149   DataArrayInt *cellIds=0;
2150   MCAuto<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds);
2151   MCAuto<DataArrayInt> cellIds2=cellIds;
2152   ret->setMesh(mesh2);
2153   MCAuto<DataArrayInt> tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end());
2154   std::vector<DataArrayDouble *> arrays;
2155   timeDiscr()->getArrays(arrays);
2156   int i=0;
2157   std::vector<DataArrayDouble *> newArr(arrays.size());
2158   std::vector< MCAuto<DataArrayDouble> > newArr2(arrays.size());
2159   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++)
2160     {
2161       if(*iter)
2162         {
2163           newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
2164           newArr[i]=newArr2[i];
2165         }
2166     }
2167   ret->setArrays(newArr);
2168   return ret.retn();
2169 }
2170
2171 /*!
2172  * Divides every cell of the underlying mesh into simplices (triangles in 2D and
2173  * tetrahedra in 3D). If some cells are divided, the underlying mesh is replaced by a new
2174  * mesh instance containing the simplices.<br> 
2175  *  \param [in] policy - specifies a pattern used for splitting. For its description, see
2176  *          MEDCouplingUMesh::simplexize().
2177  *  \return bool - \c true if some cells have been divided and hence \a this field lies
2178  *         on another mesh.
2179  *  \throw If \a policy has an invalid value. For valid values, see the description of 
2180  *         MEDCouplingUMesh::simplexize().
2181  *  \throw If MEDCouplingMesh::simplexize() is not applicable to the underlying mesh.
2182  *  \throw If the mesh is not well defined.
2183  *  \throw If the spatial discretization of \a this field is NULL.
2184  *  \throw If the data array is not set.
2185  */
2186 bool MEDCouplingFieldDouble::simplexize(int policy)
2187 {
2188   if(!_mesh)
2189     throw INTERP_KERNEL::Exception("No underlying mesh on this field to perform simplexize !");
2190   if(_type.isNull())
2191     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform simplexize !");
2192   int oldNbOfCells=_mesh->getNumberOfCells();
2193   MCAuto<MEDCouplingMesh> meshC2(_mesh->deepCopy());
2194   MCAuto<DataArrayInt> arr=meshC2->simplexize(policy);
2195   int newNbOfCells=meshC2->getNumberOfCells();
2196   if(oldNbOfCells==newNbOfCells)
2197     return false;
2198   std::vector<DataArrayDouble *> arrays;
2199   timeDiscr()->getArrays(arrays);
2200   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
2201     if(*iter)
2202       _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter);
2203   setMesh(meshC2);
2204   return true;
2205 }
2206
2207 /*!
2208  * 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.
2209  * Each Gauss points in \a this is replaced by a polygon or polyhedron cell with associated region following Voronoi algorithm.
2210  */
2211 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoize(double eps) const
2212 {
2213   checkConsistencyLight();
2214   const MEDCouplingMesh *mesh(getMesh());
2215   INTERP_KERNEL::AutoCppPtr<Voronizer> vor;
2216   int meshDim(mesh->getMeshDimension()),spaceDim(mesh->getSpaceDimension());
2217   if(meshDim==1 && (spaceDim==1 || spaceDim==2 || spaceDim==3))
2218     vor=new Voronizer1D;
2219   else if(meshDim==2 && (spaceDim==2 || spaceDim==3))
2220     vor=new Voronizer2D;
2221   else if(meshDim==3 && spaceDim==3)
2222     vor=new Voronizer3D;
2223   else
2224     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize : only 2D, 3D surf, and 3D are supported for the moment !");
2225   return voronoizeGen(vor,eps);
2226 }
2227
2228 /*!
2229  * \sa MEDCouplingUMesh::convertQuadraticCellsToLinear
2230  */
2231 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::convertQuadraticCellsToLinear() const
2232 {
2233   checkConsistencyLight();
2234   switch(getTypeOfField())
2235     {
2236     case ON_NODES:
2237       {
2238         const MEDCouplingMesh *mesh(getMesh());
2239         if(!mesh)
2240           throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
2241         MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
2242         umesh=umesh->clone(false);
2243         umesh->convertQuadraticCellsToLinear();
2244         MCAuto<DataArrayInt> o2n(umesh->zipCoordsTraducer());
2245         MCAuto<DataArrayInt> n2o(o2n->invertArrayO2N2N2O(umesh->getNumberOfNodes()));
2246         MCAuto<DataArrayDouble> arr(getArray()->selectByTupleIdSafe(n2o->begin(),n2o->end()));
2247         MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_NODES));
2248         ret->setArray(arr);
2249         ret->setMesh(umesh);
2250         ret->copyAllTinyAttrFrom(this);
2251         return ret;
2252       }
2253     case ON_CELLS:
2254       {
2255         const MEDCouplingMesh *mesh(getMesh());
2256         if(!mesh)
2257           throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
2258         MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
2259         umesh=umesh->clone(false);
2260         umesh->convertQuadraticCellsToLinear();
2261         umesh->zipCoords();
2262         MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
2263         ret->setArray(const_cast<DataArrayDouble *>(getArray()));
2264         ret->setMesh(umesh);
2265         ret->copyAllTinyAttrFrom(this);
2266         return ret;
2267       }
2268     case ON_GAUSS_PT:
2269       {
2270         const MEDCouplingMesh *mesh(getMesh());
2271         if(!mesh)
2272           throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
2273         MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
2274         std::set<INTERP_KERNEL::NormalizedCellType> gt(umesh->getAllGeoTypes());
2275         MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_GAUSS_PT));
2276         //
2277         const MEDCouplingFieldDiscretization *disc(getDiscretization());
2278         const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
2279         if(!disc2)
2280           throw INTERP_KERNEL::Exception("convertQuadraticCellsToLinear : Not a ON_GAUSS_PT field");
2281         std::set<INTERP_KERNEL::NormalizedCellType> gt2(umesh->getAllGeoTypes());
2282         const DataArrayDouble *arr(getArray());
2283         std::vector< MCAuto<DataArrayInt> > cellIdsV;
2284         std::vector< MCAuto<MEDCouplingUMesh> > meshesV;
2285         std::vector< MEDCouplingGaussLocalization > glV;
2286         bool isZipReq(false);
2287         for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=gt.begin();it!=gt.end();it++)
2288           {
2289             const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it));
2290             MCAuto<DataArrayInt> cellIds(umesh->giveCellsWithType(*it));
2291             cellIdsV.push_back(cellIds);
2292             MCAuto<MEDCouplingUMesh> part(umesh->buildPartOfMySelf(cellIds->begin(),cellIds->end()));
2293             int id(disc2->getGaussLocalizationIdOfOneType(*it));
2294             const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(id));
2295             if(!cm.isQuadratic())
2296               {
2297                 glV.push_back(gl);
2298               }
2299             else
2300               {
2301                 isZipReq=true;
2302                 part->convertQuadraticCellsToLinear();
2303                 INTERP_KERNEL::GaussInfo gi(*it,gl.getGaussCoords(),gl.getNumberOfGaussPt(),gl.getRefCoords(),gl.getNumberOfPtsInRefCell());
2304                 INTERP_KERNEL::GaussInfo gi2(gi.convertToLinear());
2305                 MEDCouplingGaussLocalization gl2(gi2.getGeoType(),gi2.getRefCoords(),gi2.getGaussCoords(),gl.getWeights());
2306                 glV.push_back(gl2);
2307               }
2308             meshesV.push_back(part);
2309           }
2310         //
2311         {
2312           std::vector< const MEDCouplingUMesh * > meshesPtr(VecAutoToVecOfCstPt(meshesV));
2313           umesh=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshesPtr);
2314           std::vector< const DataArrayInt * > zeCellIds(VecAutoToVecOfCstPt(cellIdsV));
2315           MCAuto<DataArrayInt> zeIds(DataArrayInt::Aggregate(zeCellIds));
2316           umesh->renumberCells(zeIds->begin());
2317           umesh->setName(mesh->getName());
2318         }
2319         //
2320         if(isZipReq)
2321           umesh->zipCoords();
2322         ret->setArray(const_cast<DataArrayDouble *>(getArray()));
2323         ret->setMesh(umesh);
2324         for(std::vector< MEDCouplingGaussLocalization >::const_iterator it=glV.begin();it!=glV.end();it++)
2325           ret->setGaussLocalizationOnType((*it).getType(),(*it).getRefCoords(),(*it).getGaussCoords(),(*it).getWeights());
2326         ret->copyAllTinyAttrFrom(this);
2327         ret->checkConsistencyLight();
2328         return ret;
2329       }
2330     default:
2331       throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : Only available for fields on nodes and on cells !");
2332     }
2333 }
2334
2335 /*!
2336  * 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.
2337  * Finaly \a this is also expected to be consistent.
2338  * In these conditions this method returns a newly created field (to be dealed by the caller).
2339  * The returned field will also 3 compo vector field be on nodes lying on the same mesh than \a this.
2340  * 
2341  * 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.
2342  * \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.
2343  *
2344  * \sa DataArrayDouble::fromCartToCylGiven
2345  */
2346 MEDCouplingFieldDouble *MEDCouplingFieldDouble::computeVectorFieldCyl(const double center[3], const double vect[3]) const
2347 {
2348   checkConsistencyLight();
2349   const DataArrayDouble *coo(getMesh()->getDirectAccessOfCoordsArrIfInStructure());
2350   MEDCouplingTimeDiscretization *td(timeDiscr()->computeVectorFieldCyl(coo,center,vect));
2351   td->copyTinyAttrFrom(*timeDiscr());
2352   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2353   ret->setMesh(getMesh());
2354   ret->setName(getName());
2355   return ret.retn();
2356 }
2357
2358 /*!
2359  * Creates a new MEDCouplingFieldDouble filled with the doubly contracted product of
2360  * every tensor of \a this 6-componental field.
2361  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2362  *          each tuple is calculated from the tuple <em>(t)</em> of \a this field as
2363  *          follows: \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$. 
2364  *          This new field lies on the same mesh as \a this one. The caller is to delete
2365  *          this field using decrRef() as it is no more needed.
2366  *  \throw If \a this->getNumberOfComponents() != 6.
2367  *  \throw If the spatial discretization of \a this field is NULL.
2368  */
2369 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const
2370 {
2371   if(_type.isNull())
2372     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform doublyContractedProduct !");
2373   MEDCouplingTimeDiscretization *td(timeDiscr()->doublyContractedProduct());
2374   td->copyTinyAttrFrom(*timeDiscr());
2375   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2376   ret->setName("DoublyContractedProduct");
2377   ret->setMesh(getMesh());
2378   return ret.retn();
2379 }
2380
2381 /*!
2382  * Creates a new MEDCouplingFieldDouble filled with the determinant of a square
2383  * matrix defined by every tuple of \a this field, having either 4, 6 or 9 components.
2384  * The case of 6 components corresponds to that of the upper triangular matrix. 
2385  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2386  *          each tuple is the determinant of matrix of the corresponding tuple of \a this 
2387  *          field. This new field lies on the same mesh as \a this one. The caller is to 
2388  *          delete this field using decrRef() as it is no more needed.
2389  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2390  *  \throw If the spatial discretization of \a this field is NULL.
2391  */
2392 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const
2393 {
2394   if(_type.isNull())
2395     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform determinant !");
2396   MEDCouplingTimeDiscretization *td(timeDiscr()->determinant());
2397   td->copyTinyAttrFrom(*timeDiscr());
2398   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2399   ret->setName("Determinant");
2400   ret->setMesh(getMesh());
2401   return ret.retn();
2402 }
2403
2404
2405 /*!
2406  * Creates a new MEDCouplingFieldDouble with 3 components filled with 3 eigenvalues of
2407  * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2408  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2409  *          having 3 components, whose each tuple contains the eigenvalues of the matrix of
2410  *          corresponding tuple of \a this field. This new field lies on the same mesh as
2411  *          \a this one. The caller is to delete this field using decrRef() as it is no
2412  *          more needed.  
2413  *  \throw If \a this->getNumberOfComponents() != 6.
2414  *  \throw If the spatial discretization of \a this field is NULL.
2415  */
2416 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const
2417 {
2418   if(_type.isNull())
2419     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenValues !");
2420   MEDCouplingTimeDiscretization *td(timeDiscr()->eigenValues());
2421   td->copyTinyAttrFrom(*timeDiscr());
2422   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2423   ret->setName("EigenValues");
2424   ret->setMesh(getMesh());
2425   return ret.retn();
2426 }
2427
2428 /*!
2429  * Creates a new MEDCouplingFieldDouble with 9 components filled with 3 eigenvectors of
2430  * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2431  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2432  *          having 9 components, whose each tuple contains the eigenvectors of the matrix of
2433  *          corresponding tuple of \a this field. This new field lies on the same mesh as
2434  *          \a this one. The caller is to delete this field using decrRef() as it is no
2435  *          more needed.  
2436  *  \throw If \a this->getNumberOfComponents() != 6.
2437  *  \throw If the spatial discretization of \a this field is NULL.
2438  */
2439 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const
2440 {
2441   if(_type.isNull())
2442     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenVectors !");
2443   MEDCouplingTimeDiscretization *td(timeDiscr()->eigenVectors());
2444   td->copyTinyAttrFrom(*timeDiscr());
2445   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2446   ret->setName("EigenVectors");
2447   ret->setMesh(getMesh());
2448   return ret.retn();
2449 }
2450
2451 /*!
2452  * Creates a new MEDCouplingFieldDouble filled with the inverse matrix of
2453  * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2454  * components. The case of 6 components corresponds to that of the upper triangular
2455  * matrix.
2456  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2457  *          having the same number of components as \a this one, whose each tuple
2458  *          contains the inverse matrix of the matrix of corresponding tuple of \a this
2459  *          field. This new field lies on the same mesh as \a this one. The caller is to
2460  *          delete this field using decrRef() as it is no more needed.  
2461  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2462  *  \throw If the spatial discretization of \a this field is NULL.
2463  */
2464 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const
2465 {
2466   if(_type.isNull())
2467     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform inverse !");
2468   MEDCouplingTimeDiscretization *td(timeDiscr()->inverse());
2469   td->copyTinyAttrFrom(*timeDiscr());
2470   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2471   ret->setName("Inversion");
2472   ret->setMesh(getMesh());
2473   return ret.retn();
2474 }
2475
2476 /*!
2477  * Creates a new MEDCouplingFieldDouble filled with the trace of
2478  * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2479  * components. The case of 6 components corresponds to that of the upper triangular
2480  * matrix.
2481  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2482  *          having 1 component, whose each tuple is the trace of the matrix of
2483  *          corresponding tuple of \a this field.
2484  *          This new field lies on the same mesh as \a this one. The caller is to
2485  *          delete this field using decrRef() as it is no more needed.  
2486  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2487  *  \throw If the spatial discretization of \a this field is NULL.
2488  */
2489 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const
2490 {
2491   if(_type.isNull())
2492     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform trace !");
2493   MEDCouplingTimeDiscretization *td(timeDiscr()->trace());
2494   td->copyTinyAttrFrom(*timeDiscr());
2495   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2496   ret->setName("Trace");
2497   ret->setMesh(getMesh());
2498   return ret.retn();
2499 }
2500
2501 /*!
2502  * Creates a new MEDCouplingFieldDouble filled with the stress deviator tensor of
2503  * a stress tensor defined by every tuple of \a this 6-componental field.
2504  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2505  *          having same number of components and tuples as \a this field,
2506  *          whose each tuple contains the stress deviator tensor of the stress tensor of
2507  *          corresponding tuple of \a this field. This new field lies on the same mesh as
2508  *          \a this one. The caller is to delete this field using decrRef() as it is no
2509  *          more needed.  
2510  *  \throw If \a this->getNumberOfComponents() != 6.
2511  *  \throw If the spatial discretization of \a this field is NULL.
2512  */
2513 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const
2514 {
2515   if(_type.isNull())
2516     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform deviator !");
2517   MEDCouplingTimeDiscretization *td(timeDiscr()->deviator());
2518   td->copyTinyAttrFrom(*timeDiscr());
2519   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2520   ret->setName("Deviator");
2521   ret->setMesh(getMesh());
2522   return ret.retn();
2523 }
2524
2525 /*!
2526  * Creates a new MEDCouplingFieldDouble filled with the magnitude of
2527  * every vector of \a this field.
2528  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, 
2529  *          having one component, whose each tuple is the magnitude of the vector
2530  *          of corresponding tuple of \a this field. This new field lies on the
2531  *          same mesh as \a this one. The caller is to
2532  *          delete this field using decrRef() as it is no more needed.  
2533  *  \throw If the spatial discretization of \a this field is NULL.
2534  */
2535 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const
2536 {
2537   if(_type.isNull())
2538     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform magnitude !");
2539   MEDCouplingTimeDiscretization *td(timeDiscr()->magnitude());
2540   td->copyTinyAttrFrom(*timeDiscr());
2541   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2542   ret->setName("Magnitude");
2543   ret->setMesh(getMesh());
2544   return ret.retn();
2545 }
2546
2547 /*!
2548  * Creates a new scalar MEDCouplingFieldDouble filled with the maximal value among
2549  * values of every tuple of \a this field.
2550  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2551  *          This new field lies on the same mesh as \a this one. The caller is to
2552  *          delete this field using decrRef() as it is no more needed.  
2553  *  \throw If the spatial discretization of \a this field is NULL.
2554  */
2555 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const
2556 {
2557   if(_type.isNull())
2558     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform maxPerTuple !");
2559   MEDCouplingTimeDiscretization *td(timeDiscr()->maxPerTuple());
2560   td->copyTinyAttrFrom(*timeDiscr());
2561   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2562   std::ostringstream oss;
2563   oss << "Max_" << getName();
2564   ret->setName(oss.str());
2565   ret->setMesh(getMesh());
2566   return ret.retn();
2567 }
2568
2569 /*!
2570  * Changes number of components in \a this field. If \a newNbOfComp is less
2571  * than \a this->getNumberOfComponents() then each tuple
2572  * is truncated to have \a newNbOfComp components, keeping first components. If \a
2573  * newNbOfComp is more than \a this->getNumberOfComponents() then 
2574  * each tuple is populated with \a dftValue to have \a newNbOfComp components.  
2575  *  \param [in] newNbOfComp - number of components for the new field to have.
2576  *  \param [in] dftValue - value assigned to new values added to \a this field.
2577  *  \throw If \a this is not allocated.
2578  */
2579 void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue)
2580 {
2581   timeDiscr()->changeNbOfComponents(newNbOfComp,dftValue);
2582 }
2583
2584 /*!
2585  * Creates a new MEDCouplingFieldDouble composed of selected components of \a this field.
2586  * The new MEDCouplingFieldDouble has the same number of tuples but includes components
2587  * specified by \a compoIds parameter. So that getNbOfElems() of the result field
2588  * can be either less, same or more than \a this->getNumberOfValues().
2589  *  \param [in] compoIds - sequence of zero based indices of components to include
2590  *              into the new field.
2591  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble that the caller
2592  *          is to delete using decrRef() as it is no more needed.
2593  *  \throw If a component index (\a i) is not valid: 
2594  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
2595  */
2596 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
2597 {
2598   if(_type.isNull())
2599     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform keepSelectedComponents !");
2600   MEDCouplingTimeDiscretization *td(timeDiscr()->keepSelectedComponents(compoIds));
2601   td->copyTinyAttrFrom(*timeDiscr());
2602   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2603   ret->setName(getName());
2604   ret->setMesh(getMesh());
2605   return ret.retn();
2606 }
2607
2608
2609 /*!
2610  * Copy all components in a specified order from another field.
2611  * The number of tuples in \a this and the other field can be different.
2612  *  \param [in] f - the field to copy data from.
2613  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2614  *              to be copied.
2615  *  \throw If the two fields have different number of data arrays.
2616  *  \throw If a data array is set in one of fields and is not set in the other.
2617  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2618  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2619  */
2620 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds)
2621 {
2622   timeDiscr()->setSelectedComponents(f->timeDiscr(),compoIds);
2623 }
2624
2625 /*!
2626  * Sorts value within every tuple of \a this field.
2627  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2628  *              in descending order.
2629  *  \throw If a data array is not allocated.
2630  */
2631 void MEDCouplingFieldDouble::sortPerTuple(bool asc)
2632 {
2633   timeDiscr()->sortPerTuple(asc);
2634 }
2635
2636 /*!
2637  * Creates a new MEDCouplingFieldDouble by concatenating two given fields.
2638  * Values of
2639  * the first field precede values of the second field within the result field.
2640  *  \param [in] f1 - the first field.
2641  *  \param [in] f2 - the second field.
2642  *  \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2643  *          MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() 
2644  *          as it is no more needed.
2645  *  \throw If the fields are not compatible for the merge.
2646  *  \throw If the spatial discretization of \a f1 is NULL.
2647  *  \throw If the time discretization of \a f1 is NULL.
2648  *
2649  *  \if ENABLE_EXAMPLES
2650  *  \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2651  *  \ref  py_mcfielddouble_MergeFields "Here is a Python example".
2652  *  \endif
2653  */
2654 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2655 {
2656   if(!f1->areCompatibleForMerge(f2))
2657     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
2658   const MEDCouplingMesh *m1(f1->getMesh()),*m2(f2->getMesh());
2659   if(!f1->timeDiscr())
2660     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no time discr of f1 !");
2661   if(!f1->_type)
2662     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no spatial discr of f1 !");
2663   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->aggregate(f2->timeDiscr()));
2664   td->copyTinyAttrFrom(*f1->timeDiscr());
2665   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2666   ret->setName(f1->getName());
2667   ret->setDescription(f1->getDescription());
2668   if(m1)
2669     {
2670       MCAuto<MEDCouplingMesh> m=m1->mergeMyselfWith(m2);
2671       ret->setMesh(m);
2672     }
2673   return ret.retn();
2674 }
2675
2676 /*!
2677  * Creates a new MEDCouplingFieldDouble by concatenating all given fields.
2678  * Values of the *i*-th field precede values of the (*i*+1)-th field within the result.
2679  * If there is only one field in \a a, a deepCopy() (except time information of mesh and
2680  * field) of the field is returned. 
2681  * Generally speaking the first field in \a a is used to assign tiny attributes of the
2682  * returned field. 
2683  *  \param [in] a - a vector of fields (MEDCouplingFieldDouble) to concatenate.
2684  *  \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2685  *          MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() 
2686  *          as it is no more needed.
2687  *  \throw If \a a is empty.
2688  *  \throw If the fields are not compatible for the merge.
2689  *
2690  *  \if ENABLE_EXAMPLES
2691  *  \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2692  *  \ref  py_mcfielddouble_MergeFields "Here is a Python example".
2693  *  \endif
2694  */
2695 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a)
2696 {
2697   if(a.size()<1)
2698     throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !");
2699   std::vector< MCAuto<MEDCouplingUMesh> > ms(a.size());
2700   std::vector< const MEDCouplingUMesh *> ms2(a.size());
2701   std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
2702   std::vector<const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
2703   const MEDCouplingFieldDouble *ref=(*it++);
2704   if(!ref)
2705     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of NULL instance in first place of input vector !");
2706   for(;it!=a.end();it++)
2707     if(!ref->areCompatibleForMerge(*it))
2708       throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2709   for(int i=0;i<(int)a.size();i++)
2710     {
2711       if(a[i]->getMesh())
2712         { ms[i]=a[i]->getMesh()->buildUnstructured(); ms2[i]=ms[i]; }
2713       else
2714         { ms[i]=0; ms2[i]=0; }
2715       tds[i]=a[i]->timeDiscr();
2716     }
2717   MEDCouplingTimeDiscretization *td(tds[0]->aggregate(tds));
2718   td->copyTinyAttrFrom(*(a[0]->timeDiscr()));
2719   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()));
2720   ret->setName(a[0]->getName());
2721   ret->setDescription(a[0]->getDescription());
2722   if(ms2[0])
2723     {
2724       MCAuto<MEDCouplingUMesh> m(MEDCouplingUMesh::MergeUMeshes(ms2));
2725       m->copyTinyInfoFrom(ms2[0]);
2726       ret->setMesh(m);
2727     }
2728   return ret.retn();
2729 }
2730
2731 /*!
2732  * Creates a new MEDCouplingFieldDouble by concatenating components of two given fields.
2733  * The number of components in the result field is a sum of the number of components of
2734  * given fields. The number of tuples in the result field is same as that of each of given
2735  * arrays.
2736  * Number of tuples in the given fields must be the same.
2737  *  \param [in] f1 - a field to include in the result field.
2738  *  \param [in] f2 - another field to include in the result field.
2739  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2740  *          The caller is to delete this result field using decrRef() as it is no more
2741  *          needed.
2742  *  \throw If the fields are not compatible for a meld (areCompatibleForMeld()).
2743  *  \throw If any of data arrays is not allocated.
2744  *  \throw If \a f1->getNumberOfTuples() != \a f2->getNumberOfTuples()
2745  */
2746 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2747 {
2748   if(!f1 || !f2)
2749     throw INTERP_KERNEL::Exception("MeldFields : null input pointer !");
2750   if(!f1->areCompatibleForMeld(f2))
2751     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
2752   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->meld(f2->timeDiscr()));
2753   td->copyTinyAttrFrom(*f1->timeDiscr());
2754   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2755   ret->setMesh(f1->getMesh());
2756   return ret.retn();
2757 }
2758
2759 /*!
2760  * Returns a new MEDCouplingFieldDouble containing a dot product of two given fields, 
2761  * so that the i-th tuple of the result field is a sum of products of j-th components of
2762  * i-th tuples of given fields (\f$ f_i = \sum_{j=1}^n f1_j * f2_j \f$). 
2763  * Number of tuples and components in the given fields must be the same.
2764  *  \param [in] f1 - a given field.
2765  *  \param [in] f2 - another given field.
2766  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2767  *          The caller is to delete this result field using decrRef() as it is no more
2768  *          needed.
2769  *  \throw If either \a f1 or \a f2 is NULL.
2770  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2771  *         differ not only in values.
2772  */
2773 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2774 {
2775   if(!f1)
2776     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !");
2777   if(!f1->areStrictlyCompatibleForMulDiv(f2))
2778     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them!  Check support mesh, and spatial and time discretisation.");
2779   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->dot(f2->timeDiscr()));
2780   td->copyTinyAttrFrom(*f1->timeDiscr());
2781   MEDCouplingFieldDouble *ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2782   ret->setMesh(f1->getMesh());
2783   return ret;
2784 }
2785
2786 /*!
2787  * Returns a new MEDCouplingFieldDouble containing a cross product of two given fields, 
2788  * so that
2789  * the i-th tuple of the result field is a 3D vector which is a cross
2790  * product of two vectors defined by the i-th tuples of given fields.
2791  * Number of tuples in the given fields must be the same.
2792  * Number of components in the given fields must be 3.
2793  *  \param [in] f1 - a given field.
2794  *  \param [in] f2 - another given field.
2795  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2796  *          The caller is to delete this result field using decrRef() as it is no more
2797  *          needed.
2798  *  \throw If either \a f1 or \a f2 is NULL.
2799  *  \throw If \a f1->getNumberOfComponents() != 3
2800  *  \throw If \a f2->getNumberOfComponents() != 3
2801  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2802  *         differ not only in values.
2803  */
2804 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2805 {
2806   if(!f1)
2807     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !");
2808   if(!f1->areStrictlyCompatibleForMulDiv(f2))
2809     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation.");
2810   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->crossProduct(f2->timeDiscr()));
2811   td->copyTinyAttrFrom(*f1->timeDiscr());
2812   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2813   ret->setMesh(f1->getMesh());
2814   return ret.retn();
2815 }
2816
2817 /*!
2818  * Returns a new MEDCouplingFieldDouble containing maximal values of two given fields.
2819  * Number of tuples and components in the given fields must be the same.
2820  *  \param [in] f1 - a field to compare values with another one.
2821  *  \param [in] f2 - another field to compare values with the first one.
2822  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2823  *          The caller is to delete this result field using decrRef() as it is no more
2824  *          needed.
2825  *  \throw If either \a f1 or \a f2 is NULL.
2826  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2827  *         differ not only in values.
2828  *
2829  *  \if ENABLE_EXAMPLES
2830  *  \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2831  *  \ref  py_mcfielddouble_MaxFields "Here is a Python example".
2832  *  \endif
2833  */
2834 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2835 {
2836   if(!f1)
2837     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MaxFields : input field is NULL !");
2838   if(!f1->areStrictlyCompatible(f2))
2839     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MaxFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2840   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->max(f2->timeDiscr()));
2841   td->copyTinyAttrFrom(*f1->timeDiscr());
2842   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2843   ret->setMesh(f1->getMesh());
2844   return ret.retn();
2845 }
2846
2847 /*!
2848  * Returns a new MEDCouplingFieldDouble containing minimal values of two given fields.
2849  * Number of tuples and components in the given fields must be the same.
2850  *  \param [in] f1 - a field to compare values with another one.
2851  *  \param [in] f2 - another field to compare values with the first one.
2852  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2853  *          The caller is to delete this result field using decrRef() as it is no more
2854  *          needed.
2855  *  \throw If either \a f1 or \a f2 is NULL.
2856  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2857  *         differ not only in values.
2858  *
2859  *  \if ENABLE_EXAMPLES
2860  *  \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2861  *  \ref  py_mcfielddouble_MaxFields "Here is a Python example".
2862  *  \endif
2863  */
2864 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2865 {
2866   if(!f1)
2867     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MinFields : input field is NULL !");
2868   if(!f1->areStrictlyCompatible(f2))
2869     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MinFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2870   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->min(f2->timeDiscr()));
2871   td->copyTinyAttrFrom(*f1->timeDiscr());
2872   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2873   ret->setMesh(f1->getMesh());
2874   return ret.retn();
2875 }
2876
2877 /*!
2878  * Returns a copy of \a this field in which sign of all values is reversed.
2879  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble
2880  *         containing the same number of tuples and components as \a this field. 
2881  *         The caller is to delete this result field using decrRef() as it is no more
2882  *         needed. 
2883  *  \throw If the spatial discretization of \a this field is NULL.
2884  *  \throw If a data array is not allocated.
2885  */
2886 MEDCouplingFieldDouble *MEDCouplingFieldDouble::negate() const
2887 {
2888   if(_type.isNull())
2889     throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform negate !");
2890   MEDCouplingTimeDiscretization *td(timeDiscr()->negate());
2891   td->copyTinyAttrFrom(*timeDiscr());
2892   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2893   ret->setMesh(getMesh());
2894   return ret.retn();
2895 }
2896
2897 /*!
2898  * Returns a new MEDCouplingFieldDouble containing sum values of corresponding values of
2899  * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] + _f2_ [ i, j ] ).
2900  * Number of tuples and components in the given fields must be the same.
2901  *  \param [in] f1 - a field to sum up.
2902  *  \param [in] f2 - another field to sum up.
2903  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2904  *          The caller is to delete this result field using decrRef() as it is no more
2905  *          needed.
2906  *  \throw If either \a f1 or \a f2 is NULL.
2907  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2908  *         differ not only in values.
2909  */
2910 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2911 {
2912   if(!f1)
2913     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::AddFields : input field is NULL !");
2914   if(!f1->areStrictlyCompatible(f2))
2915     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply AddFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2916   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->add(f2->timeDiscr()));
2917   td->copyTinyAttrFrom(*f1->timeDiscr());
2918   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2919   ret->setMesh(f1->getMesh());
2920   return ret.retn();
2921 }
2922
2923 /*!
2924  * Adds values of another MEDCouplingFieldDouble to values of \a this one
2925  * ( _this_ [ i, j ] += _other_ [ i, j ] ) using DataArrayDouble::addEqual().
2926  * The two fields must have same number of tuples, components and same underlying mesh.
2927  *  \param [in] other - the field to add to \a this one.
2928  *  \return const MEDCouplingFieldDouble & - a reference to \a this field.
2929  *  \throw If \a other is NULL.
2930  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2931  *         differ not only in values.
2932  */
2933 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other)
2934 {
2935   if(!areStrictlyCompatible(&other))
2936     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply += on them! Check support mesh, field nature, and spatial and time discretisation.");
2937   timeDiscr()->addEqual(other.timeDiscr());
2938   return *this;
2939 }
2940
2941 /*!
2942  * Returns a new MEDCouplingFieldDouble containing subtraction of corresponding values of
2943  * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] - _f2_ [ i, j ] ).
2944  * Number of tuples and components in the given fields must be the same.
2945  *  \param [in] f1 - a field to subtract from.
2946  *  \param [in] f2 - a field to subtract.
2947  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2948  *          The caller is to delete this result field using decrRef() as it is no more
2949  *          needed.
2950  *  \throw If either \a f1 or \a f2 is NULL.
2951  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2952  *         differ not only in values.
2953  */
2954 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2955 {
2956   if(!f1)
2957     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::SubstractFields : input field is NULL !");
2958   if(!f1->areStrictlyCompatible(f2))
2959     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply SubstractFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2960   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->substract(f2->timeDiscr()));
2961   td->copyTinyAttrFrom(*f1->timeDiscr());
2962   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2963   ret->setMesh(f1->getMesh());
2964   return ret.retn();
2965 }
2966
2967 /*!
2968  * Subtract values of another MEDCouplingFieldDouble from values of \a this one
2969  * ( _this_ [ i, j ] -= _other_ [ i, j ] ) using DataArrayDouble::substractEqual().
2970  * The two fields must have same number of tuples, components and same underlying mesh.
2971  *  \param [in] other - the field to subtract from \a this one.
2972  *  \return const MEDCouplingFieldDouble & - a reference to \a this field.
2973  *  \throw If \a other is NULL.
2974  *  \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2975  *         differ not only in values.
2976  */
2977 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other)
2978 {
2979   if(!areStrictlyCompatible(&other))
2980     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply -= on them! Check support mesh, field nature, and spatial and time discretisation.");
2981   timeDiscr()->substractEqual(other.timeDiscr());
2982   return *this;
2983 }
2984
2985 /*!
2986  * Returns a new MEDCouplingFieldDouble containing product values of
2987  * two given fields. There are 2 valid cases.
2988  * 1.  The fields have same number of tuples and components. Then each value of
2989  *   the result field (_f_) is a product of the corresponding values of _f1_ and
2990  *   _f2_, i.e. _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, j ].
2991  * 2.  The fields have same number of tuples and one field, say _f2_, has one
2992  *   component. Then
2993  *   _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, 0 ].
2994  *
2995  * The two fields must have same number of tuples and same underlying mesh.
2996  *  \param [in] f1 - a factor field.
2997  *  \param [in] f2 - another factor field.
2998  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2999  *          The caller is to delete this result field using decrRef() as it is no more
3000  *          needed.
3001  *  \throw If either \a f1 or \a f2 is NULL.
3002  *  \throw If the fields are not compatible for multiplication (areCompatibleForMul()),
3003  *         i.e. they differ not only in values and possibly number of components.
3004  */
3005 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
3006 {
3007   if(!f1)
3008     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MultiplyFields : input field is NULL !");
3009   if(!f1->areCompatibleForMul(f2))
3010     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MultiplyFields on them! Check support mesh, and spatial and time discretisation.");
3011   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->multiply(f2->timeDiscr()));
3012   td->copyTinyAttrFrom(*f1->timeDiscr());
3013   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
3014   ret->setMesh(f1->getMesh());
3015   return ret.retn();
3016 }
3017
3018 /*!
3019  * Multiply values of another MEDCouplingFieldDouble to values of \a this one
3020  * using DataArrayDouble::multiplyEqual().
3021  * The two fields must have same number of tuples and same underlying mesh.
3022  * There are 2 valid cases.
3023  * 1.  The fields have same number of components. Then each value of
3024  *   \a other is multiplied to the corresponding value of \a this field, i.e.
3025  *   _this_ [ i, j ] *= _other_ [ i, j ].
3026  * 2. The _other_ field has one component. Then
3027  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
3028  *
3029  * The two fields must have same number of tuples and same underlying mesh.
3030  *  \param [in] other - an field to multiply to \a this one.
3031  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
3032  *          The caller is to delete this result field using decrRef() as it is no more
3033  *          needed.
3034  *  \throw If \a other is NULL.
3035  *  \throw If the fields are not strictly compatible for multiplication
3036  *         (areCompatibleForMul()),
3037  *         i.e. they differ not only in values and possibly in number of components.
3038  */
3039 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other)
3040 {
3041   if(!areCompatibleForMul(&other))
3042     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply *= on them! Check support mesh, and spatial and time discretisation.");
3043   timeDiscr()->multiplyEqual(other.timeDiscr());
3044   _nature = NoNature;
3045   return *this;
3046 }
3047
3048 /*!
3049  * Returns a new MEDCouplingFieldDouble containing division of two given fields.
3050  * There are 2 valid cases.
3051  * 1.  The fields have same number of tuples and components. Then each value of
3052  *   the result field (_f_) is a division of the corresponding values of \a f1 and
3053  *   \a f2, i.e. _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, j ].
3054  * 2.  The fields have same number of tuples and _f2_ has one component. Then
3055  *   _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, 0 ].
3056  *
3057  *  \param [in] f1 - a numerator field.
3058  *  \param [in] f2 - a denominator field.
3059  *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
3060  *          The caller is to delete this result field using decrRef() as it is no more
3061  *          needed.
3062  *  \throw If either \a f1 or \a f2 is NULL.
3063  *  \throw If the fields are not compatible for division (areCompatibleForDiv()),
3064  *         i.e. they differ not only in values and possibly in number of components.
3065  */
3066 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
3067 {
3068   if(!f1)
3069     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DivideFields : input field is NULL !");
3070   if(!f1->areCompatibleForDiv(f2))
3071     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DivideFields on them! Check support mesh, and spatial and time discretisation.");
3072   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->divide(f2->timeDiscr()));
3073   td->copyTinyAttrFrom(*f1->timeDiscr());
3074   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
3075   ret->setMesh(f1->getMesh());
3076   return ret.retn();
3077 }
3078
3079 /*!
3080  * Divide values of \a this field by values of another MEDCouplingFieldDouble
3081  * using DataArrayDouble::divideEqual().
3082  * The two fields must have same number of tuples and same underlying mesh.
3083  * There are 2 valid cases.
3084  * 1.  The fields have same number of components. Then each value of
3085  *    \a this field is divided by the corresponding value of \a other one, i.e.
3086  *   _this_ [ i, j ] /= _other_ [ i, j ].
3087  * 2.  The \a other field has one component. Then
3088  *   _this_ [ i, j ] /= _other_ [ i, 0 ].
3089  *
3090  *  \warning No check of division by zero is performed!
3091  *  \param [in] other - an field to divide \a this one by.
3092  *  \throw If \a other is NULL.
3093  *  \throw If the fields are not compatible for division (areCompatibleForDiv()),
3094  *         i.e. they differ not only in values and possibly in number of components.
3095  */
3096 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other)
3097 {
3098   if(!areCompatibleForDiv(&other))
3099     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply /= on them! Check support mesh, and spatial and time discretisation.");
3100   timeDiscr()->divideEqual(other.timeDiscr());
3101   _nature = NoNature;
3102   return *this;
3103 }
3104
3105 /*!
3106  * Directly called by MEDCouplingFieldDouble::operator^.
3107  * 
3108  * \sa MEDCouplingFieldDouble::operator^
3109  */
3110 MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
3111 {
3112   if(!f1)
3113     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::PowFields : input field is NULL !");
3114   if(!f1->areCompatibleForMul(f2))
3115     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply PowFields on them! Check support mesh, and spatial and time discretisation.");
3116   MEDCouplingTimeDiscretization *td(f1->timeDiscr()->pow(f2->timeDiscr()));
3117   td->copyTinyAttrFrom(*f1->timeDiscr());
3118   MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
3119   ret->setMesh(f1->getMesh());
3120   return ret.retn();
3121 }
3122
3123 /*!
3124  * Directly call MEDCouplingFieldDouble::PowFields static method.
3125  * 
3126  * \sa MEDCouplingFieldDouble::PowFields
3127  */
3128 MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const
3129 {
3130   return PowFields(this,&other);
3131 }
3132
3133 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other)
3134 {
3135   if(!areCompatibleForDiv(&other))
3136     throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply ^= on them!  Check support mesh, and spatial and time discretisation.");
3137   timeDiscr()->powEqual(other.timeDiscr());
3138   _nature = NoNature;
3139   return *this;
3140 }
3141
3142 /*!
3143  * Writes the field series \a fs and the mesh the fields lie on in the VTK file \a fileName.
3144  * If \a fs is empty no file is written.
3145  * The result file is valid provided that no exception is thrown.
3146  * \warning All the fields must be named and lie on the same non NULL mesh.
3147  *  \param [in] fileName - the name of a VTK file to write in.
3148  *  \param [in] fs - the fields to write.
3149  *  \param [in] isBinary - specifies the VTK format of the written file. By default true (Binary mode)
3150  *  \throw If \a fs[ 0 ] == NULL.
3151  *  \throw If the fields lie not on the same mesh.
3152  *  \throw If the mesh is not set.
3153  *  \throw If any of the fields has no name.
3154  *
3155  *  \if ENABLE_EXAMPLES
3156  *  \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".<br>
3157  *  \ref  py_mcfielddouble_WriteVTK "Here is a Python example".
3158  *  \endif
3159  */
3160 std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector<const MEDCouplingFieldDouble *>& fs, bool isBinary)
3161 {
3162   if(fs.empty())
3163     return std::string();
3164   std::size_t nfs=fs.size();
3165   if(!fs[0])
3166     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field is NULL !");
3167   const MEDCouplingMesh *m=fs[0]->getMesh();
3168   if(!m)
3169     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field lies on NULL mesh !");
3170   for(std::size_t i=1;i<nfs;i++)
3171     if(fs[i]->getMesh()!=m)
3172       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.");
3173   if(!m)
3174     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !");
3175   std::string ret(m->getVTKFileNameOf(fileName));
3176   MCAuto<DataArrayByte> byteArr;
3177   if(isBinary)
3178     { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); }
3179   std::ostringstream coss,noss;
3180   for(std::size_t i=0;i<nfs;i++)
3181     {
3182       const MEDCouplingFieldDouble *cur=fs[i];
3183       std::string name(cur->getName());
3184       if(name.empty())
3185         {
3186           std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
3187           throw INTERP_KERNEL::Exception(oss.str());
3188         }
3189       TypeOfField typ=cur->getTypeOfField();
3190       if(typ==ON_CELLS)
3191         cur->getArray()->writeVTK(coss,8,cur->getName(),byteArr);
3192       else if(typ==ON_NODES)
3193         cur->getArray()->writeVTK(noss,8,cur->getName(),byteArr);
3194       else
3195         throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : only node and cell fields supported for the moment !");
3196     }
3197   m->writeVTKAdvanced(ret,coss.str(),noss.str(),byteArr);
3198   return ret;
3199 }
3200
3201 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoizeGen(const Voronizer *vor, double eps) const
3202 {
3203   checkConsistencyLight();
3204   if(!vor)
3205     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoizeGen : null pointer !");
3206   MCAuto<MEDCouplingFieldDouble> fieldToWO;
3207   const MEDCouplingMesh *inpMeshBase(getMesh());
3208   MCAuto<MEDCouplingUMesh> inpMesh(inpMeshBase->buildUnstructured());
3209   std::string meshName(inpMesh->getName());
3210   if(!inpMesh->isPresenceOfQuadratic())
3211     fieldToWO=clone(false);
3212   else
3213     {
3214       fieldToWO=convertQuadraticCellsToLinear();
3215       inpMeshBase=fieldToWO->getMesh();
3216       inpMesh=inpMeshBase->buildUnstructured();
3217     }
3218   int nbCells(inpMesh->getNumberOfCells());
3219   const MEDCouplingFieldDiscretization *disc(fieldToWO->getDiscretization());
3220   const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
3221   if(!disc2)
3222     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : Not a ON_GAUSS_PT field");
3223   int nbLocs(disc2->getNbOfGaussLocalization());
3224   std::vector< MCAuto<MEDCouplingUMesh> > cells(nbCells);
3225   for(int i=0;i<nbLocs;i++)
3226     {
3227       const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(i));
3228       if(gl.getDimension()!=vor->getDimension())
3229         throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : not a 2D one !");
3230       MCAuto<MEDCouplingUMesh> mesh(gl.buildRefCell());
3231       const std::vector<double>& coo(gl.getGaussCoords());
3232       MCAuto<DataArrayDouble> coo2(DataArrayDouble::NewFromStdVector(coo));
3233       coo2->rearrange(vor->getDimension());
3234       //
3235       MCAuto<MEDCouplingUMesh> coo3(MEDCouplingUMesh::Build0DMeshFromCoords(coo2));
3236       //
3237       MCAuto<MEDCouplingUMesh> vorCellsForCurDisc(vor->doIt(mesh,coo2,eps));
3238       std::vector<int> ids;
3239       MCAuto<DataArrayDouble> ptsInReal;
3240       disc2->getCellIdsHavingGaussLocalization(i,ids);
3241       {
3242         MCAuto<MEDCouplingUMesh> subMesh(inpMesh->buildPartOfMySelf(&ids[0],&ids[0]+ids.size()));
3243         ptsInReal=gl.localizePtsInRefCooForEachCell(vorCellsForCurDisc->getCoords(),subMesh);
3244       }
3245       int nbPtsPerCell(vorCellsForCurDisc->getNumberOfNodes());
3246       for(std::size_t i=0;i<ids.size();i++)
3247         {
3248           MCAuto<MEDCouplingUMesh> elt(vorCellsForCurDisc->clone(false));
3249           MCAuto<DataArrayDouble> coo(ptsInReal->selectByTupleIdSafeSlice(i*nbPtsPerCell,(i+1)*nbPtsPerCell,1));
3250           elt->setCoords(coo);
3251           cells[ids[i]]=elt;
3252         }
3253     }
3254   std::vector< const MEDCouplingUMesh * > cellsPtr(VecAutoToVecOfCstPt(cells));
3255   MCAuto<MEDCouplingUMesh> outMesh(MEDCouplingUMesh::MergeUMeshes(cellsPtr));
3256   outMesh->setName(meshName);
3257   MCAuto<MEDCouplingFieldDouble> onCells(MEDCouplingFieldDouble::New(ON_CELLS));
3258   onCells->setMesh(outMesh);
3259   {
3260     MCAuto<DataArrayDouble> arr(fieldToWO->getArray()->deepCopy());
3261     onCells->setArray(arr);
3262   }
3263   onCells->setTimeUnit(getTimeUnit());
3264   {
3265     int b,c;
3266     double a(getTime(b,c));
3267     onCells->setTime(a,b,c);
3268   }
3269   onCells->setName(getName());
3270   return onCells;
3271 }
3272
3273 MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr()
3274 {
3275   MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
3276   if(!ret)
3277     return 0;
3278   MEDCouplingTimeDiscretization *retc(dynamic_cast<MEDCouplingTimeDiscretization *>(ret));
3279   if(!retc)
3280     throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");
3281   return retc;
3282 }
3283
3284 const MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr() const
3285 {
3286   const MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
3287   if(!ret)
3288     return 0;
3289   const MEDCouplingTimeDiscretization *retc(dynamic_cast<const MEDCouplingTimeDiscretization *>(ret));
3290   if(!retc)
3291     throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");
3292   return retc;
3293 }
3294