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