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