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