1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (EDF R&D)
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"
30 #include "MEDCouplingVoronoi.hxx"
31 #include "MEDCouplingNatureOfField.hxx"
33 #include "InterpKernelAutoPtr.hxx"
34 #include "InterpKernelGaussCoords.hxx"
41 using namespace MEDCoupling;
43 template class MEDCoupling::MEDCouplingFieldT<double>;
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.
62 MEDCouplingFieldDouble* MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td)
64 return new MEDCouplingFieldDouble(type,td);
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
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.
85 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td)
87 return new MEDCouplingFieldDouble(ft,td);
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.
94 //void MEDCouplingFieldDouble::setTimeUnit(const std::string& unit)
97 * Returns a time unit of \a this field.
98 * \return a string describing units in which time is measured.
100 //std::string MEDCouplingFieldDouble::getTimeUnit() const
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.
107 * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is
110 void MEDCouplingFieldDouble::synchronizeTimeWithSupport()
112 timeDiscr()->synchronizeTimeWith(_mesh);
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)
122 * - \ref MEDCouplingSpatialDisc "a spatial discretization".
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()
136 MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
138 return new MEDCouplingFieldDouble(*this,recDeepCpy);
142 * Returns a new MEDCouplingFieldDouble which is a deep copy of \a this one **including
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()
152 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCopy() const
154 return cloneWithMesh(true);
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.
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."
178 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const
180 MEDCouplingTimeDiscretization *tdo=timeDiscr()->buildNewTimeReprFromThis(td,deepCpy);
181 MCAuto<MEDCouplingFieldDiscretization> disc;
184 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),tdo,disc.retn()));
185 ret->setMesh(getMesh());
186 ret->setName(getName());
187 ret->setDescription(getDescription());
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.
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).
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.
204 MEDCouplingFieldDouble *MEDCouplingFieldDouble::nodeToCellDiscretization() const
206 checkConsistencyLight();
207 TypeOfField tf(getTypeOfField());
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++)
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)
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>());
235 std::transform(pt,pt+nbCompo,pt,std::bind2nd(std::multiplies<double>(),1./((double)nbNodesInCell)));
238 std::ostringstream oss; oss << "MEDCouplingFieldDouble::nodeToCellDiscretization : Cell id #" << i << " has been detected to have no nodes !";
239 throw INTERP_KERNEL::Exception(oss.str());
243 ret->setArrays(outArrs);
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.).
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).
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.
260 MEDCouplingFieldDouble *MEDCouplingFieldDouble::cellToNodeDiscretization() const
262 checkConsistencyLight();
263 TypeOfField tf(getTypeOfField());
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++)
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];
285 ret->setArrays(outArrs);
290 * Returns a string describing \a this field. The string includes info on
293 * - \ref MEDCouplingSpatialDisc "spatial discretization",
294 * - \ref MEDCouplingTemporalDisc "time discretization",
297 * - contents of data arrays.
299 * \return std::string - the string describing \a this field.
301 std::string MEDCouplingFieldDouble::advancedRepr() const
303 std::ostringstream ret;
304 ret << "FieldDouble with name : \"" << getName() << "\"\n";
305 ret << "Description of field is : \"" << getDescription() << "\"\n";
307 { ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; }
309 { ret << "FieldDouble has no space discretization set !\n"; }
311 { ret << "FieldDouble time discretization is : " << timeDiscr()->getStringRepr() << "\n"; }
313 { ret << "FieldDouble has no time discretization set !\n"; }
315 ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
317 ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr();
319 ret << "Mesh support information : No mesh set !\n";
320 std::vector<DataArrayDouble *> arrays;
321 timeDiscr()->getArrays(arrays);
323 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++)
325 ret << "Array #" << arrayId << " :\n__________\n";
327 (*iter)->reprWithoutNameStream(ret);
329 ret << "Array empty !";
335 std::string MEDCouplingFieldDouble::writeVTK(const std::string& fileName, bool isBinary) const
337 std::vector<const MEDCouplingFieldDouble *> fs(1,this);
338 return MEDCouplingFieldDouble::WriteVTK(fileName,fs,isBinary);
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.
346 bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const
348 if(!MEDCouplingField::areCompatibleForMerge(other))
350 const MEDCouplingFieldDouble *otherC(dynamic_cast<const MEDCouplingFieldDouble *>(other));
353 if(!timeDiscr()->areCompatible(otherC->timeDiscr()))
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.
362 bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const
364 if(!MEDCouplingField::areStrictlyCompatible(other))
366 if(!timeDiscr()->areCompatibleForMeld(other->timeDiscr()))
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.
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".
390 void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps)
392 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
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);
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.
425 void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps)
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++)
433 _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter);
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
446 * \throw If the data array is not set.
447 * \throw If \a this->getNumberOfComponents() != 1.
449 DataArrayInt *MEDCouplingFieldDouble::findIdsInRange(double vmin, double vmax) const
452 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::findIdsInRange : no default array set !");
453 return getArray()->findIdsInRange(vmin,vmax);
457 typename Traits<U>::FieldType *ConvertToUField(const MEDCouplingFieldDouble *self)
459 MCAuto<MEDCouplingFieldTemplate> tmp(MEDCouplingFieldTemplate::New(*self));
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);
466 MCAuto<typename Traits<U>::ArrayType> arr(self->getArray()->convertToOtherTypeOfArr<U>());
472 MEDCouplingFieldInt *MEDCouplingFieldDouble::convertToIntField() const
474 return ConvertToUField<int>(this);
477 MEDCouplingFieldFloat *MEDCouplingFieldDouble::convertToFloatField() const
479 return ConvertToUField<float>(this);
482 MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(type,MEDCouplingTimeDiscretization::New(td))
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 ! **
489 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(ft,MEDCouplingTimeDiscretization::New(td),false)
493 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCpy):MEDCouplingFieldT<double>(other,deepCpy)
497 MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingFieldT<double>(type,n,td)
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
509 double MEDCouplingFieldDouble::accumulate(int compId) const
512 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
513 return getArray()->accumulate(compId);
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
521 * \throw If the data array is not set.
523 void MEDCouplingFieldDouble::accumulate(double *res) const
526 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
527 getArray()->accumulate(res);
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.
538 double MEDCouplingFieldDouble::getMaxValue() const
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++)
550 ret=std::max(ret,(*iter)->getMaxValue(loc));
554 throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !");
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.
568 double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const
570 std::vector<DataArrayDouble *> arrays;
571 timeDiscr()->getArrays(arrays);
572 double ret(-std::numeric_limits<double>::max());
573 bool isExistingArr=false;
575 MCAuto<DataArrayInt> ret1;
576 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
582 ret=std::max(ret,(*iter)->getMaxValue2(tmp));
583 MCAuto<DataArrayInt> tmpSafe(tmp);
584 if(!((const DataArrayInt *)ret1))
589 throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !");
590 tupleIds=ret1.retn();
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.
602 double MEDCouplingFieldDouble::getMinValue() const
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++)
614 ret=std::min(ret,(*iter)->getMinValue(loc));
618 throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !");
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.
632 double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const
634 std::vector<DataArrayDouble *> arrays;
635 timeDiscr()->getArrays(arrays);
636 double ret(-std::numeric_limits<double>::max());
637 bool isExistingArr=false;
639 MCAuto<DataArrayInt> ret1;
640 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
646 ret=std::max(ret,(*iter)->getMinValue2(tmp));
647 MCAuto<DataArrayInt> tmpSafe(tmp);
648 if(!((const DataArrayInt *)ret1))
653 throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !");
654 tupleIds=ret1.retn();
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.
664 double MEDCouplingFieldDouble::getAverageValue() const
667 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !");
668 return getArray()->getAverageValue();
672 * This method returns the euclidean norm of \a this field.
674 * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]}
676 * \throw If the data array is not set.
678 double MEDCouplingFieldDouble::norm2() const
681 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !");
682 return getArray()->norm2();
686 * This method returns the max norm of \a this field.
688 * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
690 * \throw If the data array is not set.
692 double MEDCouplingFieldDouble::normMax() const
695 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
696 return getArray()->normMax();
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.
711 void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const
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));
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() ).
737 double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const
739 int nbComps=getArray()->getNumberOfComponents();
740 if(compId<0 || compId>=nbComps)
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());
745 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
746 getWeightedAverageValue(res,isWAbs);
751 * Returns the \c normL1 of values of a given component of \a this field:
753 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
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() ).
761 double MEDCouplingFieldDouble::normL1(int compId) const
764 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1 !");
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)
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());
773 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
774 _type->normL1(_mesh,getArray(),res);
779 * Returns the \c normL1 of values of each component of \a this field:
781 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
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.
788 void MEDCouplingFieldDouble::normL1(double *res) const
791 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
793 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
794 _type->normL1(_mesh,getArray(),res);
798 * Returns the \c normL2 of values of a given component of \a this field:
800 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
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() ).
808 double MEDCouplingFieldDouble::normL2(int compId) const
811 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
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)
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());
820 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
821 _type->normL2(_mesh,getArray(),res);
826 * Returns the \c normL2 of values of each component of \a this field:
828 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
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.
835 void MEDCouplingFieldDouble::normL2(double *res) const
838 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
840 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
841 _type->normL2(_mesh,getArray(),res);
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() ).
858 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const
861 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
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)
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());
870 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
871 _type->integral(_mesh,getArray(),isWAbs,res);
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.
889 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const
892 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
894 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral2 !");
895 _type->integral(_mesh,getArray(),isWAbs,res);
899 * Returns a value at a given cell of a structured mesh. The cell is specified by its
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.
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".
918 void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const
920 const DataArrayDouble *arr=timeDiscr()->getArray();
922 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
924 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
925 _type->getValueOnPos(arr,_mesh,i,j,k,res);
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.
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".
942 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const
944 const DataArrayDouble *arr=timeDiscr()->getArray();
946 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
948 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
949 _type->getValueOn(arr,_mesh,spaceLoc,res);
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.
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".
970 DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const
972 const DataArrayDouble *arr=timeDiscr()->getArray();
974 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
976 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnMulti !");
977 return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
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.
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".
997 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const
999 std::vector< const DataArrayDouble *> arrs=timeDiscr()->getArraysForTime(time);
1001 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
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++)
1007 int sz=(int)res2.size();
1008 res2.resize(sz+(*iter)->getNumberOfComponents());
1009 _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]);
1011 timeDiscr()->getValueForTime(time,res2,res);
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.
1022 void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
1024 timeDiscr()->applyLin(a,b,compoId);
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.
1034 void MEDCouplingFieldDouble::applyLin(double a, double b)
1036 timeDiscr()->applyLin(a,b);
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.
1044 MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value)
1047 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
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);
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
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.
1065 * \if ENABLE_EXAMPLES
1066 * \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example".
1069 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func)
1072 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
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);
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.)
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.
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".
1116 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func)
1119 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
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);
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.)
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.
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".
1165 void MEDCouplingFieldDouble::fillFromAnalyticCompo(int nbOfComp, const std::string& func)
1168 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
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);
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.)
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.
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".
1214 void MEDCouplingFieldDouble::fillFromAnalyticNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1217 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
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);
1225 * Modifies values of \a this field by applying a C function to each tuple of all
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.
1232 * \if ENABLE_EXAMPLES
1233 * \ref cpp_mcfielddouble_applyFunc_c_func "Here is a C++ example".
1236 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
1238 timeDiscr()->applyFunc(nbOfComp,func);
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.
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".
1255 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
1258 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
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);
1266 * Modifies values of \a this field by applying a function to each tuple of all
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.)
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.
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".
1297 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func)
1299 timeDiscr()->applyFunc(nbOfComp,func);
1304 * Modifies values of \a this field by applying a function to each tuple of all
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.)
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.
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".
1337 void MEDCouplingFieldDouble::applyFuncCompo(int nbOfComp, const std::string& func)
1339 timeDiscr()->applyFuncCompo(nbOfComp,func);
1343 * Modifies values of \a this field by applying a function to each tuple of all
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.)
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.
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".
1376 void MEDCouplingFieldDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1378 timeDiscr()->applyFuncNamedCompo(nbOfComp,varsOrder,func);
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.)
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.
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".
1408 void MEDCouplingFieldDouble::applyFunc(const std::string& func)
1410 timeDiscr()->applyFunc(func);
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 !
1418 void MEDCouplingFieldDouble::applyFuncFast32(const std::string& func)
1420 timeDiscr()->applyFuncFast32(func);
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 !
1428 void MEDCouplingFieldDouble::applyFuncFast64(const std::string& func)
1430 timeDiscr()->applyFuncFast64(func);
1434 * Returns number of components in the data array. For more info on the data arrays,
1436 * \return int - the number of components in the data array.
1437 * \throw If the data array is not set.
1439 std::size_t MEDCouplingFieldDouble::getNumberOfComponents() const
1442 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
1443 return getArray()->getNumberOfComponents();
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.
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").
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.
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
1470 std::size_t MEDCouplingFieldDouble::getNumberOfTuples() const
1473 throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
1475 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getNumberOfTuples !");
1476 return _type->getNumberOfTuples(_mesh);
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
1484 * \throw If the data array is not set.
1486 std::size_t MEDCouplingFieldDouble::getNumberOfValues() const
1489 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
1490 return getArray()->getNbOfElems();
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.
1497 void MEDCouplingFieldDouble::updateTime() const
1499 MEDCouplingField::updateTime();
1500 updateTimeWith(*timeDiscr());
1503 std::size_t MEDCouplingFieldDouble::getHeapMemorySizeWithoutChildren() const
1505 return MEDCouplingField::getHeapMemorySizeWithoutChildren();
1508 std::vector<const BigMemoryObject *> MEDCouplingFieldDouble::getDirectChildrenWithNull() const
1510 std::vector<const BigMemoryObject *> ret(MEDCouplingField::getDirectChildrenWithNull());
1513 std::vector<const BigMemoryObject *> ret2(timeDiscr()->getDirectChildrenWithNull());
1514 ret.insert(ret.end(),ret2.begin(),ret2.end());
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".
1534 double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
1537 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getIJK !");
1538 return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
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.
1548 //void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
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.
1558 //void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
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.
1569 //void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs)
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.
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".
1596 void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps)
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);
1604 renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
1606 renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps);
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
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.
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".
1643 * \sa changeUnderlyingMesh().
1645 void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps)
1647 checkConsistencyLight();
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);
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
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.
1672 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals)
1674 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1676 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1678 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes !");
1679 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1682 MCAuto<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2);
1683 if(!ret)//no nodes have been merged.
1685 std::vector<DataArrayDouble *> arrays;
1686 timeDiscr()->getArrays(arrays);
1687 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1689 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
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
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
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.
1711 bool MEDCouplingFieldDouble::mergeNodesCenter(double eps, double epsOnVals)
1713 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1715 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1717 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodesCenter !");
1718 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1721 MCAuto<DataArrayInt> arr=meshC2->mergeNodesCenter(eps,ret,ret2);
1722 if(!ret)//no nodes have been merged.
1724 std::vector<DataArrayDouble *> arrays;
1725 timeDiscr()->getArrays(arrays);
1726 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1728 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
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
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.
1748 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals)
1750 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1752 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
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)
1760 std::vector<DataArrayDouble *> arrays;
1761 timeDiscr()->getArrays(arrays);
1762 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1764 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
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
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.
1789 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals)
1791 const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
1793 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipConnectivity : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
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)
1801 std::vector<DataArrayDouble *> arrays;
1802 timeDiscr()->getArrays(arrays);
1803 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1805 _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter);
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.
1816 * \return a newly allocated field double containing the result that the user should deallocate.
1818 MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const
1820 const MEDCouplingMesh *mesh=getMesh();
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);
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++)
1842 newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
1843 newArr[i]=newArr2[i];
1846 ret->setArrays(newArr);
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
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.
1865 bool MEDCouplingFieldDouble::simplexize(int policy)
1868 throw INTERP_KERNEL::Exception("No underlying mesh on this field to perform simplexize !");
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)
1877 std::vector<DataArrayDouble *> arrays;
1878 timeDiscr()->getArrays(arrays);
1879 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1881 _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter);
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.
1890 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoize(double eps) const
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;
1903 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize : only 2D, 3D surf, and 3D are supported for the moment !");
1904 return voronoizeGen(vor,eps);
1908 * \sa MEDCouplingUMesh::convertQuadraticCellsToLinear
1910 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::convertQuadraticCellsToLinear() const
1912 checkConsistencyLight();
1913 switch(getTypeOfField())
1917 const MEDCouplingMesh *mesh(getMesh());
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));
1928 ret->setMesh(umesh);
1929 ret->copyAllTinyAttrFrom(this);
1934 const MEDCouplingMesh *mesh(getMesh());
1936 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
1937 MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1938 umesh=umesh->clone(false);
1939 umesh->convertQuadraticCellsToLinear();
1941 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
1942 ret->setArray(const_cast<DataArrayDouble *>(getArray()));
1943 ret->setMesh(umesh);
1944 ret->copyAllTinyAttrFrom(this);
1949 const MEDCouplingMesh *mesh(getMesh());
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));
1956 const MEDCouplingFieldDiscretization *disc(getDiscretization());
1957 const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
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++)
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())
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());
1986 meshesV.push_back(part);
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());
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();
2009 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : Only available for fields on nodes and on cells !");
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.
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.
2022 * \sa DataArrayDouble::fromCartToCylGiven
2024 MEDCouplingFieldDouble *MEDCouplingFieldDouble::computeVectorFieldCyl(const double center[3], const double vect[3]) const
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());
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.
2047 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const
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());
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.
2070 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const
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());
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
2091 * \throw If \a this->getNumberOfComponents() != 6.
2092 * \throw If the spatial discretization of \a this field is NULL.
2094 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const
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());
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
2114 * \throw If \a this->getNumberOfComponents() != 6.
2115 * \throw If the spatial discretization of \a this field is NULL.
2117 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const
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());
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
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.
2142 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const
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());
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
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.
2167 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const
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());
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
2188 * \throw If \a this->getNumberOfComponents() != 6.
2189 * \throw If the spatial discretization of \a this field is NULL.
2191 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const
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());
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.
2213 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const
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());
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.
2233 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const
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());
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.
2257 void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue)
2259 timeDiscr()->changeNbOfComponents(newNbOfComp,dftValue);
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().
2274 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
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());
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
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().
2298 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds)
2300 timeDiscr()->setSelectedComponents(f->timeDiscr(),compoIds);
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.
2309 void MEDCouplingFieldDouble::sortPerTuple(bool asc)
2311 timeDiscr()->sortPerTuple(asc);
2315 * Creates a new MEDCouplingFieldDouble by concatenating two given fields.
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.
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".
2332 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
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 !");
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());
2348 MCAuto<MEDCouplingMesh> m=m1->mergeMyselfWith(m2);
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
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.
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".
2373 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a)
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++);
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++)
2390 { ms[i]=a[i]->getMesh()->buildUnstructured(); ms2[i]=ms[i]; }
2392 { ms[i]=0; ms2[i]=0; }
2393 tds[i]=a[i]->timeDiscr();
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());
2402 MCAuto<MEDCouplingUMesh> m(MEDCouplingUMesh::MergeUMeshes(ms2));
2403 m->copyTinyInfoFrom(ms2[0]);
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
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
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()
2424 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *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());
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
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.
2451 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
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());
2465 * Returns a new MEDCouplingFieldDouble containing a cross product of two given fields,
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
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.
2482 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
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());
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
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.
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".
2512 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
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());
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
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.
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".
2542 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
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());
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
2561 * \throw If the spatial discretization of \a this field is NULL.
2562 * \throw If a data array is not allocated.
2564 MEDCouplingFieldDouble *MEDCouplingFieldDouble::negate() const
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());
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
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.
2588 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
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());
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.
2611 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other)
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());
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
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.
2632 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
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());
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.
2655 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other)
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());
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
2671 * _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, 0 ].
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
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.
2683 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
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());
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 ].
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
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.
2717 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other)
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());
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 ].
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
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.
2744 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
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());
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 ].
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.
2774 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other)
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());
2784 * Directly called by MEDCouplingFieldDouble::operator^.
2786 * \sa MEDCouplingFieldDouble::operator^
2788 MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
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());
2802 * Directly call MEDCouplingFieldDouble::PowFields static method.
2804 * \sa MEDCouplingFieldDouble::PowFields
2806 MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const
2808 return PowFields(this,&other);
2811 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other)
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());
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.
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".
2838 std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector<const MEDCouplingFieldDouble *>& fs, bool isBinary)
2841 return std::string();
2842 std::size_t nfs=fs.size();
2844 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field is NULL !");
2845 const MEDCouplingMesh *m=fs[0]->getMesh();
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.");
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;
2856 { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); }
2857 std::ostringstream coss,noss;
2858 for(std::size_t i=0;i<nfs;i++)
2860 const MEDCouplingFieldDouble *cur=fs[i];
2861 std::string name(cur->getName());
2864 std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
2865 throw INTERP_KERNEL::Exception(oss.str());
2867 TypeOfField typ=cur->getTypeOfField();
2869 cur->getArray()->writeVTK(coss,8,cur->getName(),byteArr);
2870 else if(typ==ON_NODES)
2871 cur->getArray()->writeVTK(noss,8,cur->getName(),byteArr);
2873 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : only node and cell fields supported for the moment !");
2875 m->writeVTKAdvanced(ret,coss.str(),noss.str(),byteArr);
2879 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoizeGen(const Voronizer *vor, double eps) const
2881 checkConsistencyLight();
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);
2892 fieldToWO=convertQuadraticCellsToLinear();
2893 inpMeshBase=fieldToWO->getMesh();
2894 inpMesh=inpMeshBase->buildUnstructured();
2896 int nbCells(inpMesh->getNumberOfCells());
2897 const MEDCouplingFieldDiscretization *disc(fieldToWO->getDiscretization());
2898 const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
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++)
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());
2913 MCAuto<MEDCouplingUMesh> coo3(MEDCouplingUMesh::Build0DMeshFromCoords(coo2));
2915 MCAuto<MEDCouplingUMesh> vorCellsForCurDisc(vor->doIt(mesh,coo2,eps));
2916 std::vector<int> ids;
2917 MCAuto<DataArrayDouble> ptsInReal;
2918 disc2->getCellIdsHavingGaussLocalization(i,ids);
2920 MCAuto<MEDCouplingUMesh> subMesh(inpMesh->buildPartOfMySelf(&ids[0],&ids[0]+ids.size()));
2921 ptsInReal=gl.localizePtsInRefCooForEachCell(vorCellsForCurDisc->getCoords(),subMesh);
2923 int nbPtsPerCell(vorCellsForCurDisc->getNumberOfNodes());
2924 for(std::size_t j=0;j<ids.size();j++)
2926 MCAuto<MEDCouplingUMesh> elt(vorCellsForCurDisc->clone(false));
2927 MCAuto<DataArrayDouble> coo4(ptsInReal->selectByTupleIdSafeSlice(j*nbPtsPerCell,(j+1)*nbPtsPerCell,1));
2928 elt->setCoords(coo4);
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);
2938 MCAuto<DataArrayDouble> arr(fieldToWO->getArray()->deepCopy());
2939 onCells->setArray(arr);
2941 onCells->setTimeUnit(getTimeUnit());
2944 double a(getTime(b,c));
2945 onCells->setTime(a,b,c);
2947 onCells->setName(getName());
2951 MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr()
2953 MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
2956 MEDCouplingTimeDiscretization *retc(dynamic_cast<MEDCouplingTimeDiscretization *>(ret));
2958 throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");
2962 const MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr() const
2964 const MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
2967 const MEDCouplingTimeDiscretization *retc(dynamic_cast<const MEDCouplingTimeDiscretization *>(ret));
2969 throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");