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"
32 #include "MEDCouplingMemArray.txx"
34 #include "InterpKernelAutoPtr.hxx"
35 #include "InterpKernelGaussCoords.hxx"
42 using namespace MEDCoupling;
44 template class MEDCoupling::MEDCouplingFieldT<double>;
47 * Creates a new MEDCouplingFieldDouble, of given spatial type and time discretization.
48 * For more info, see \ref MEDCouplingFirstSteps3.
49 * \param [in] type - the type of spatial discretization of the created field, one of
50 * (\ref MEDCoupling::ON_CELLS "ON_CELLS",
51 * \ref MEDCoupling::ON_NODES "ON_NODES",
52 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT",
53 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE",
54 * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR").
55 * \param [in] td - the type of time discretization of the created field, one of
56 * (\ref MEDCoupling::NO_TIME "NO_TIME",
57 * \ref MEDCoupling::ONE_TIME "ONE_TIME",
58 * \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME",
59 * \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
60 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
61 * caller is to delete this field using decrRef() as it is no more needed.
63 MEDCouplingFieldDouble* MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td)
65 return new MEDCouplingFieldDouble(type,td);
69 * Creates a new MEDCouplingFieldDouble, of a given time discretization and with a
70 * spatial type and supporting mesh copied from a given
71 * \ref MEDCouplingFieldTemplatesPage "field template".
72 * For more info, see \ref MEDCouplingFirstSteps3.
73 * \warning This method does not deeply copy neither the mesh nor the spatial
74 * discretization. Only a shallow copy (reference) is done for the mesh and the spatial
76 * \param [in] ft - the \ref MEDCouplingFieldTemplatesPage "field template" defining
77 * the spatial discretization and the supporting mesh.
78 * \param [in] td - the type of time discretization of the created field, one of
79 * (\ref MEDCoupling::NO_TIME "NO_TIME",
80 * \ref MEDCoupling::ONE_TIME "ONE_TIME",
81 * \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME",
82 * \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
83 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
84 * caller is to delete this field using decrRef() as it is no more needed.
86 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td)
88 return new MEDCouplingFieldDouble(ft,td);
92 * Sets a time \a unit of \a this field. For more info, see \ref MEDCouplingFirstSteps3.
93 * \param [in] unit \a unit (string) in which time is measured.
95 //void MEDCouplingFieldDouble::setTimeUnit(const std::string& unit)
98 * Returns a time unit of \a this field.
99 * \return a string describing units in which time is measured.
101 //std::string MEDCouplingFieldDouble::getTimeUnit() const
105 * This method if possible the time information (time unit, time iteration, time unit and time value) with its support
106 * that is to say its mesh.
108 * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is
111 void MEDCouplingFieldDouble::synchronizeTimeWithSupport()
113 timeDiscr()->synchronizeTimeWith(_mesh);
117 * Returns a new MEDCouplingFieldDouble which is a copy of \a this one. The data
118 * of \a this field is copied either deep or shallow depending on \a recDeepCpy
119 * parameter. But the underlying mesh is always shallow copied.
120 * Data that can be copied either deeply or shallow are:
121 * - \ref MEDCouplingTemporalDisc "temporal discretization" data that holds array(s)
123 * - \ref MEDCouplingSpatialDisc "a spatial discretization".
125 * \c clone(false) is rather dedicated for advanced users that want to limit the amount
126 * of memory. It allows the user to perform methods like operator+(), operator*()
127 * etc. with \a this and the returned field. If the user wants to duplicate deeply the
128 * underlying mesh he should call cloneWithMesh() method or deepCopy() instead.
129 * \warning The underlying \b mesh of the returned field is **always the same**
130 * (pointer) as \a this one **whatever the value** of \a recDeepCpy parameter.
131 * \param [in] recDeepCpy - if \c true, the copy of the underlying data arrays is
132 * deep, else all data arrays of \a this field are shared by the new field.
133 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The
134 * caller is to delete this field using decrRef() as it is no more needed.
135 * \sa cloneWithMesh()
137 MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
139 return new MEDCouplingFieldDouble(*this,recDeepCpy);
143 * Returns a new MEDCouplingFieldDouble which is a deep copy of \a this one **including
145 * The result of this method is exactly the same as that of \c cloneWithMesh(true).
146 * So the resulting field can not be used together with \a this one in the methods
147 * like operator+(), operator*() etc. To avoid deep copying the underlying mesh,
148 * the user can call clone().
149 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The
150 * caller is to delete this field using decrRef() as it is no more needed.
151 * \sa cloneWithMesh()
153 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCopy() const
155 return cloneWithMesh(true);
159 * Creates a new MEDCouplingFieldDouble of given
160 * \ref MEDCouplingTemporalDisc "temporal discretization". The result field either
161 * shares the data array(s) with \a this field, or holds a deep copy of it, depending on
162 * \a deepCopy parameter. But the underlying \b mesh is always **shallow copied**.
163 * \param [in] td - the type of time discretization of the created field, one of
164 * (\ref MEDCoupling::NO_TIME "NO_TIME",
165 * \ref MEDCoupling::ONE_TIME "ONE_TIME",
166 * \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME",
167 * \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
168 * \param [in] deepCopy - if \c true, the copy of the underlying data arrays is
169 * deep, else all data arrays of \a this field are shared by the new field.
170 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
171 * caller is to delete this field using decrRef() as it is no more needed.
173 * \if ENABLE_EXAMPLES
174 * \ref cpp_mcfielddouble_buildNewTimeReprFromThis "Here is a C++ example."<br>
175 * \ref py_mcfielddouble_buildNewTimeReprFromThis "Here is a Python example."
179 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const
181 MEDCouplingTimeDiscretization *tdo=timeDiscr()->buildNewTimeReprFromThis(td,deepCpy);
182 MCAuto<MEDCouplingFieldDiscretization> disc;
185 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),tdo,disc.retn()));
186 ret->setMesh(getMesh());
187 ret->setName(getName());
188 ret->setDescription(getDescription());
193 * This method converts a field on nodes (\a this) to a cell field (returned field). The conversion is a \b non \b conservative remapping !
194 * This method is useful only for users that need a fast conversion from node to cell spatial discretization. The algorithm applied is simply to attach
195 * to each cell the average of values on nodes constituting this cell.
197 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
198 * caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this.
199 * \throw If \a this spatial discretization is empty or not ON_NODES.
200 * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkConsistencyLight).
202 * \warning This method is a \b non \b conservative method of remapping from node spatial discretization to cell spatial discretization.
203 * If a conservative method of interpolation is required MEDCoupling::MEDCouplingRemapper class should be used instead with "P1P0" method.
205 MEDCouplingFieldDouble *MEDCouplingFieldDouble::nodeToCellDiscretization() const
207 checkConsistencyLight();
208 TypeOfField tf(getTypeOfField());
210 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::nodeToCellDiscretization : this field is expected to be on ON_NODES !");
211 MCAuto<MEDCouplingFieldDouble> ret(clone(false));
212 MCAuto<MEDCouplingFieldDiscretizationP0> nsp(new MEDCouplingFieldDiscretizationP0);
213 ret->setDiscretization(nsp);
214 const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkConsistencyLight call
215 int nbCells(m->getNumberOfCells());
216 std::vector<DataArrayDouble *> arrs(getArrays());
217 std::size_t sz(arrs.size());
218 std::vector< MCAuto<DataArrayDouble> > outArrsSafe(sz); std::vector<DataArrayDouble *> outArrs(sz);
219 for(std::size_t j=0;j<sz;j++)
221 int nbCompo(arrs[j]->getNumberOfComponents());
222 outArrsSafe[j]=DataArrayDouble::New(); outArrsSafe[j]->alloc(nbCells,nbCompo);
223 outArrsSafe[j]->copyStringInfoFrom(*arrs[j]);
224 outArrs[j]=outArrsSafe[j];
225 double *pt(outArrsSafe[j]->getPointer());
226 const double *srcPt(arrs[j]->begin());
227 for(int i=0;i<nbCells;i++,pt+=nbCompo)
229 std::vector<int> nodeIds;
230 m->getNodeIdsOfCell(i,nodeIds);
231 std::fill(pt,pt+nbCompo,0.);
232 std::size_t nbNodesInCell(nodeIds.size());
233 for(std::size_t k=0;k<nbNodesInCell;k++)
234 std::transform(srcPt+nodeIds[k]*nbCompo,srcPt+(nodeIds[k]+1)*nbCompo,pt,pt,std::plus<double>());
236 std::transform(pt,pt+nbCompo,pt,std::bind2nd(std::multiplies<double>(),1./((double)nbNodesInCell)));
239 std::ostringstream oss; oss << "MEDCouplingFieldDouble::nodeToCellDiscretization : Cell id #" << i << " has been detected to have no nodes !";
240 throw INTERP_KERNEL::Exception(oss.str());
244 ret->setArrays(outArrs);
249 * This method converts a field on cell (\a this) to a node field (returned field). The conversion is a \b non \b conservative remapping !
250 * This method is useful only for users that need a fast conversion from cell to node spatial discretization. The algorithm applied is simply to attach
251 * to each node the average of values on cell sharing this node. If \a this lies on a mesh having orphan nodes the values applied on them will be NaN (division by 0.).
253 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
254 * caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this.
255 * \throw If \a this spatial discretization is empty or not ON_CELLS.
256 * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkConsistencyLight).
258 * \warning This method is a \b non \b conservative method of remapping from cell spatial discretization to node spatial discretization.
259 * If a conservative method of interpolation is required MEDCoupling::MEDCouplingRemapper class should be used instead with "P0P1" method.
261 MEDCouplingFieldDouble *MEDCouplingFieldDouble::cellToNodeDiscretization() const
263 checkConsistencyLight();
264 TypeOfField tf(getTypeOfField());
266 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::cellToNodeDiscretization : this field is expected to be on ON_CELLS !");
267 MCAuto<MEDCouplingFieldDouble> ret(clone(false));
268 MCAuto<MEDCouplingFieldDiscretizationP1> nsp(new MEDCouplingFieldDiscretizationP1);
269 ret->setDiscretization(nsp);
270 const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkConsistencyLight call
271 MCAuto<DataArrayInt> rn(DataArrayInt::New()),rni(DataArrayInt::New());
272 m->getReverseNodalConnectivity(rn,rni);
273 MCAuto<DataArrayInt> rni2(rni->deltaShiftIndex());
274 MCAuto<DataArrayDouble> rni3(rni2->convertToDblArr()); rni2=0;
275 std::vector<DataArrayDouble *> arrs(getArrays());
276 std::size_t sz(arrs.size());
277 std::vector< MCAuto<DataArrayDouble> > outArrsSafe(sz); std::vector<DataArrayDouble *> outArrs(sz);
278 for(std::size_t j=0;j<sz;j++)
280 MCAuto<DataArrayDouble> tmp(arrs[j]->selectByTupleIdSafe(rn->begin(),rn->end()));
281 outArrsSafe[j]=(tmp->accumulatePerChunck(rni->begin(),rni->end())); tmp=0;
282 outArrsSafe[j]->divideEqual(rni3);
283 outArrsSafe[j]->copyStringInfoFrom(*arrs[j]);
284 outArrs[j]=outArrsSafe[j];
286 ret->setArrays(outArrs);
291 * Returns a string describing \a this field. The string includes info on
294 * - \ref MEDCouplingSpatialDisc "spatial discretization",
295 * - \ref MEDCouplingTemporalDisc "time discretization",
298 * - contents of data arrays.
300 * \return std::string - the string describing \a this field.
302 std::string MEDCouplingFieldDouble::advancedRepr() const
304 std::ostringstream ret;
305 ret << "FieldDouble with name : \"" << getName() << "\"\n";
306 ret << "Description of field is : \"" << getDescription() << "\"\n";
308 { ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; }
310 { ret << "FieldDouble has no space discretization set !\n"; }
312 { ret << "FieldDouble time discretization is : " << timeDiscr()->getStringRepr() << "\n"; }
314 { ret << "FieldDouble has no time discretization set !\n"; }
316 ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
318 ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr();
320 ret << "Mesh support information : No mesh set !\n";
321 std::vector<DataArrayDouble *> arrays;
322 timeDiscr()->getArrays(arrays);
324 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++)
326 ret << "Array #" << arrayId << " :\n__________\n";
328 (*iter)->reprWithoutNameStream(ret);
330 ret << "Array empty !";
336 std::string MEDCouplingFieldDouble::writeVTK(const std::string& fileName, bool isBinary) const
338 std::vector<const MEDCouplingFieldDouble *> fs(1,this);
339 return MEDCouplingFieldDouble::WriteVTK(fileName,fs,isBinary);
343 * This method states if \a this and 'other' are compatibles each other before performing any treatment.
344 * This method is good for methods like : mergeFields.
345 * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields.
347 bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const
349 if(!MEDCouplingField::areCompatibleForMerge(other))
351 const MEDCouplingFieldDouble *otherC(dynamic_cast<const MEDCouplingFieldDouble *>(other));
354 if(!timeDiscr()->areCompatible(otherC->timeDiscr()))
360 * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible,
361 * except that \a this and other can have different number of components.
363 bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const
365 if(!MEDCouplingField::areStrictlyCompatible(other))
367 if(!timeDiscr()->areCompatibleForMeld(other->timeDiscr()))
373 * Permutes values of \a this field according to a given permutation array for node
374 * renumbering. The underlying mesh is deeply copied and its nodes are also permuted.
375 * The number of nodes can change, contrary to renumberCells().
376 * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
377 * to be equal to \a this->getMesh()->getNumberOfNodes().
378 * \param [in] eps - a precision used to compare field values at merged nodes. If
379 * the values differ more than \a eps, an exception is thrown.
380 * \throw If the mesh is not set.
381 * \throw If the spatial discretization of \a this field is NULL.
382 * \throw If \a check == \c true and \a old2NewBg contains equal ids.
383 * \throw If mesh nature does not allow renumbering (e.g. structured mesh).
384 * \throw If values at merged nodes deffer more than \a eps.
386 * \if ENABLE_EXAMPLES
387 * \ref cpp_mcfielddouble_renumberNodes "Here is a C++ example".<br>
388 * \ref py_mcfielddouble_renumberNodes "Here is a Python example".
391 void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps)
393 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
395 throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !");
396 int nbOfNodes=meshC->getNumberOfNodes();
397 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
398 int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1;
399 renumberNodesWithoutMesh(old2NewBg,newNbOfNodes,eps);
400 meshC2->renumberNodes(old2NewBg,newNbOfNodes);
405 * Permutes values of \a this field according to a given permutation array for nodes
406 * renumbering. The underlying mesh is \b not permuted.
407 * The number of nodes can change, contrary to renumberCells().
408 * A given epsilon specifies a threshold of error in case of two nodes are merged but
409 * the difference of values on these nodes are higher than \a eps.
410 * This method performs a part of job of renumberNodes(), excluding node renumbering
411 * in mesh. The reasonable use of this
412 * method is only for multi-field instances lying on the same mesh to avoid a
413 * systematic duplication and renumbering of _mesh attribute.
414 * \warning Use this method with a lot of care!
415 * \warning In case of an exception thrown, the contents of the data array can be
416 * partially modified until the exception occurs.
417 * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
418 * to be equal to \a this->getMesh()->getNumberOfNodes().
419 * \param [in] newNbOfNodes - a number of nodes in the mesh after renumbering.
420 * \param [in] eps - a precision used to compare field values at merged nodes. If
421 * the values differ more than \a eps, an exception is thrown.
422 * \throw If the mesh is not set.
423 * \throw If the spatial discretization of \a this field is NULL.
424 * \throw If values at merged nodes deffer more than \a eps.
426 void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps)
429 throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !");
430 std::vector<DataArrayDouble *> arrays;
431 timeDiscr()->getArrays(arrays);
432 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
434 _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter);
438 * Returns all tuple ids of \a this scalar field that fit the range [\a vmin,
439 * \a vmax]. This method calls DataArrayDouble::findIdsInRange().
440 * \param [in] vmin - a lower boundary of the range. Tuples with values less than \a
441 * vmin are not included in the result array.
442 * \param [in] vmax - an upper boundary of the range. Tuples with values more than \a
443 * vmax are not included in the result array.
444 * \return DataArrayInt * - a new instance of DataArrayInt holding ids of selected
445 * tuples. The caller is to delete this array using decrRef() as it is no
447 * \throw If the data array is not set.
448 * \throw If \a this->getNumberOfComponents() != 1.
450 DataArrayInt *MEDCouplingFieldDouble::findIdsInRange(double vmin, double vmax) const
453 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::findIdsInRange : no default array set !");
454 return getArray()->findIdsInRange(vmin,vmax);
458 typename Traits<U>::FieldType *ConvertToUField(const MEDCouplingFieldDouble *self)
460 MCAuto<MEDCouplingFieldTemplate> tmp(MEDCouplingFieldTemplate::New(*self));
462 double t0(self->getTime(t1,t2));
463 MCAuto<typename Traits<U>::FieldType > ret(Traits<U>::FieldType::New(*tmp,self->getTimeDiscretization()));
464 ret->setTime(t0,t1,t2);
467 MCAuto<typename Traits<U>::ArrayType> arr(self->getArray()->convertToOtherTypeOfArr<U>());
473 MEDCouplingFieldInt *MEDCouplingFieldDouble::convertToIntField() const
475 return ConvertToUField<int>(this);
478 MEDCouplingFieldFloat *MEDCouplingFieldDouble::convertToFloatField() const
480 return ConvertToUField<float>(this);
483 MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(type,MEDCouplingTimeDiscretization::New(td))
488 * ** WARINING : This method do not deeply copy neither mesh nor spatial discretization. Only a shallow copy (reference) is done for mesh and spatial discretization ! **
490 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(ft,MEDCouplingTimeDiscretization::New(td),false)
494 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCpy):MEDCouplingFieldT<double>(other,deepCpy)
498 MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingFieldT<double>(type,n,td)
503 * Accumulate values of a given component of \a this field.
504 * \param [in] compId - the index of the component of interest.
505 * \return double - a sum value of *compId*-th component.
506 * \throw If the data array is not set.
507 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
510 double MEDCouplingFieldDouble::accumulate(int compId) const
513 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
514 return getArray()->accumulate(compId);
518 * Accumulates values of each component of \a this array.
519 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
520 * by the caller, that is filled by this method with sum value for each
522 * \throw If the data array is not set.
524 void MEDCouplingFieldDouble::accumulate(double *res) const
527 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
528 getArray()->accumulate(res);
532 * Returns the maximal value within \a this scalar field. Values of all arrays stored
533 * in \a this->_time_discr are checked.
534 * \return double - the maximal value among all values of \a this field.
535 * \throw If \a this->getNumberOfComponents() != 1
536 * \throw If the data array is not set.
537 * \throw If there is an empty data array in \a this field.
539 double MEDCouplingFieldDouble::getMaxValue() const
541 std::vector<DataArrayDouble *> arrays;
542 timeDiscr()->getArrays(arrays);
543 double ret(-std::numeric_limits<double>::max());
544 bool isExistingArr=false;
545 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
551 ret=std::max(ret,(*iter)->getMaxValue(loc));
555 throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !");
560 * Returns the maximal value and all its locations within \a this scalar field.
561 * Only the first of available data arrays is checked.
562 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
563 * tuples holding the maximal value. The caller is to delete it using
564 * decrRef() as it is no more needed.
565 * \return double - the maximal value among all values of the first array of \a this filed.
566 * \throw If \a this->getNumberOfComponents() != 1.
567 * \throw If there is an empty data array in \a this field.
569 double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const
571 std::vector<DataArrayDouble *> arrays;
572 timeDiscr()->getArrays(arrays);
573 double ret(-std::numeric_limits<double>::max());
574 bool isExistingArr=false;
576 MCAuto<DataArrayInt> ret1;
577 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
583 ret=std::max(ret,(*iter)->getMaxValue2(tmp));
584 MCAuto<DataArrayInt> tmpSafe(tmp);
585 if(!((const DataArrayInt *)ret1))
590 throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !");
591 tupleIds=ret1.retn();
596 * Returns the minimal value within \a this scalar field. Values of all arrays stored
597 * in \a this->_time_discr are checked.
598 * \return double - the minimal value among all values of \a this field.
599 * \throw If \a this->getNumberOfComponents() != 1
600 * \throw If the data array is not set.
601 * \throw If there is an empty data array in \a this field.
603 double MEDCouplingFieldDouble::getMinValue() const
605 std::vector<DataArrayDouble *> arrays;
606 timeDiscr()->getArrays(arrays);
607 double ret(std::numeric_limits<double>::max());
608 bool isExistingArr=false;
609 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
615 ret=std::min(ret,(*iter)->getMinValue(loc));
619 throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !");
624 * Returns the minimal value and all its locations within \a this scalar field.
625 * Only the first of available data arrays is checked.
626 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
627 * tuples holding the minimal value. The caller is to delete it using
628 * decrRef() as it is no more needed.
629 * \return double - the minimal value among all values of the first array of \a this filed.
630 * \throw If \a this->getNumberOfComponents() != 1.
631 * \throw If there is an empty data array in \a this field.
633 double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const
635 std::vector<DataArrayDouble *> arrays;
636 timeDiscr()->getArrays(arrays);
637 double ret(-std::numeric_limits<double>::max());
638 bool isExistingArr=false;
640 MCAuto<DataArrayInt> ret1;
641 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
647 ret=std::max(ret,(*iter)->getMinValue2(tmp));
648 MCAuto<DataArrayInt> tmpSafe(tmp);
649 if(!((const DataArrayInt *)ret1))
654 throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !");
655 tupleIds=ret1.retn();
660 * Returns the average value of \a this scalar field.
661 * \return double - the average value over all values of the data array.
662 * \throw If \a this->getNumberOfComponents() != 1
663 * \throw If the data array is not set or it is empty.
665 double MEDCouplingFieldDouble::getAverageValue() const
668 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !");
669 return getArray()->getAverageValue();
673 * This method returns the euclidean norm of \a this field.
675 * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]}
677 * \throw If the data array is not set.
679 double MEDCouplingFieldDouble::norm2() const
682 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !");
683 return getArray()->norm2();
687 * This method returns the max norm of \a this field.
689 * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
691 * \throw If the data array is not set.
693 double MEDCouplingFieldDouble::normMax() const
696 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
697 return getArray()->normMax();
701 * Computes the weighted average of values of each component of \a this field, the weights being the
702 * values returned by buildMeasureField().
703 * \param [out] res - pointer to an array of result sum values, of size at least \a
704 * this->getNumberOfComponents(), that is to be allocated by the caller.
705 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by
706 * buildMeasureField(). It makes this method slower. If you are sure that all
707 * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs ==
708 * \c false to speed up the method.
709 * \throw If the mesh is not set.
710 * \throw If the data array is not set.
712 void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const
715 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
716 MCAuto<MEDCouplingFieldDouble> w=buildMeasureField(isWAbs);
717 double deno=w->getArray()->accumulate(0);
718 MCAuto<DataArrayDouble> arr=getArray()->deepCopy();
719 arr->multiplyEqual(w->getArray());
720 arr->accumulate(res);
721 int nCompo = getArray()->getNumberOfComponents();
722 std::transform(res,res+nCompo,res,std::bind2nd(std::multiplies<double>(),1./deno));
726 * Computes the weighted average of values of a given component of \a this field, the weights being the
727 * values returned by buildMeasureField().
728 * \param [in] compId - an index of the component of interest.
729 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by
730 * buildMeasureField(). It makes this method slower. If you are sure that all
731 * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs ==
732 * \c false to speed up the method.
733 * \throw If the mesh is not set.
734 * \throw If the data array is not set.
735 * \throw If \a compId is not valid.
736 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
738 double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const
740 int nbComps=getArray()->getNumberOfComponents();
741 if(compId<0 || compId>=nbComps)
743 std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
744 throw INTERP_KERNEL::Exception(oss.str());
746 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
747 getWeightedAverageValue(res,isWAbs);
752 * Returns the \c normL1 of values of a given component of \a this field:
754 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
756 * \param [in] compId - an index of the component of interest.
757 * \throw If the mesh is not set.
758 * \throw If the spatial discretization of \a this field is NULL.
759 * \throw If \a compId is not valid.
760 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
762 double MEDCouplingFieldDouble::normL1(int compId) const
765 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1 !");
767 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
768 int nbComps=getArray()->getNumberOfComponents();
769 if(compId<0 || compId>=nbComps)
771 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
772 throw INTERP_KERNEL::Exception(oss.str());
774 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
775 _type->normL1(_mesh,getArray(),res);
780 * Returns the \c normL1 of values of each component of \a this field:
782 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
784 * \param [out] res - pointer to an array of result values, of size at least \a
785 * this->getNumberOfComponents(), that is to be allocated by the caller.
786 * \throw If the mesh is not set.
787 * \throw If the spatial discretization of \a this field is NULL.
789 void MEDCouplingFieldDouble::normL1(double *res) const
792 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
794 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
795 _type->normL1(_mesh,getArray(),res);
799 * Returns the \c normL2 of values of a given component of \a this field:
801 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
803 * \param [in] compId - an index of the component of interest.
804 * \throw If the mesh is not set.
805 * \throw If the spatial discretization of \a this field is NULL.
806 * \throw If \a compId is not valid.
807 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
809 double MEDCouplingFieldDouble::normL2(int compId) const
812 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
814 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
815 int nbComps=getArray()->getNumberOfComponents();
816 if(compId<0 || compId>=nbComps)
818 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
819 throw INTERP_KERNEL::Exception(oss.str());
821 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
822 _type->normL2(_mesh,getArray(),res);
827 * Returns the \c normL2 of values of each component of \a this field:
829 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
831 * \param [out] res - pointer to an array of result values, of size at least \a
832 * this->getNumberOfComponents(), that is to be allocated by the caller.
833 * \throw If the mesh is not set.
834 * \throw If the spatial discretization of \a this field is NULL.
836 void MEDCouplingFieldDouble::normL2(double *res) const
839 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
841 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
842 _type->normL2(_mesh,getArray(),res);
846 * Computes a sum of values of a given component of \a this field multiplied by
847 * values returned by buildMeasureField().
848 * This method is useful to check the conservativity of interpolation method.
849 * \param [in] compId - an index of the component of interest.
850 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by
851 * buildMeasureField() that makes this method slower. If a user is sure that all
852 * cells of the underlying mesh have correct orientation, he can put \a isWAbs ==
853 * \c false that speeds up this method.
854 * \throw If the mesh is not set.
855 * \throw If the data array is not set.
856 * \throw If \a compId is not valid.
857 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
859 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const
862 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
864 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral !");
865 int nbComps=getArray()->getNumberOfComponents();
866 if(compId<0 || compId>=nbComps)
868 std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
869 throw INTERP_KERNEL::Exception(oss.str());
871 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
872 _type->integral(_mesh,getArray(),isWAbs,res);
877 * Computes a sum of values of each component of \a this field multiplied by
878 * values returned by buildMeasureField().
879 * This method is useful to check the conservativity of interpolation method.
880 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by
881 * buildMeasureField() that makes this method slower. If a user is sure that all
882 * cells of the underlying mesh have correct orientation, he can put \a isWAbs ==
883 * \c false that speeds up this method.
884 * \param [out] res - pointer to an array of result sum values, of size at least \a
885 * this->getNumberOfComponents(), that is to be allocated by the caller.
886 * \throw If the mesh is not set.
887 * \throw If the data array is not set.
888 * \throw If the spatial discretization of \a this field is NULL.
890 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const
893 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
895 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral2 !");
896 _type->integral(_mesh,getArray(),isWAbs,res);
900 * Returns a value at a given cell of a structured mesh. The cell is specified by its
902 * \param [in] i - a index of node coordinates array along X axis. The cell is
903 * located between the i-th and ( i + 1 )-th nodes along X axis.
904 * \param [in] j - a index of node coordinates array along Y axis. The cell is
905 * located between the j-th and ( j + 1 )-th nodes along Y axis.
906 * \param [in] k - a index of node coordinates array along Z axis. The cell is
907 * located between the k-th and ( k + 1 )-th nodes along Z axis.
908 * \param [out] res - pointer to an array returning a feild value, of size at least
909 * \a this->getNumberOfComponents(), that is to be allocated by the caller.
910 * \throw If the spatial discretization of \a this field is NULL.
911 * \throw If the mesh is not set.
912 * \throw If the mesh is not a structured one.
914 * \if ENABLE_EXAMPLES
915 * \ref cpp_mcfielddouble_getValueOnPos "Here is a C++ example".<br>
916 * \ref py_mcfielddouble_getValueOnPos "Here is a Python example".
919 void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const
921 const DataArrayDouble *arr=timeDiscr()->getArray();
923 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
925 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
926 _type->getValueOnPos(arr,_mesh,i,j,k,res);
930 * Returns a value of \a this at a given point using spatial discretization.
931 * \param [in] spaceLoc - the point of interest.
932 * \param [out] res - pointer to an array returning a feild value, of size at least
933 * \a this->getNumberOfComponents(), that is to be allocated by the caller.
934 * \throw If the spatial discretization of \a this field is NULL.
935 * \throw If the mesh is not set.
936 * \throw If \a spaceLoc is out of the spatial discretization.
938 * \if ENABLE_EXAMPLES
939 * \ref cpp_mcfielddouble_getValueOn "Here is a C++ example".<br>
940 * \ref py_mcfielddouble_getValueOn "Here is a Python example".
943 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const
945 const DataArrayDouble *arr=timeDiscr()->getArray();
947 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
949 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
950 _type->getValueOn(arr,_mesh,spaceLoc,res);
954 * Returns values of \a this at given points using spatial discretization.
955 * \param [in] spaceLoc - coordinates of points of interest in full-interlace
956 * mode. This array is to be of size ( \a nbOfPoints * \a this->getNumberOfComponents() ).
957 * \param [in] nbOfPoints - number of points of interest.
958 * \return DataArrayDouble * - a new instance of DataArrayDouble holding field
959 * values relating to the input points. This array is of size \a nbOfPoints
960 * tuples per \a this->getNumberOfComponents() components. The caller is to
961 * delete this array using decrRef() as it is no more needed.
962 * \throw If the spatial discretization of \a this field is NULL.
963 * \throw If the mesh is not set.
964 * \throw If any point in \a spaceLoc is out of the spatial discretization.
966 * \if ENABLE_EXAMPLES
967 * \ref cpp_mcfielddouble_getValueOnMulti "Here is a C++ example".<br>
968 * \ref py_mcfielddouble_getValueOnMulti "Here is a Python example".
971 DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const
973 const DataArrayDouble *arr=timeDiscr()->getArray();
975 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
977 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnMulti !");
978 return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
982 * Returns a value of \a this field at a given point at a given time using spatial discretization.
983 * If the time is not covered by \a this->_time_discr, an exception is thrown.
984 * \param [in] spaceLoc - the point of interest.
985 * \param [in] time - the time of interest.
986 * \param [out] res - pointer to an array returning a feild value, of size at least
987 * \a this->getNumberOfComponents(), that is to be allocated by the caller.
988 * \throw If the spatial discretization of \a this field is NULL.
989 * \throw If the mesh is not set.
990 * \throw If \a spaceLoc is out of the spatial discretization.
991 * \throw If \a time is not covered by \a this->_time_discr.
993 * \if ENABLE_EXAMPLES
994 * \ref cpp_mcfielddouble_getValueOn_time "Here is a C++ example".<br>
995 * \ref py_mcfielddouble_getValueOn_time "Here is a Python example".
998 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const
1000 std::vector< const DataArrayDouble *> arrs=timeDiscr()->getArraysForTime(time);
1002 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
1004 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOn !");
1005 std::vector<double> res2;
1006 for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
1008 int sz=(int)res2.size();
1009 res2.resize(sz+(*iter)->getNumberOfComponents());
1010 _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]);
1012 timeDiscr()->getValueForTime(time,res2,res);
1016 * Apply a linear function to a given component of \a this field, so that
1017 * a component value <em>(x)</em> becomes \f$ a * x + b \f$.
1018 * \param [in] a - the first coefficient of the function.
1019 * \param [in] b - the second coefficient of the function.
1020 * \param [in] compoId - the index of component to modify.
1021 * \throw If the data array(s) is(are) not set.
1023 void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
1025 timeDiscr()->applyLin(a,b,compoId);
1029 * Apply a linear function to all components of \a this field, so that
1030 * values <em>(x)</em> becomes \f$ a * x + b \f$.
1031 * \param [in] a - the first coefficient of the function.
1032 * \param [in] b - the second coefficient of the function.
1033 * \throw If the data array(s) is(are) not set.
1035 void MEDCouplingFieldDouble::applyLin(double a, double b)
1037 timeDiscr()->applyLin(a,b);
1041 * This method sets \a this to a uniform scalar field with one component.
1042 * All tuples will have the same value 'value'.
1043 * An exception is thrown if no underlying mesh is defined.
1045 MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value)
1048 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
1050 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform operator = !");
1051 int nbOfTuple=_type->getNumberOfTuples(_mesh);
1052 timeDiscr()->setOrCreateUniformValueOnAllComponents(nbOfTuple,value);
1057 * Creates data array(s) of \a this field by using a C function for value generation.
1058 * \param [in] nbOfComp - the number of components for \a this field to have.
1059 * \param [in] func - the function used to compute values of \a this field.
1060 * This function is to compute a field value basing on coordinates of value
1062 * \throw If the mesh is not set.
1063 * \throw If \a func returns \c false.
1064 * \throw If the spatial discretization of \a this field is NULL.
1066 * \if ENABLE_EXAMPLES
1067 * \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example".
1070 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func)
1073 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1075 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
1076 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1077 timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
1081 * Creates data array(s) of \a this field by using a function for value generation.<br>
1082 * The function is applied to coordinates of value location points. For example, if
1083 * \a this field is on cells, the function is applied to cell barycenters.
1084 * For more info on supported expressions that can be used in the function, see \ref
1085 * MEDCouplingArrayApplyFuncExpr. <br>
1086 * The function can include arbitrary named variables
1087 * (e.g. "x","y" or "va44") to refer to components of point coordinates. Names of
1088 * variables are sorted in \b alphabetical \b order to associate a variable name with a
1089 * component. For example, in the expression "2*x+z", "x" stands for the component #0
1090 * and "z" stands for the component #1 (\b not #2)!<br>
1091 * In a general case, a value resulting from the function evaluation is assigned to all
1092 * components of a field value. But there is a possibility to have its own expression for
1093 * each component within one function. For this purpose, there are predefined variable
1094 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1095 * the component #0 etc). A factor of such a variable is added to the
1096 * corresponding component only.<br>
1097 * For example, \a nbOfComp == 4, coordinates of a 3D point are (1.,3.,7.), then
1098 * - "2*x + z" produces (5.,5.,5.,5.)
1099 * - "2*x + 0*y + z" produces (9.,9.,9.,9.)
1100 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1101 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1103 * \param [in] nbOfComp - the number of components for \a this field to have.
1104 * \param [in] func - the function used to compute values of \a this field.
1105 * This function is used to compute a field value basing on coordinates of value
1106 * location point. For example, if \a this field is on cells, the function
1107 * is applied to cell barycenters.
1108 * \throw If the mesh is not set.
1109 * \throw If the spatial discretization of \a this field is NULL.
1110 * \throw If computing \a func fails.
1112 * \if ENABLE_EXAMPLES
1113 * \ref cpp_mcfielddouble_fillFromAnalytic "Here is a C++ example".<br>
1114 * \ref py_mcfielddouble_fillFromAnalytic "Here is a Python example".
1117 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func)
1120 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1122 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
1123 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1124 timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
1128 * Creates data array(s) of \a this field by using a function for value generation.<br>
1129 * The function is applied to coordinates of value location points. For example, if
1130 * \a this field is on cells, the function is applied to cell barycenters.<br>
1131 * This method differs from
1132 * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()"
1133 * by the way how variable
1134 * names, used in the function, are associated with components of coordinates of field
1135 * location points; here, a variable name corresponding to a component is retrieved from
1136 * a corresponding node coordinates array (where it is set via
1137 * DataArrayDouble::setInfoOnComponent()).<br>
1138 * For more info on supported expressions that can be used in the function, see \ref
1139 * MEDCouplingArrayApplyFuncExpr. <br>
1140 * In a general case, a value resulting from the function evaluation is assigned to all
1141 * components of a field value. But there is a possibility to have its own expression for
1142 * each component within one function. For this purpose, there are predefined variable
1143 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1144 * the component #0 etc). A factor of such a variable is added to the
1145 * corresponding component only.<br>
1146 * For example, \a nbOfComp == 4, names of spatial components are "x", "y" and "z",
1147 * coordinates of a 3D point are (1.,3.,7.), then
1148 * - "2*x + z" produces (9.,9.,9.,9.)
1149 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1150 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1152 * \param [in] nbOfComp - the number of components for \a this field to have.
1153 * \param [in] func - the function used to compute values of \a this field.
1154 * This function is used to compute a field value basing on coordinates of value
1155 * location point. For example, if \a this field is on cells, the function
1156 * is applied to cell barycenters.
1157 * \throw If the mesh is not set.
1158 * \throw If the spatial discretization of \a this field is NULL.
1159 * \throw If computing \a func fails.
1161 * \if ENABLE_EXAMPLES
1162 * \ref cpp_mcfielddouble_fillFromAnalytic2 "Here is a C++ example".<br>
1163 * \ref py_mcfielddouble_fillFromAnalytic2 "Here is a Python example".
1166 void MEDCouplingFieldDouble::fillFromAnalyticCompo(int nbOfComp, const std::string& func)
1169 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
1171 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticCompo !");
1172 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1173 timeDiscr()->fillFromAnalyticCompo(loc,nbOfComp,func);
1177 * Creates data array(s) of \a this field by using a function for value generation.<br>
1178 * The function is applied to coordinates of value location points. For example, if
1179 * \a this field is on cells, the function is applied to cell barycenters.<br>
1180 * This method differs from
1181 * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()"
1182 * by the way how variable
1183 * names, used in the function, are associated with components of coordinates of field
1184 * location points; here, a component index of a variable is defined by a
1185 * rank of the variable within the input array \a varsOrder.<br>
1186 * For more info on supported expressions that can be used in the function, see \ref
1187 * MEDCouplingArrayApplyFuncExpr.
1188 * In a general case, a value resulting from the function evaluation is assigned to all
1189 * components of a field value. But there is a possibility to have its own expression for
1190 * each component within one function. For this purpose, there are predefined variable
1191 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1192 * the component #0 etc). A factor of such a variable is added to the
1193 * corresponding component only.<br>
1194 * For example, \a nbOfComp == 4, names of
1195 * spatial components are given in \a varsOrder: ["x", "y","z"], coordinates of a
1196 * 3D point are (1.,3.,7.), then
1197 * - "2*x + z" produces (9.,9.,9.,9.)
1198 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1199 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1201 * \param [in] nbOfComp - the number of components for \a this field to have.
1202 * \param [in] func - the function used to compute values of \a this field.
1203 * This function is used to compute a field value basing on coordinates of value
1204 * location point. For example, if \a this field is on cells, the function
1205 * is applied to cell barycenters.
1206 * \throw If the mesh is not set.
1207 * \throw If the spatial discretization of \a this field is NULL.
1208 * \throw If computing \a func fails.
1210 * \if ENABLE_EXAMPLES
1211 * \ref cpp_mcfielddouble_fillFromAnalytic3 "Here is a C++ example".<br>
1212 * \ref py_mcfielddouble_fillFromAnalytic3 "Here is a Python example".
1215 void MEDCouplingFieldDouble::fillFromAnalyticNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1218 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
1220 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticNamedCompo !");
1221 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1222 timeDiscr()->fillFromAnalyticNamedCompo(loc,nbOfComp,varsOrder,func);
1226 * Modifies values of \a this field by applying a C function to each tuple of all
1228 * \param [in] nbOfComp - the number of components for \a this field to have.
1229 * \param [in] func - the function used to compute values of \a this field.
1230 * This function is to compute a field value basing on a current field value.
1231 * \throw If \a func returns \c false.
1233 * \if ENABLE_EXAMPLES
1234 * \ref cpp_mcfielddouble_applyFunc_c_func "Here is a C++ example".
1237 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
1239 timeDiscr()->applyFunc(nbOfComp,func);
1243 * Fill \a this field with a given value.<br>
1244 * This method is a specialization of other overloaded methods. When \a nbOfComp == 1
1245 * this method is equivalent to MEDCoupling::MEDCouplingFieldDouble::operator=().
1246 * \param [in] nbOfComp - the number of components for \a this field to have.
1247 * \param [in] val - the value to assign to every atomic value of \a this field.
1248 * \throw If the spatial discretization of \a this field is NULL.
1249 * \throw If the mesh is not set.
1251 * \if ENABLE_EXAMPLES
1252 * \ref cpp_mcfielddouble_applyFunc_val "Here is a C++ example".<br>
1253 * \ref py_mcfielddouble_applyFunc_val "Here is a Python example".
1256 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
1259 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
1261 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform applyFunc !");
1262 int nbOfTuple=_type->getNumberOfTuples(_mesh);
1263 timeDiscr()->setUniformValue(nbOfTuple,nbOfComp,val);
1267 * Modifies values of \a this field by applying a function to each tuple of all
1269 * For more info on supported expressions that can be used in the function, see \ref
1270 * MEDCouplingArrayApplyFuncExpr. <br>
1271 * The function can include arbitrary named variables
1272 * (e.g. "x","y" or "va44") to refer to components of a field value. Names of
1273 * variables are sorted in \b alphabetical \b order to associate a variable name with a
1274 * component. For example, in the expression "2*x+z", "x" stands for the component #0
1275 * and "z" stands for the component #1 (\b not #2)!<br>
1276 * In a general case, a value resulting from the function evaluation is assigned to all
1277 * components of a field value. But there is a possibility to have its own expression for
1278 * each component within one function. For this purpose, there are predefined variable
1279 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1280 * the component #0 etc). A factor of such a variable is added to the
1281 * corresponding component only.<br>
1282 * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then
1283 * - "2*x + z" produces (5.,5.,5.,5.)
1284 * - "2*x + 0*y + z" produces (9.,9.,9.,9.)
1285 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1286 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1288 * \param [in] nbOfComp - the number of components for \a this field to have.
1289 * \param [in] func - the function used to compute values of \a this field.
1290 * This function is to compute a field value basing on a current field value.
1291 * \throw If computing \a func fails.
1293 * \if ENABLE_EXAMPLES
1294 * \ref cpp_mcfielddouble_applyFunc "Here is a C++ example".<br>
1295 * \ref py_mcfielddouble_applyFunc "Here is a Python example".
1298 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func)
1300 timeDiscr()->applyFunc(nbOfComp,func);
1305 * Modifies values of \a this field by applying a function to each tuple of all
1307 * For more info on supported expressions that can be used in the function, see \ref
1308 * MEDCouplingArrayApplyFuncExpr. <br>
1309 * This method differs from
1310 * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()"
1311 * by the way how variable
1312 * names, used in the function, are associated with components of field values;
1313 * here, a variable name corresponding to a component is retrieved from
1314 * component information of an array (where it is set via
1315 * DataArrayDouble::setInfoOnComponent()).<br>
1316 * In a general case, a value resulting from the function evaluation is assigned to all
1317 * components of a field value. But there is a possibility to have its own expression for
1318 * each component within one function. For this purpose, there are predefined variable
1319 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1320 * the component #0 etc). A factor of such a variable is added to the
1321 * corresponding component only.<br>
1322 * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then
1323 * - "2*x + z" produces (5.,5.,5.,5.)
1324 * - "2*x + 0*y + z" produces (9.,9.,9.,9.)
1325 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1326 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1328 * \param [in] nbOfComp - the number of components for \a this field to have.
1329 * \param [in] func - the function used to compute values of \a this field.
1330 * This function is to compute a new field value basing on a current field value.
1331 * \throw If computing \a func fails.
1333 * \if ENABLE_EXAMPLES
1334 * \ref cpp_mcfielddouble_applyFunc2 "Here is a C++ example".<br>
1335 * \ref py_mcfielddouble_applyFunc2 "Here is a Python example".
1338 void MEDCouplingFieldDouble::applyFuncCompo(int nbOfComp, const std::string& func)
1340 timeDiscr()->applyFuncCompo(nbOfComp,func);
1344 * Modifies values of \a this field by applying a function to each tuple of all
1346 * This method differs from
1347 * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()"
1348 * by the way how variable
1349 * names, used in the function, are associated with components of field values;
1350 * here, a component index of a variable is defined by a
1351 * rank of the variable within the input array \a varsOrder.<br>
1352 * For more info on supported expressions that can be used in the function, see \ref
1353 * MEDCouplingArrayApplyFuncExpr.
1354 * In a general case, a value resulting from the function evaluation is assigned to all
1355 * components of a field value. But there is a possibility to have its own expression for
1356 * each component within one function. For this purpose, there are predefined variable
1357 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1358 * the component #0 etc). A factor of such a variable is added to the
1359 * corresponding component only.<br>
1360 * For example, \a nbOfComp == 4, names of
1361 * components are given in \a varsOrder: ["x", "y","z"], components of a
1362 * 3D vector are (1.,3.,7.), then
1363 * - "2*x + z" produces (9.,9.,9.,9.)
1364 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1365 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1367 * \param [in] nbOfComp - the number of components for \a this field to have.
1368 * \param [in] func - the function used to compute values of \a this field.
1369 * This function is to compute a new field value basing on a current field value.
1370 * \throw If computing \a func fails.
1372 * \if ENABLE_EXAMPLES
1373 * \ref cpp_mcfielddouble_applyFunc3 "Here is a C++ example".<br>
1374 * \ref py_mcfielddouble_applyFunc3 "Here is a Python example".
1377 void MEDCouplingFieldDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1379 timeDiscr()->applyFuncNamedCompo(nbOfComp,varsOrder,func);
1383 * Modifies values of \a this field by applying a function to each atomic value of all
1384 * data arrays. The function computes a new single value basing on an old single value.
1385 * For more info on supported expressions that can be used in the function, see \ref
1386 * MEDCouplingArrayApplyFuncExpr. <br>
1387 * The function can include **only one** arbitrary named variable
1388 * (e.g. "x","y" or "va44") to refer to a field atomic value. <br>
1389 * In a general case, a value resulting from the function evaluation is assigned to
1390 * a single field value. But there is a possibility to have its own expression for
1391 * each component within one function. For this purpose, there are predefined variable
1392 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1393 * the component #0 etc). A factor of such a variable is added to the
1394 * corresponding component only.<br>
1395 * For example, components of a field value are (1.,3.,7.), then
1396 * - "2*x - 1" produces (1.,5.,13.)
1397 * - "2*x*IVec + (x+3)*KVec" produces (2.,0.,10.)
1398 * - "2*x*IVec + (x+3)*KVec + 1" produces (3.,1.,11.)
1400 * \param [in] func - the function used to compute values of \a this field.
1401 * This function is to compute a field value basing on a current field value.
1402 * \throw If computing \a func fails.
1404 * \if ENABLE_EXAMPLES
1405 * \ref cpp_mcfielddouble_applyFunc_same_nb_comp "Here is a C++ example".<br>
1406 * \ref py_mcfielddouble_applyFunc_same_nb_comp "Here is a Python example".
1409 void MEDCouplingFieldDouble::applyFunc(const std::string& func)
1411 timeDiscr()->applyFunc(func);
1415 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1416 * The field will contain exactly the same number of components after the call.
1417 * Use is not warranted for the moment !
1419 void MEDCouplingFieldDouble::applyFuncFast32(const std::string& func)
1421 timeDiscr()->applyFuncFast32(func);
1425 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1426 * The field will contain exactly the same number of components after the call.
1427 * Use is not warranted for the moment !
1429 void MEDCouplingFieldDouble::applyFuncFast64(const std::string& func)
1431 timeDiscr()->applyFuncFast64(func);
1435 * Returns number of components in the data array. For more info on the data arrays,
1437 * \return int - the number of components in the data array.
1438 * \throw If the data array is not set.
1440 std::size_t MEDCouplingFieldDouble::getNumberOfComponents() const
1443 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
1444 return getArray()->getNumberOfComponents();
1448 * Use MEDCouplingField::getNumberOfTuplesExpected instead of this method. This method will be removed soon, because it is
1449 * confusing compared to getNumberOfComponents() and getNumberOfValues() behaviour.
1451 * Returns number of tuples in \a this field, that depends on
1452 * - the number of entities in the underlying mesh
1453 * - \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field (e.g. number
1454 * of Gauss points if \a this->getTypeOfField() ==
1455 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT").
1457 * The returned value does \b not \b depend on the number of tuples in the data array
1458 * (which has to be equal to the returned value), \b contrary to
1459 * getNumberOfComponents() and getNumberOfValues() that retrieve information from the
1460 * data array (Sorry, it is confusing !).
1461 * So \b this \b method \b behaves \b exactly \b as MEDCouplingField::getNumberOfTuplesExpected \b method.
1463 * \warning No checkConsistencyLight() is done here.
1464 * For more info on the data arrays, see \ref arrays.
1465 * \return int - the number of tuples.
1466 * \throw If the mesh is not set.
1467 * \throw If the spatial discretization of \a this field is NULL.
1468 * \throw If the spatial discretization is not fully defined.
1469 * \sa MEDCouplingField::getNumberOfTuplesExpected
1471 std::size_t MEDCouplingFieldDouble::getNumberOfTuples() const
1474 throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
1476 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getNumberOfTuples !");
1477 return _type->getNumberOfTuples(_mesh);
1481 * Returns number of atomic double values in the data array of \a this field.
1482 * For more info on the data arrays, see \ref arrays.
1483 * \return int - (number of tuples) * (number of components) of the
1485 * \throw If the data array is not set.
1487 std::size_t MEDCouplingFieldDouble::getNumberOfValues() const
1490 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
1491 return getArray()->getNbOfElems();
1495 * Sets own modification time by the most recently modified element of data (the mesh,
1496 * the data array etc). For more info, see \ref MEDCouplingTimeLabelPage.
1498 void MEDCouplingFieldDouble::updateTime() const
1500 MEDCouplingField::updateTime();
1501 updateTimeWith(*timeDiscr());
1504 std::size_t MEDCouplingFieldDouble::getHeapMemorySizeWithoutChildren() const
1506 return MEDCouplingField::getHeapMemorySizeWithoutChildren();
1509 std::vector<const BigMemoryObject *> MEDCouplingFieldDouble::getDirectChildrenWithNull() const
1511 std::vector<const BigMemoryObject *> ret(MEDCouplingField::getDirectChildrenWithNull());
1514 std::vector<const BigMemoryObject *> ret2(timeDiscr()->getDirectChildrenWithNull());
1515 ret.insert(ret.end(),ret2.begin(),ret2.end());
1521 * Returns a value of \a this field of type either
1522 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or
1523 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE".
1524 * \param [in] cellId - an id of cell of interest.
1525 * \param [in] nodeIdInCell - a node index within the cell.
1526 * \param [in] compoId - an index of component.
1527 * \return double - the field value corresponding to the specified parameters.
1528 * \throw If the data array is not set.
1529 * \throw If the mesh is not set.
1530 * \throw If the spatial discretization of \a this field is NULL.
1531 * \throw If \a this field if of type other than
1532 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or
1533 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE".
1535 double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
1538 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getIJK !");
1539 return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
1543 * Sets the data array.
1544 * \param [in] array - the data array holding values of \a this field. It's size
1545 * should correspond to the mesh and
1546 * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1547 * (see getNumberOfTuples()), but this size is not checked here.
1549 //void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
1552 * Sets the data array holding values corresponding to an end of a time interval
1553 * for which \a this field is defined.
1554 * \param [in] array - the data array holding values of \a this field. It's size
1555 * should correspond to the mesh and
1556 * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1557 * (see getNumberOfTuples()), but this size is not checked here.
1559 //void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
1562 * Sets all data arrays needed to define the field values.
1563 * \param [in] arrs - a vector of DataArrayDouble's holding values of \a this
1564 * field. Size of each array should correspond to the mesh and
1565 * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1566 * (see getNumberOfTuples()), but this size is not checked here.
1567 * \throw If number of arrays in \a arrs does not correspond to type of
1568 * \ref MEDCouplingTemporalDisc "temporal discretization" of \a this field.
1570 //void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs)
1573 * Tries to set an \a other mesh as the support of \a this field. An attempt fails, if
1574 * a current and the \a other meshes are different with use of specified equality
1575 * criteria, and then an exception is thrown.
1576 * \param [in] other - the mesh to use as the field support if this mesh can be
1577 * considered equal to the current mesh.
1578 * \param [in] levOfCheck - defines equality criteria used for mesh comparison. For
1579 * it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which
1580 * is used for mesh comparison.
1581 * \param [in] precOnMesh - a precision used to compare nodes of the two meshes.
1582 * It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith().
1583 * \param [in] eps - a precision used at node renumbering (if needed) to compare field
1584 * values at merged nodes. If the values differ more than \a eps, an
1585 * exception is thrown.
1586 * \throw If the mesh is not set.
1587 * \throw If \a other == NULL.
1588 * \throw If any of the meshes is not well defined.
1589 * \throw If the two meshes do not match.
1590 * \throw If field values at merged nodes (if any) deffer more than \a eps.
1592 * \if ENABLE_EXAMPLES
1593 * \ref cpp_mcfielddouble_changeUnderlyingMesh "Here is a C++ example".<br>
1594 * \ref py_mcfielddouble_changeUnderlyingMesh "Here is a Python example".
1597 void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps)
1599 if(_mesh==0 || other==0)
1600 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
1601 DataArrayInt *cellCor=0,*nodeCor=0;
1602 other->checkGeoEquivalWith(_mesh,levOfCheck,precOnMesh,cellCor,nodeCor);
1603 MCAuto<DataArrayInt> cellCor2(cellCor),nodeCor2(nodeCor);
1605 renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
1607 renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps);
1612 * Subtracts another field from \a this one in case when the two fields have different
1613 * supporting meshes. The subtraction is performed provided that the tho meshes can be
1614 * considered equal with use of specified equality criteria, else an exception is thrown.
1615 * If the meshes match, the mesh of \a f is set to \a this field (\a this is permuted if
1616 * necessary) and field values are subtracted. No interpolation is done here, only an
1617 * analysis of two underlying mesh is done to see if the meshes are geometrically
1619 * The job of this method consists in calling
1620 * \a this->changeUnderlyingMesh() with \a f->getMesh() as the first parameter, and then
1621 * \a this -= \a f.<br>
1622 * This method requires that \a f and \a this are coherent (checkConsistencyLight()) and that \a f
1623 * and \a this are coherent for a merge.<br>
1624 * "DM" in the method name stands for "different meshes".
1625 * \param [in] f - the field to subtract from this.
1626 * \param [in] levOfCheck - defines equality criteria used for mesh comparison. For
1627 * it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which
1628 * is used for mesh comparison.
1629 * \param [in] precOnMesh - a precision used to compare nodes of the two meshes.
1630 * It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith().
1631 * \param [in] eps - a precision used at node renumbering (if needed) to compare field
1632 * values at merged nodes. If the values differ more than \a eps, an
1633 * exception is thrown.
1634 * \throw If \a f == NULL.
1635 * \throw If any of the meshes is not set or is not well defined.
1636 * \throw If the two meshes do not match.
1637 * \throw If the two fields are not coherent for merge.
1638 * \throw If field values at merged nodes (if any) deffer more than \a eps.
1640 * \if ENABLE_EXAMPLES
1641 * \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".<br>
1642 * \ref py_mcfielddouble_substractInPlaceDM "Here is a Python example".
1644 * \sa changeUnderlyingMesh().
1646 void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps)
1648 checkConsistencyLight();
1650 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : input field is NULL !");
1651 f->checkConsistencyLight();
1652 if(!areCompatibleForMerge(f))
1653 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : Fields are not compatible ; unable to apply mergeFields on them !");
1654 changeUnderlyingMesh(f->getMesh(),levOfCheck,precOnMesh,eps);
1659 * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the
1660 * underlying mesh is replaced by a new mesh instance where the coincident nodes are merged.
1661 * \param [in] eps - a precision used to compare nodes of the two meshes.
1662 * \param [in] epsOnVals - a precision used to compare field
1663 * values at merged nodes. If the values differ more than \a epsOnVals, an
1664 * exception is thrown.
1665 * \return bool - \c true if some nodes have been merged and hence \a this field lies
1667 * \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1668 * \throw If the mesh is not well defined.
1669 * \throw If the spatial discretization of \a this field is NULL.
1670 * \throw If the data array is not set.
1671 * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
1673 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals)
1675 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1677 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1679 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes !");
1680 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1683 MCAuto<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2);
1684 if(!ret)//no nodes have been merged.
1686 std::vector<DataArrayDouble *> arrays;
1687 timeDiscr()->getArrays(arrays);
1688 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1690 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1696 * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the
1697 * underlying mesh is replaced by a new mesh instance where the coincident nodes are
1699 * In contrast to mergeNodes(), location of merged nodes is changed to be at their barycenter.
1700 * \param [in] eps - a precision used to compare nodes of the two meshes.
1701 * \param [in] epsOnVals - a precision used to compare field
1702 * values at merged nodes. If the values differ more than \a epsOnVals, an
1703 * exception is thrown.
1704 * \return bool - \c true if some nodes have been merged and hence \a this field lies
1706 * \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1707 * \throw If the mesh is not well defined.
1708 * \throw If the spatial discretization of \a this field is NULL.
1709 * \throw If the data array is not set.
1710 * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
1712 bool MEDCouplingFieldDouble::mergeNodesCenter(double eps, double epsOnVals)
1714 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1716 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1718 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodesCenter !");
1719 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1722 MCAuto<DataArrayInt> arr=meshC2->mergeNodesCenter(eps,ret,ret2);
1723 if(!ret)//no nodes have been merged.
1725 std::vector<DataArrayDouble *> arrays;
1726 timeDiscr()->getArrays(arrays);
1727 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1729 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1735 * Removes from the underlying mesh nodes not used in any cell. If some nodes are
1736 * removed, the underlying mesh is replaced by a new mesh instance where the unused
1737 * nodes are removed.<br>
1738 * \param [in] epsOnVals - a precision used to compare field
1739 * values at merged nodes. If the values differ more than \a epsOnVals, an
1740 * exception is thrown.
1741 * \return bool - \c true if some nodes have been removed and hence \a this field lies
1743 * \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1744 * \throw If the mesh is not well defined.
1745 * \throw If the spatial discretization of \a this field is NULL.
1746 * \throw If the data array is not set.
1747 * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
1749 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals)
1751 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1753 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1755 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipCoords !");
1756 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1757 int oldNbOfNodes=meshC2->getNumberOfNodes();
1758 MCAuto<DataArrayInt> arr=meshC2->zipCoordsTraducer();
1759 if(meshC2->getNumberOfNodes()!=oldNbOfNodes)
1761 std::vector<DataArrayDouble *> arrays;
1762 timeDiscr()->getArrays(arrays);
1763 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1765 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1773 * Removes duplicates of cells from the understanding mesh. If some cells are
1774 * removed, the underlying mesh is replaced by a new mesh instance where the cells
1775 * duplicates are removed.<br>
1776 * \param [in] compType - specifies a cell comparison technique. Meaning of its
1777 * valid values [0,1,2] is explained in the description of
1778 * MEDCouplingPointSet::zipConnectivityTraducer() which is called by this method.
1779 * \param [in] epsOnVals - a precision used to compare field
1780 * values at merged cells. If the values differ more than \a epsOnVals, an
1781 * exception is thrown.
1782 * \return bool - \c true if some cells have been removed and hence \a this field lies
1784 * \throw If the mesh is not an instance of MEDCouplingUMesh.
1785 * \throw If the mesh is not well defined.
1786 * \throw If the spatial discretization of \a this field is NULL.
1787 * \throw If the data array is not set.
1788 * \throw If field values at merged cells (if any) deffer more than \a epsOnVals.
1790 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals)
1792 const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
1794 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipConnectivity : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1796 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipConnectivity !");
1797 MCAuto<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCopy());
1798 std::size_t oldNbOfCells(meshC2->getNumberOfCells());
1799 MCAuto<DataArrayInt> arr=meshC2->zipConnectivityTraducer(compType);
1800 if(meshC2->getNumberOfCells()!=oldNbOfCells)
1802 std::vector<DataArrayDouble *> arrays;
1803 timeDiscr()->getArrays(arrays);
1804 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1806 _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter);
1814 * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists.
1815 * For the moment, this method is implemented for fields on cells.
1817 * \return a newly allocated field double containing the result that the user should deallocate.
1819 MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const
1821 const MEDCouplingMesh *mesh=getMesh();
1823 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !");
1824 if(getTypeOfField()!=ON_CELLS)
1825 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !");
1826 const MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1827 MCAuto<MEDCouplingFieldDouble> ret(clone(false));
1828 ret->setMesh(umesh);
1829 DataArrayInt *cellIds=0;
1830 MCAuto<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds);
1831 MCAuto<DataArrayInt> cellIds2=cellIds;
1832 ret->setMesh(mesh2);
1833 MCAuto<DataArrayInt> tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end());
1834 std::vector<DataArrayDouble *> arrays;
1835 timeDiscr()->getArrays(arrays);
1837 std::vector<DataArrayDouble *> newArr(arrays.size());
1838 std::vector< MCAuto<DataArrayDouble> > newArr2(arrays.size());
1839 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++)
1843 newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
1844 newArr[i]=newArr2[i];
1847 ret->setArrays(newArr);
1852 * Divides every cell of the underlying mesh into simplices (triangles in 2D and
1853 * tetrahedra in 3D). If some cells are divided, the underlying mesh is replaced by a new
1854 * mesh instance containing the simplices.<br>
1855 * \param [in] policy - specifies a pattern used for splitting. For its description, see
1856 * MEDCouplingUMesh::simplexize().
1857 * \return bool - \c true if some cells have been divided and hence \a this field lies
1859 * \throw If \a policy has an invalid value. For valid values, see the description of
1860 * MEDCouplingUMesh::simplexize().
1861 * \throw If MEDCouplingMesh::simplexize() is not applicable to the underlying mesh.
1862 * \throw If the mesh is not well defined.
1863 * \throw If the spatial discretization of \a this field is NULL.
1864 * \throw If the data array is not set.
1866 bool MEDCouplingFieldDouble::simplexize(int policy)
1869 throw INTERP_KERNEL::Exception("No underlying mesh on this field to perform simplexize !");
1871 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform simplexize !");
1872 int oldNbOfCells=_mesh->getNumberOfCells();
1873 MCAuto<MEDCouplingMesh> meshC2(_mesh->deepCopy());
1874 MCAuto<DataArrayInt> arr=meshC2->simplexize(policy);
1875 int newNbOfCells=meshC2->getNumberOfCells();
1876 if(oldNbOfCells==newNbOfCells)
1878 std::vector<DataArrayDouble *> arrays;
1879 timeDiscr()->getArrays(arrays);
1880 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1882 _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter);
1888 * 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.
1889 * Each Gauss points in \a this is replaced by a polygon or polyhedron cell with associated region following Voronoi algorithm.
1891 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoize(double eps) const
1893 checkConsistencyLight();
1894 const MEDCouplingMesh *mesh(getMesh());
1895 INTERP_KERNEL::AutoCppPtr<Voronizer> vor;
1896 int meshDim(mesh->getMeshDimension()),spaceDim(mesh->getSpaceDimension());
1897 if(meshDim==1 && (spaceDim==1 || spaceDim==2 || spaceDim==3))
1898 vor=new Voronizer1D;
1899 else if(meshDim==2 && (spaceDim==2 || spaceDim==3))
1900 vor=new Voronizer2D;
1901 else if(meshDim==3 && spaceDim==3)
1902 vor=new Voronizer3D;
1904 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize : only 2D, 3D surf, and 3D are supported for the moment !");
1905 return voronoizeGen(vor,eps);
1909 * \sa MEDCouplingUMesh::convertQuadraticCellsToLinear
1911 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::convertQuadraticCellsToLinear() const
1913 checkConsistencyLight();
1914 switch(getTypeOfField())
1918 const MEDCouplingMesh *mesh(getMesh());
1920 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
1921 MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1922 umesh=umesh->clone(false);
1923 umesh->convertQuadraticCellsToLinear();
1924 MCAuto<DataArrayInt> o2n(umesh->zipCoordsTraducer());
1925 MCAuto<DataArrayInt> n2o(o2n->invertArrayO2N2N2O(umesh->getNumberOfNodes()));
1926 MCAuto<DataArrayDouble> arr(getArray()->selectByTupleIdSafe(n2o->begin(),n2o->end()));
1927 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_NODES));
1929 ret->setMesh(umesh);
1930 ret->copyAllTinyAttrFrom(this);
1935 const MEDCouplingMesh *mesh(getMesh());
1937 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
1938 MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1939 umesh=umesh->clone(false);
1940 umesh->convertQuadraticCellsToLinear();
1942 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
1943 ret->setArray(const_cast<DataArrayDouble *>(getArray()));
1944 ret->setMesh(umesh);
1945 ret->copyAllTinyAttrFrom(this);
1950 const MEDCouplingMesh *mesh(getMesh());
1952 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
1953 MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1954 std::set<INTERP_KERNEL::NormalizedCellType> gt(umesh->getAllGeoTypes());
1955 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_GAUSS_PT));
1957 const MEDCouplingFieldDiscretization *disc(getDiscretization());
1958 const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
1960 throw INTERP_KERNEL::Exception("convertQuadraticCellsToLinear : Not a ON_GAUSS_PT field");
1961 std::set<INTERP_KERNEL::NormalizedCellType> gt2(umesh->getAllGeoTypes());
1962 std::vector< MCAuto<DataArrayInt> > cellIdsV;
1963 std::vector< MCAuto<MEDCouplingUMesh> > meshesV;
1964 std::vector< MEDCouplingGaussLocalization > glV;
1965 bool isZipReq(false);
1966 for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=gt.begin();it!=gt.end();it++)
1968 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it));
1969 MCAuto<DataArrayInt> cellIds(umesh->giveCellsWithType(*it));
1970 cellIdsV.push_back(cellIds);
1971 MCAuto<MEDCouplingUMesh> part(umesh->buildPartOfMySelf(cellIds->begin(),cellIds->end()));
1972 int id(disc2->getGaussLocalizationIdOfOneType(*it));
1973 const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(id));
1974 if(!cm.isQuadratic())
1981 part->convertQuadraticCellsToLinear();
1982 INTERP_KERNEL::GaussInfo gi(*it,gl.getGaussCoords(),gl.getNumberOfGaussPt(),gl.getRefCoords(),gl.getNumberOfPtsInRefCell());
1983 INTERP_KERNEL::GaussInfo gi2(gi.convertToLinear());
1984 MEDCouplingGaussLocalization gl2(gi2.getGeoType(),gi2.getRefCoords(),gi2.getGaussCoords(),gl.getWeights());
1987 meshesV.push_back(part);
1991 std::vector< const MEDCouplingUMesh * > meshesPtr(VecAutoToVecOfCstPt(meshesV));
1992 umesh=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshesPtr);
1993 std::vector< const DataArrayInt * > zeCellIds(VecAutoToVecOfCstPt(cellIdsV));
1994 MCAuto<DataArrayInt> zeIds(DataArrayInt::Aggregate(zeCellIds));
1995 umesh->renumberCells(zeIds->begin());
1996 umesh->setName(mesh->getName());
2001 ret->setArray(const_cast<DataArrayDouble *>(getArray()));
2002 ret->setMesh(umesh);
2003 for(std::vector< MEDCouplingGaussLocalization >::const_iterator it=glV.begin();it!=glV.end();it++)
2004 ret->setGaussLocalizationOnType((*it).getType(),(*it).getRefCoords(),(*it).getGaussCoords(),(*it).getWeights());
2005 ret->copyAllTinyAttrFrom(this);
2006 ret->checkConsistencyLight();
2010 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : Only available for fields on nodes and on cells !");
2015 * 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.
2016 * Finally \a this is also expected to be consistent.
2017 * In these conditions this method returns a newly created field (to be dealed by the caller).
2018 * The returned field will also 3 compo vector field be on nodes lying on the same mesh than \a this.
2020 * 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.
2021 * \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.
2023 * \sa DataArrayDouble::fromCartToCylGiven
2025 MEDCouplingFieldDouble *MEDCouplingFieldDouble::computeVectorFieldCyl(const double center[3], const double vect[3]) const
2027 checkConsistencyLight();
2028 const DataArrayDouble *coo(getMesh()->getDirectAccessOfCoordsArrIfInStructure());
2029 MEDCouplingTimeDiscretization *td(timeDiscr()->computeVectorFieldCyl(coo,center,vect));
2030 td->copyTinyAttrFrom(*timeDiscr());
2031 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2032 ret->setMesh(getMesh());
2033 ret->setName(getName());
2038 * Creates a new MEDCouplingFieldDouble filled with the doubly contracted product of
2039 * every tensor of \a this 6-componental field.
2040 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2041 * each tuple is calculated from the tuple <em>(t)</em> of \a this field as
2042 * follows: \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2043 * This new field lies on the same mesh as \a this one. The caller is to delete
2044 * this field using decrRef() as it is no more needed.
2045 * \throw If \a this->getNumberOfComponents() != 6.
2046 * \throw If the spatial discretization of \a this field is NULL.
2048 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const
2051 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform doublyContractedProduct !");
2052 MEDCouplingTimeDiscretization *td(timeDiscr()->doublyContractedProduct());
2053 td->copyTinyAttrFrom(*timeDiscr());
2054 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2055 ret->setName("DoublyContractedProduct");
2056 ret->setMesh(getMesh());
2061 * Creates a new MEDCouplingFieldDouble filled with the determinant of a square
2062 * matrix defined by every tuple of \a this field, having either 4, 6 or 9 components.
2063 * The case of 6 components corresponds to that of the upper triangular matrix.
2064 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2065 * each tuple is the determinant of matrix of the corresponding tuple of \a this
2066 * field. This new field lies on the same mesh as \a this one. The caller is to
2067 * delete this field using decrRef() as it is no more needed.
2068 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2069 * \throw If the spatial discretization of \a this field is NULL.
2071 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const
2074 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform determinant !");
2075 MEDCouplingTimeDiscretization *td(timeDiscr()->determinant());
2076 td->copyTinyAttrFrom(*timeDiscr());
2077 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2078 ret->setName("Determinant");
2079 ret->setMesh(getMesh());
2085 * Creates a new MEDCouplingFieldDouble with 3 components filled with 3 eigenvalues of
2086 * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2087 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2088 * having 3 components, whose each tuple contains the eigenvalues of the matrix of
2089 * corresponding tuple of \a this field. This new field lies on the same mesh as
2090 * \a this one. The caller is to delete this field using decrRef() as it is no
2092 * \throw If \a this->getNumberOfComponents() != 6.
2093 * \throw If the spatial discretization of \a this field is NULL.
2095 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const
2098 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenValues !");
2099 MEDCouplingTimeDiscretization *td(timeDiscr()->eigenValues());
2100 td->copyTinyAttrFrom(*timeDiscr());
2101 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2102 ret->setName("EigenValues");
2103 ret->setMesh(getMesh());
2108 * Creates a new MEDCouplingFieldDouble with 9 components filled with 3 eigenvectors of
2109 * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2110 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2111 * having 9 components, whose each tuple contains the eigenvectors of the matrix of
2112 * corresponding tuple of \a this field. This new field lies on the same mesh as
2113 * \a this one. The caller is to delete this field using decrRef() as it is no
2115 * \throw If \a this->getNumberOfComponents() != 6.
2116 * \throw If the spatial discretization of \a this field is NULL.
2118 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const
2121 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenVectors !");
2122 MEDCouplingTimeDiscretization *td(timeDiscr()->eigenVectors());
2123 td->copyTinyAttrFrom(*timeDiscr());
2124 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2125 ret->setName("EigenVectors");
2126 ret->setMesh(getMesh());
2131 * Creates a new MEDCouplingFieldDouble filled with the inverse matrix of
2132 * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2133 * components. The case of 6 components corresponds to that of the upper triangular
2135 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2136 * having the same number of components as \a this one, whose each tuple
2137 * contains the inverse matrix of the matrix of corresponding tuple of \a this
2138 * field. This new field lies on the same mesh as \a this one. The caller is to
2139 * delete this field using decrRef() as it is no more needed.
2140 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2141 * \throw If the spatial discretization of \a this field is NULL.
2143 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const
2146 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform inverse !");
2147 MEDCouplingTimeDiscretization *td(timeDiscr()->inverse());
2148 td->copyTinyAttrFrom(*timeDiscr());
2149 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2150 ret->setName("Inversion");
2151 ret->setMesh(getMesh());
2156 * Creates a new MEDCouplingFieldDouble filled with the trace of
2157 * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2158 * components. The case of 6 components corresponds to that of the upper triangular
2160 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2161 * having 1 component, whose each tuple is the trace of the matrix of
2162 * corresponding tuple of \a this field.
2163 * This new field lies on the same mesh as \a this one. The caller is to
2164 * delete this field using decrRef() as it is no more needed.
2165 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2166 * \throw If the spatial discretization of \a this field is NULL.
2168 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const
2171 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform trace !");
2172 MEDCouplingTimeDiscretization *td(timeDiscr()->trace());
2173 td->copyTinyAttrFrom(*timeDiscr());
2174 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2175 ret->setName("Trace");
2176 ret->setMesh(getMesh());
2181 * Creates a new MEDCouplingFieldDouble filled with the stress deviator tensor of
2182 * a stress tensor defined by every tuple of \a this 6-componental field.
2183 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2184 * having same number of components and tuples as \a this field,
2185 * whose each tuple contains the stress deviator tensor of the stress tensor of
2186 * corresponding tuple of \a this field. This new field lies on the same mesh as
2187 * \a this one. The caller is to delete this field using decrRef() as it is no
2189 * \throw If \a this->getNumberOfComponents() != 6.
2190 * \throw If the spatial discretization of \a this field is NULL.
2192 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const
2195 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform deviator !");
2196 MEDCouplingTimeDiscretization *td(timeDiscr()->deviator());
2197 td->copyTinyAttrFrom(*timeDiscr());
2198 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2199 ret->setName("Deviator");
2200 ret->setMesh(getMesh());
2205 * Creates a new MEDCouplingFieldDouble filled with the magnitude of
2206 * every vector of \a this field.
2207 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2208 * having one component, whose each tuple is the magnitude of the vector
2209 * of corresponding tuple of \a this field. This new field lies on the
2210 * same mesh as \a this one. The caller is to
2211 * delete this field using decrRef() as it is no more needed.
2212 * \throw If the spatial discretization of \a this field is NULL.
2214 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const
2217 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform magnitude !");
2218 MEDCouplingTimeDiscretization *td(timeDiscr()->magnitude());
2219 td->copyTinyAttrFrom(*timeDiscr());
2220 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2221 ret->setName("Magnitude");
2222 ret->setMesh(getMesh());
2227 * Creates a new scalar MEDCouplingFieldDouble filled with the maximal value among
2228 * values of every tuple of \a this field.
2229 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2230 * This new field lies on the same mesh as \a this one. The caller is to
2231 * delete this field using decrRef() as it is no more needed.
2232 * \throw If the spatial discretization of \a this field is NULL.
2234 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const
2237 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform maxPerTuple !");
2238 MEDCouplingTimeDiscretization *td(timeDiscr()->maxPerTuple());
2239 td->copyTinyAttrFrom(*timeDiscr());
2240 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2241 std::ostringstream oss;
2242 oss << "Max_" << getName();
2243 ret->setName(oss.str());
2244 ret->setMesh(getMesh());
2249 * Changes number of components in \a this field. If \a newNbOfComp is less
2250 * than \a this->getNumberOfComponents() then each tuple
2251 * is truncated to have \a newNbOfComp components, keeping first components. If \a
2252 * newNbOfComp is more than \a this->getNumberOfComponents() then
2253 * each tuple is populated with \a dftValue to have \a newNbOfComp components.
2254 * \param [in] newNbOfComp - number of components for the new field to have.
2255 * \param [in] dftValue - value assigned to new values added to \a this field.
2256 * \throw If \a this is not allocated.
2258 void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue)
2260 timeDiscr()->changeNbOfComponents(newNbOfComp,dftValue);
2264 * Creates a new MEDCouplingFieldDouble composed of selected components of \a this field.
2265 * The new MEDCouplingFieldDouble has the same number of tuples but includes components
2266 * specified by \a compoIds parameter. So that getNbOfElems() of the result field
2267 * can be either less, same or more than \a this->getNumberOfValues().
2268 * \param [in] compoIds - sequence of zero based indices of components to include
2269 * into the new field.
2270 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble that the caller
2271 * is to delete using decrRef() as it is no more needed.
2272 * \throw If a component index (\a i) is not valid:
2273 * \a i < 0 || \a i >= \a this->getNumberOfComponents().
2275 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
2278 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform keepSelectedComponents !");
2279 MEDCouplingTimeDiscretization *td(timeDiscr()->keepSelectedComponents(compoIds));
2280 td->copyTinyAttrFrom(*timeDiscr());
2281 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2282 ret->setName(getName());
2283 ret->setMesh(getMesh());
2289 * Copy all components in a specified order from another field.
2290 * The number of tuples in \a this and the other field can be different.
2291 * \param [in] f - the field to copy data from.
2292 * \param [in] compoIds - sequence of zero based indices of components, data of which is
2294 * \throw If the two fields have different number of data arrays.
2295 * \throw If a data array is set in one of fields and is not set in the other.
2296 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2297 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2299 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds)
2301 timeDiscr()->setSelectedComponents(f->timeDiscr(),compoIds);
2305 * Sorts value within every tuple of \a this field.
2306 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2307 * in descending order.
2308 * \throw If a data array is not allocated.
2310 void MEDCouplingFieldDouble::sortPerTuple(bool asc)
2312 timeDiscr()->sortPerTuple(asc);
2316 * Creates a new MEDCouplingFieldDouble by concatenating two given fields.
2318 * the first field precede values of the second field within the result field.
2319 * \param [in] f1 - the first field.
2320 * \param [in] f2 - the second field.
2321 * \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2322 * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef()
2323 * as it is no more needed.
2324 * \throw If the fields are not compatible for the merge.
2325 * \throw If the spatial discretization of \a f1 is NULL.
2326 * \throw If the time discretization of \a f1 is NULL.
2328 * \if ENABLE_EXAMPLES
2329 * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2330 * \ref py_mcfielddouble_MergeFields "Here is a Python example".
2333 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2335 if(!f1->areCompatibleForMerge(f2))
2336 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
2337 const MEDCouplingMesh *m1(f1->getMesh()),*m2(f2->getMesh());
2338 if(!f1->timeDiscr())
2339 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no time discr of f1 !");
2341 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no spatial discr of f1 !");
2342 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->aggregate(f2->timeDiscr()));
2343 td->copyTinyAttrFrom(*f1->timeDiscr());
2344 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2345 ret->setName(f1->getName());
2346 ret->setDescription(f1->getDescription());
2349 MCAuto<MEDCouplingMesh> m=m1->mergeMyselfWith(m2);
2356 * Creates a new MEDCouplingFieldDouble by concatenating all given fields.
2357 * Values of the *i*-th field precede values of the (*i*+1)-th field within the result.
2358 * If there is only one field in \a a, a deepCopy() (except time information of mesh and
2359 * field) of the field is returned.
2360 * Generally speaking the first field in \a a is used to assign tiny attributes of the
2362 * \param [in] a - a vector of fields (MEDCouplingFieldDouble) to concatenate.
2363 * \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2364 * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef()
2365 * as it is no more needed.
2366 * \throw If \a a is empty.
2367 * \throw If the fields are not compatible for the merge.
2369 * \if ENABLE_EXAMPLES
2370 * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2371 * \ref py_mcfielddouble_MergeFields "Here is a Python example".
2374 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a)
2377 throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !");
2378 std::vector< MCAuto<MEDCouplingUMesh> > ms(a.size());
2379 std::vector< const MEDCouplingUMesh *> ms2(a.size());
2380 std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
2381 std::vector<const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
2382 const MEDCouplingFieldDouble *ref=(*it++);
2384 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of NULL instance in first place of input vector !");
2385 for(;it!=a.end();it++)
2386 if(!ref->areCompatibleForMerge(*it))
2387 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2388 for(int i=0;i<(int)a.size();i++)
2391 { ms[i]=a[i]->getMesh()->buildUnstructured(); ms2[i]=ms[i]; }
2393 { ms[i]=0; ms2[i]=0; }
2394 tds[i]=a[i]->timeDiscr();
2396 MEDCouplingTimeDiscretization *td(tds[0]->aggregate(tds));
2397 td->copyTinyAttrFrom(*(a[0]->timeDiscr()));
2398 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()));
2399 ret->setName(a[0]->getName());
2400 ret->setDescription(a[0]->getDescription());
2403 MCAuto<MEDCouplingUMesh> m(MEDCouplingUMesh::MergeUMeshes(ms2));
2404 m->copyTinyInfoFrom(ms2[0]);
2411 * Creates a new MEDCouplingFieldDouble by concatenating components of two given fields.
2412 * The number of components in the result field is a sum of the number of components of
2413 * given fields. The number of tuples in the result field is same as that of each of given
2415 * Number of tuples in the given fields must be the same.
2416 * \param [in] f1 - a field to include in the result field.
2417 * \param [in] f2 - another field to include in the result field.
2418 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2419 * The caller is to delete this result field using decrRef() as it is no more
2421 * \throw If the fields are not compatible for a meld (areCompatibleForMeld()).
2422 * \throw If any of data arrays is not allocated.
2423 * \throw If \a f1->getNumberOfTuples() != \a f2->getNumberOfTuples()
2425 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2428 throw INTERP_KERNEL::Exception("MeldFields : null input pointer !");
2429 if(!f1->areCompatibleForMeld(f2))
2430 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
2431 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->meld(f2->timeDiscr()));
2432 td->copyTinyAttrFrom(*f1->timeDiscr());
2433 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2434 ret->setMesh(f1->getMesh());
2439 * Returns a new MEDCouplingFieldDouble containing a dot product of two given fields,
2440 * so that the i-th tuple of the result field is a sum of products of j-th components of
2441 * i-th tuples of given fields (\f$ f_i = \sum_{j=1}^n f1_j * f2_j \f$).
2442 * Number of tuples and components in the given fields must be the same.
2443 * \param [in] f1 - a given field.
2444 * \param [in] f2 - another given field.
2445 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2446 * The caller is to delete this result field using decrRef() as it is no more
2448 * \throw If either \a f1 or \a f2 is NULL.
2449 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2450 * differ not only in values.
2452 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2455 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !");
2456 if(!f1->areStrictlyCompatibleForMulDiv(f2))
2457 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them! Check support mesh, and spatial and time discretisation.");
2458 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->dot(f2->timeDiscr()));
2459 td->copyTinyAttrFrom(*f1->timeDiscr());
2460 MEDCouplingFieldDouble *ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2461 ret->setMesh(f1->getMesh());
2466 * Returns a new MEDCouplingFieldDouble containing a cross product of two given fields,
2468 * the i-th tuple of the result field is a 3D vector which is a cross
2469 * product of two vectors defined by the i-th tuples of given fields.
2470 * Number of tuples in the given fields must be the same.
2471 * Number of components in the given fields must be 3.
2472 * \param [in] f1 - a given field.
2473 * \param [in] f2 - another given field.
2474 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2475 * The caller is to delete this result field using decrRef() as it is no more
2477 * \throw If either \a f1 or \a f2 is NULL.
2478 * \throw If \a f1->getNumberOfComponents() != 3
2479 * \throw If \a f2->getNumberOfComponents() != 3
2480 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2481 * differ not only in values.
2483 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2486 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !");
2487 if(!f1->areStrictlyCompatibleForMulDiv(f2))
2488 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation.");
2489 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->crossProduct(f2->timeDiscr()));
2490 td->copyTinyAttrFrom(*f1->timeDiscr());
2491 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2492 ret->setMesh(f1->getMesh());
2497 * Returns a new MEDCouplingFieldDouble containing maximal values of two given fields.
2498 * Number of tuples and components in the given fields must be the same.
2499 * \param [in] f1 - a field to compare values with another one.
2500 * \param [in] f2 - another field to compare values with the first one.
2501 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2502 * The caller is to delete this result field using decrRef() as it is no more
2504 * \throw If either \a f1 or \a f2 is NULL.
2505 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2506 * differ not only in values.
2508 * \if ENABLE_EXAMPLES
2509 * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2510 * \ref py_mcfielddouble_MaxFields "Here is a Python example".
2513 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2516 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MaxFields : input field is NULL !");
2517 if(!f1->areStrictlyCompatible(f2))
2518 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MaxFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2519 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->max(f2->timeDiscr()));
2520 td->copyTinyAttrFrom(*f1->timeDiscr());
2521 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2522 ret->setMesh(f1->getMesh());
2527 * Returns a new MEDCouplingFieldDouble containing minimal values of two given fields.
2528 * Number of tuples and components in the given fields must be the same.
2529 * \param [in] f1 - a field to compare values with another one.
2530 * \param [in] f2 - another field to compare values with the first one.
2531 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2532 * The caller is to delete this result field using decrRef() as it is no more
2534 * \throw If either \a f1 or \a f2 is NULL.
2535 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2536 * differ not only in values.
2538 * \if ENABLE_EXAMPLES
2539 * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2540 * \ref py_mcfielddouble_MaxFields "Here is a Python example".
2543 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2546 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MinFields : input field is NULL !");
2547 if(!f1->areStrictlyCompatible(f2))
2548 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MinFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2549 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->min(f2->timeDiscr()));
2550 td->copyTinyAttrFrom(*f1->timeDiscr());
2551 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2552 ret->setMesh(f1->getMesh());
2557 * Returns a copy of \a this field in which sign of all values is reversed.
2558 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble
2559 * containing the same number of tuples and components as \a this field.
2560 * The caller is to delete this result field using decrRef() as it is no more
2562 * \throw If the spatial discretization of \a this field is NULL.
2563 * \throw If a data array is not allocated.
2565 MEDCouplingFieldDouble *MEDCouplingFieldDouble::negate() const
2568 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform negate !");
2569 MEDCouplingTimeDiscretization *td(timeDiscr()->negate());
2570 td->copyTinyAttrFrom(*timeDiscr());
2571 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2572 ret->setMesh(getMesh());
2577 * Returns a new MEDCouplingFieldDouble containing sum values of corresponding values of
2578 * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] + _f2_ [ i, j ] ).
2579 * Number of tuples and components in the given fields must be the same.
2580 * \param [in] f1 - a field to sum up.
2581 * \param [in] f2 - another field to sum up.
2582 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2583 * The caller is to delete this result field using decrRef() as it is no more
2585 * \throw If either \a f1 or \a f2 is NULL.
2586 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2587 * differ not only in values.
2589 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2592 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::AddFields : input field is NULL !");
2593 if(!f1->areStrictlyCompatible(f2))
2594 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply AddFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2595 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->add(f2->timeDiscr()));
2596 td->copyTinyAttrFrom(*f1->timeDiscr());
2597 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2598 ret->setMesh(f1->getMesh());
2603 * Adds values of another MEDCouplingFieldDouble to values of \a this one
2604 * ( _this_ [ i, j ] += _other_ [ i, j ] ) using DataArrayDouble::addEqual().
2605 * The two fields must have same number of tuples, components and same underlying mesh.
2606 * \param [in] other - the field to add to \a this one.
2607 * \return const MEDCouplingFieldDouble & - a reference to \a this field.
2608 * \throw If \a other is NULL.
2609 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2610 * differ not only in values.
2612 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other)
2614 if(!areStrictlyCompatible(&other))
2615 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply += on them! Check support mesh, field nature, and spatial and time discretisation.");
2616 timeDiscr()->addEqual(other.timeDiscr());
2621 * Returns a new MEDCouplingFieldDouble containing subtraction of corresponding values of
2622 * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] - _f2_ [ i, j ] ).
2623 * Number of tuples and components in the given fields must be the same.
2624 * \param [in] f1 - a field to subtract from.
2625 * \param [in] f2 - a field to subtract.
2626 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2627 * The caller is to delete this result field using decrRef() as it is no more
2629 * \throw If either \a f1 or \a f2 is NULL.
2630 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2631 * differ not only in values.
2633 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2636 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::SubstractFields : input field is NULL !");
2637 if(!f1->areStrictlyCompatible(f2))
2638 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply SubstractFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2639 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->substract(f2->timeDiscr()));
2640 td->copyTinyAttrFrom(*f1->timeDiscr());
2641 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2642 ret->setMesh(f1->getMesh());
2647 * Subtract values of another MEDCouplingFieldDouble from values of \a this one
2648 * ( _this_ [ i, j ] -= _other_ [ i, j ] ) using DataArrayDouble::substractEqual().
2649 * The two fields must have same number of tuples, components and same underlying mesh.
2650 * \param [in] other - the field to subtract from \a this one.
2651 * \return const MEDCouplingFieldDouble & - a reference to \a this field.
2652 * \throw If \a other is NULL.
2653 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2654 * differ not only in values.
2656 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other)
2658 if(!areStrictlyCompatible(&other))
2659 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply -= on them! Check support mesh, field nature, and spatial and time discretisation.");
2660 timeDiscr()->substractEqual(other.timeDiscr());
2665 * Returns a new MEDCouplingFieldDouble containing product values of
2666 * two given fields. There are 2 valid cases.
2667 * 1. The fields have same number of tuples and components. Then each value of
2668 * the result field (_f_) is a product of the corresponding values of _f1_ and
2669 * _f2_, i.e. _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, j ].
2670 * 2. The fields have same number of tuples and one field, say _f2_, has one
2672 * _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, 0 ].
2674 * The two fields must have same number of tuples and same underlying mesh.
2675 * \param [in] f1 - a factor field.
2676 * \param [in] f2 - another factor field.
2677 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2678 * The caller is to delete this result field using decrRef() as it is no more
2680 * \throw If either \a f1 or \a f2 is NULL.
2681 * \throw If the fields are not compatible for multiplication (areCompatibleForMul()),
2682 * i.e. they differ not only in values and possibly number of components.
2684 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2687 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MultiplyFields : input field is NULL !");
2688 if(!f1->areCompatibleForMul(f2))
2689 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MultiplyFields on them! Check support mesh, and spatial and time discretisation.");
2690 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->multiply(f2->timeDiscr()));
2691 td->copyTinyAttrFrom(*f1->timeDiscr());
2692 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2693 ret->setMesh(f1->getMesh());
2698 * Multiply values of another MEDCouplingFieldDouble to values of \a this one
2699 * using DataArrayDouble::multiplyEqual().
2700 * The two fields must have same number of tuples and same underlying mesh.
2701 * There are 2 valid cases.
2702 * 1. The fields have same number of components. Then each value of
2703 * \a other is multiplied to the corresponding value of \a this field, i.e.
2704 * _this_ [ i, j ] *= _other_ [ i, j ].
2705 * 2. The _other_ field has one component. Then
2706 * _this_ [ i, j ] *= _other_ [ i, 0 ].
2708 * The two fields must have same number of tuples and same underlying mesh.
2709 * \param [in] other - an field to multiply to \a this one.
2710 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2711 * The caller is to delete this result field using decrRef() as it is no more
2713 * \throw If \a other is NULL.
2714 * \throw If the fields are not strictly compatible for multiplication
2715 * (areCompatibleForMul()),
2716 * i.e. they differ not only in values and possibly in number of components.
2718 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other)
2720 if(!areCompatibleForMul(&other))
2721 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply *= on them! Check support mesh, and spatial and time discretisation.");
2722 timeDiscr()->multiplyEqual(other.timeDiscr());
2728 * Returns a new MEDCouplingFieldDouble containing division of two given fields.
2729 * There are 2 valid cases.
2730 * 1. The fields have same number of tuples and components. Then each value of
2731 * the result field (_f_) is a division of the corresponding values of \a f1 and
2732 * \a f2, i.e. _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, j ].
2733 * 2. The fields have same number of tuples and _f2_ has one component. Then
2734 * _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, 0 ].
2736 * \param [in] f1 - a numerator field.
2737 * \param [in] f2 - a denominator field.
2738 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2739 * The caller is to delete this result field using decrRef() as it is no more
2741 * \throw If either \a f1 or \a f2 is NULL.
2742 * \throw If the fields are not compatible for division (areCompatibleForDiv()),
2743 * i.e. they differ not only in values and possibly in number of components.
2745 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2748 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DivideFields : input field is NULL !");
2749 if(!f1->areCompatibleForDiv(f2))
2750 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DivideFields on them! Check support mesh, and spatial and time discretisation.");
2751 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->divide(f2->timeDiscr()));
2752 td->copyTinyAttrFrom(*f1->timeDiscr());
2753 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2754 ret->setMesh(f1->getMesh());
2759 * Divide values of \a this field by values of another MEDCouplingFieldDouble
2760 * using DataArrayDouble::divideEqual().
2761 * The two fields must have same number of tuples and same underlying mesh.
2762 * There are 2 valid cases.
2763 * 1. The fields have same number of components. Then each value of
2764 * \a this field is divided by the corresponding value of \a other one, i.e.
2765 * _this_ [ i, j ] /= _other_ [ i, j ].
2766 * 2. The \a other field has one component. Then
2767 * _this_ [ i, j ] /= _other_ [ i, 0 ].
2769 * \warning No check of division by zero is performed!
2770 * \param [in] other - an field to divide \a this one by.
2771 * \throw If \a other is NULL.
2772 * \throw If the fields are not compatible for division (areCompatibleForDiv()),
2773 * i.e. they differ not only in values and possibly in number of components.
2775 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other)
2777 if(!areCompatibleForDiv(&other))
2778 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply /= on them! Check support mesh, and spatial and time discretisation.");
2779 timeDiscr()->divideEqual(other.timeDiscr());
2785 * Directly called by MEDCouplingFieldDouble::operator^.
2787 * \sa MEDCouplingFieldDouble::operator^
2789 MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2792 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::PowFields : input field is NULL !");
2793 if(!f1->areCompatibleForMul(f2))
2794 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply PowFields on them! Check support mesh, and spatial and time discretisation.");
2795 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->pow(f2->timeDiscr()));
2796 td->copyTinyAttrFrom(*f1->timeDiscr());
2797 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2798 ret->setMesh(f1->getMesh());
2803 * Directly call MEDCouplingFieldDouble::PowFields static method.
2805 * \sa MEDCouplingFieldDouble::PowFields
2807 MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const
2809 return PowFields(this,&other);
2812 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other)
2814 if(!areCompatibleForDiv(&other))
2815 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply ^= on them! Check support mesh, and spatial and time discretisation.");
2816 timeDiscr()->powEqual(other.timeDiscr());
2822 * Writes the field series \a fs and the mesh the fields lie on in the VTK file \a fileName.
2823 * If \a fs is empty no file is written.
2824 * The result file is valid provided that no exception is thrown.
2825 * \warning All the fields must be named and lie on the same non NULL mesh.
2826 * \param [in] fileName - the name of a VTK file to write in.
2827 * \param [in] fs - the fields to write.
2828 * \param [in] isBinary - specifies the VTK format of the written file. By default true (Binary mode)
2829 * \throw If \a fs[ 0 ] == NULL.
2830 * \throw If the fields lie not on the same mesh.
2831 * \throw If the mesh is not set.
2832 * \throw If any of the fields has no name.
2834 * \if ENABLE_EXAMPLES
2835 * \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".<br>
2836 * \ref py_mcfielddouble_WriteVTK "Here is a Python example".
2839 std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector<const MEDCouplingFieldDouble *>& fs, bool isBinary)
2842 return std::string();
2843 std::size_t nfs=fs.size();
2845 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field is NULL !");
2846 const MEDCouplingMesh *m=fs[0]->getMesh();
2848 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field lies on NULL mesh !");
2849 for(std::size_t i=1;i<nfs;i++)
2850 if(fs[i]->getMesh()!=m)
2851 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.");
2853 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !");
2854 std::string ret(m->getVTKFileNameOf(fileName));
2855 MCAuto<DataArrayByte> byteArr;
2857 { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); }
2858 std::ostringstream coss,noss;
2859 for(std::size_t i=0;i<nfs;i++)
2861 const MEDCouplingFieldDouble *cur=fs[i];
2862 std::string name(cur->getName());
2865 std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
2866 throw INTERP_KERNEL::Exception(oss.str());
2868 TypeOfField typ=cur->getTypeOfField();
2870 cur->getArray()->writeVTK(coss,8,cur->getName(),byteArr);
2871 else if(typ==ON_NODES)
2872 cur->getArray()->writeVTK(noss,8,cur->getName(),byteArr);
2874 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : only node and cell fields supported for the moment !");
2876 m->writeVTKAdvanced(ret,coss.str(),noss.str(),byteArr);
2880 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoizeGen(const Voronizer *vor, double eps) const
2882 checkConsistencyLight();
2884 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoizeGen : null pointer !");
2885 MCAuto<MEDCouplingFieldDouble> fieldToWO;
2886 const MEDCouplingMesh *inpMeshBase(getMesh());
2887 MCAuto<MEDCouplingUMesh> inpMesh(inpMeshBase->buildUnstructured());
2888 std::string meshName(inpMesh->getName());
2889 if(!inpMesh->isPresenceOfQuadratic())
2890 fieldToWO=clone(false);
2893 fieldToWO=convertQuadraticCellsToLinear();
2894 inpMeshBase=fieldToWO->getMesh();
2895 inpMesh=inpMeshBase->buildUnstructured();
2897 int nbCells(inpMesh->getNumberOfCells());
2898 const MEDCouplingFieldDiscretization *disc(fieldToWO->getDiscretization());
2899 const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
2901 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : Not a ON_GAUSS_PT field");
2902 int nbLocs(disc2->getNbOfGaussLocalization());
2903 std::vector< MCAuto<MEDCouplingUMesh> > cells(nbCells);
2904 for(int i=0;i<nbLocs;i++)
2906 const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(i));
2907 if(gl.getDimension()!=vor->getDimension())
2908 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : not a 2D one !");
2909 MCAuto<MEDCouplingUMesh> mesh(gl.buildRefCell());
2910 const std::vector<double>& coo(gl.getGaussCoords());
2911 MCAuto<DataArrayDouble> coo2(DataArrayDouble::NewFromStdVector(coo));
2912 coo2->rearrange(vor->getDimension());
2914 MCAuto<MEDCouplingUMesh> coo3(MEDCouplingUMesh::Build0DMeshFromCoords(coo2));
2916 MCAuto<MEDCouplingUMesh> vorCellsForCurDisc(vor->doIt(mesh,coo2,eps));
2917 std::vector<int> ids;
2918 MCAuto<DataArrayDouble> ptsInReal;
2919 disc2->getCellIdsHavingGaussLocalization(i,ids);
2921 MCAuto<MEDCouplingUMesh> subMesh(inpMesh->buildPartOfMySelf(&ids[0],&ids[0]+ids.size()));
2922 ptsInReal=gl.localizePtsInRefCooForEachCell(vorCellsForCurDisc->getCoords(),subMesh);
2924 int nbPtsPerCell(vorCellsForCurDisc->getNumberOfNodes());
2925 for(std::size_t j=0;j<ids.size();j++)
2927 MCAuto<MEDCouplingUMesh> elt(vorCellsForCurDisc->clone(false));
2928 MCAuto<DataArrayDouble> coo4(ptsInReal->selectByTupleIdSafeSlice(j*nbPtsPerCell,(j+1)*nbPtsPerCell,1));
2929 elt->setCoords(coo4);
2933 std::vector< const MEDCouplingUMesh * > cellsPtr(VecAutoToVecOfCstPt(cells));
2934 MCAuto<MEDCouplingUMesh> outMesh(MEDCouplingUMesh::MergeUMeshes(cellsPtr));
2935 outMesh->setName(meshName);
2936 MCAuto<MEDCouplingFieldDouble> onCells(MEDCouplingFieldDouble::New(ON_CELLS));
2937 onCells->setMesh(outMesh);
2939 MCAuto<DataArrayDouble> arr(fieldToWO->getArray()->deepCopy());
2940 onCells->setArray(arr);
2942 onCells->setTimeUnit(getTimeUnit());
2945 double a(getTime(b,c));
2946 onCells->setTime(a,b,c);
2948 onCells->setName(getName());
2952 MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr()
2954 MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
2957 MEDCouplingTimeDiscretization *retc(dynamic_cast<MEDCouplingTimeDiscretization *>(ret));
2959 throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");
2963 const MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr() const
2965 const MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
2968 const MEDCouplingTimeDiscretization *retc(dynamic_cast<const MEDCouplingTimeDiscretization *>(ret));
2970 throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");