1 // Copyright (C) 2007-2021 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 "MEDCouplingFieldInt32.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] deepCpy - 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 mcIdType nbCells=ToIdType(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 std::size_t 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(mcIdType i=0;i<nbCells;i++,pt+=nbCompo)
229 std::vector<mcIdType> 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::bind(std::multiplies<double>(),std::placeholders::_1,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<DataArrayIdType> rn(DataArrayIdType::New()),rni(DataArrayIdType::New());
272 m->getReverseNodalConnectivity(rn,rni);
273 MCAuto<DataArrayIdType> 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 differ 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 mcIdType *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 mcIdType nbOfNodes=meshC->getNumberOfNodes();
397 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
398 mcIdType 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 differ more than \a eps.
426 void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const mcIdType *old2NewBg, mcIdType 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 DataArrayIdType * - a new instance of DataArrayIdType 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 DataArrayIdType *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 MEDCouplingFieldInt32 *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 DataArrayIdType containing indices of
563 * tuples holding the maximal value. The caller is to delete it using
564 * decrRef() as it is no more needed.
565 * \return double - the maximal value among all values of the first array of \a this filed.
566 * \throw If \a this->getNumberOfComponents() != 1.
567 * \throw If there is an empty data array in \a this field.
569 double MEDCouplingFieldDouble::getMaxValue2(DataArrayIdType*& 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<DataArrayIdType> ret1;
577 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
582 DataArrayIdType *tmp;
583 ret=std::max(ret,(*iter)->getMaxValue2(tmp));
584 MCAuto<DataArrayIdType> tmpSafe(tmp);
585 if(!((const DataArrayIdType *)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 DataArrayIdType containing indices of
627 * tuples holding the minimal value. The caller is to delete it using
628 * decrRef() as it is no more needed.
629 * \return double - the minimal value among all values of the first array of \a this filed.
630 * \throw If \a this->getNumberOfComponents() != 1.
631 * \throw If there is an empty data array in \a this field.
633 double MEDCouplingFieldDouble::getMinValue2(DataArrayIdType*& 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<DataArrayIdType> ret1;
641 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
646 DataArrayIdType *tmp;
647 ret=std::max(ret,(*iter)->getMinValue2(tmp));
648 MCAuto<DataArrayIdType> tmpSafe(tmp);
649 if(!((const DataArrayIdType *)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();
688 * Computes the weighted average of values of each component of \a this field, the weights being the
689 * values returned by buildMeasureField().
690 * \param [out] res - pointer to an array of result sum values, of size at least \a
691 * this->getNumberOfComponents(), that is to be allocated by the caller.
692 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by
693 * buildMeasureField(). It makes this method slower. If you are sure that all
694 * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs ==
695 * \c false to speed up the method.
696 * \throw If the mesh is not set.
697 * \throw If the data array is not set.
699 void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const
702 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
703 MCAuto<MEDCouplingFieldDouble> w=buildMeasureField(isWAbs);
704 double deno=w->getArray()->accumulate((std::size_t)0);
705 MCAuto<DataArrayDouble> arr=getArray()->deepCopy();
706 arr->multiplyEqual(w->getArray());
707 arr->accumulate(res);
708 std::size_t nCompo = getArray()->getNumberOfComponents();
709 std::transform(res,res+nCompo,res,std::bind(std::multiplies<double>(),std::placeholders::_1,1./deno));
713 * Computes the weighted average of values of a given component of \a this field, the weights being the
714 * values returned by buildMeasureField().
715 * \param [in] compId - an index of the component of interest.
716 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by
717 * buildMeasureField(). It makes this method slower. If you are sure that all
718 * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs ==
719 * \c false to speed up the method.
720 * \throw If the mesh is not set.
721 * \throw If the data array is not set.
722 * \throw If \a compId is not valid.
723 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
725 double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const
727 std::size_t nbComps=getArray()->getNumberOfComponents();
728 if(compId<0 || compId>=ToIdType(nbComps))
730 std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
731 throw INTERP_KERNEL::Exception(oss.str());
733 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
734 getWeightedAverageValue(res,isWAbs);
739 * Returns the \c normL1 of values of a given component of \a this field:
741 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
743 * \param [in] compId - an index of the component of interest.
744 * \throw If the mesh is not set.
745 * \throw If the spatial discretization of \a this field is NULL.
746 * \throw If \a compId is not valid.
747 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
749 double MEDCouplingFieldDouble::normL1(int compId) const
752 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1 !");
754 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
755 std::size_t nbComps=getArray()->getNumberOfComponents();
756 if(compId<0 || compId>=ToIdType(nbComps))
758 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
759 throw INTERP_KERNEL::Exception(oss.str());
761 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
762 _type->normL1(_mesh,getArray(),res);
767 * Returns the \c normL1 of values of each component of \a this field:
769 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
771 * \param [out] res - pointer to an array of result values, of size at least \a
772 * this->getNumberOfComponents(), that is to be allocated by the caller.
773 * \throw If the mesh is not set.
774 * \throw If the spatial discretization of \a this field is NULL.
776 void MEDCouplingFieldDouble::normL1(double *res) const
779 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
781 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
782 _type->normL1(_mesh,getArray(),res);
786 * Returns the \c normL2 of values of a given component of \a this field:
788 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
790 * \param [in] compId - an index of the component of interest.
791 * \throw If the mesh is not set.
792 * \throw If the spatial discretization of \a this field is NULL.
793 * \throw If \a compId is not valid.
794 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
796 double MEDCouplingFieldDouble::normL2(int compId) const
799 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
801 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
802 std::size_t nbComps=getArray()->getNumberOfComponents();
803 if(compId<0 || compId>=ToIdType(nbComps))
805 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
806 throw INTERP_KERNEL::Exception(oss.str());
808 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
809 _type->normL2(_mesh,getArray(),res);
814 * Returns the \c normL2 of values of each component of \a this field:
816 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
818 * \param [out] res - pointer to an array of result values, of size at least \a
819 * this->getNumberOfComponents(), that is to be allocated by the caller.
820 * \throw If the mesh is not set.
821 * \throw If the spatial discretization of \a this field is NULL.
823 void MEDCouplingFieldDouble::normL2(double *res) const
826 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
828 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
829 _type->normL2(_mesh,getArray(),res);
833 * Returns the \c infinite norm of values of a given component of \a this field:
835 * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
837 * \param [in] compId - an index of the component of interest.
838 * \throw If \a compId is not valid.
839 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
840 * \throw If the data array is not set.
842 double MEDCouplingFieldDouble::normMax(int compId) const
845 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
846 std::size_t nbComps=getArray()->getNumberOfComponents();
847 if(compId<0 || compId>=ToIdType(nbComps))
849 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normMax : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
850 throw INTERP_KERNEL::Exception(oss.str());
852 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
853 getArray()->normMaxPerComponent(res);
858 * Returns the \c infinite norm of values of each component of \a this field:
860 * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
862 * \param [out] res - pointer to an array of result values, of size at least \a
863 * this->getNumberOfComponents(), that is to be allocated by the caller.
864 * \throw If the data array is not set.
867 void MEDCouplingFieldDouble::normMax(double *res) const
870 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
871 getArray()->normMaxPerComponent(res);
875 * Computes a sum of values of a given component of \a this field multiplied by
876 * values returned by buildMeasureField().
877 * This method is useful to check the conservativity of interpolation method.
878 * \param [in] compId - an index of the component of interest.
879 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by
880 * buildMeasureField() that makes this method slower. If a user is sure that all
881 * cells of the underlying mesh have correct orientation, he can put \a isWAbs ==
882 * \c false that speeds up this method.
883 * \throw If the mesh is not set.
884 * \throw If the data array is not set.
885 * \throw If \a compId is not valid.
886 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
888 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const
891 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
893 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral !");
894 std::size_t nbComps=getArray()->getNumberOfComponents();
895 if(compId<0 || compId>=ToIdType(nbComps))
897 std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
898 throw INTERP_KERNEL::Exception(oss.str());
900 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
901 _type->integral(_mesh,getArray(),isWAbs,res);
906 * Computes a sum of values of each component of \a this field multiplied by
907 * values returned by buildMeasureField().
908 * This method is useful to check the conservativity of interpolation method.
909 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by
910 * buildMeasureField() that makes this method slower. If a user is sure that all
911 * cells of the underlying mesh have correct orientation, he can put \a isWAbs ==
912 * \c false that speeds up this method.
913 * \param [out] res - pointer to an array of result sum values, of size at least \a
914 * this->getNumberOfComponents(), that is to be allocated by the caller.
915 * \throw If the mesh is not set.
916 * \throw If the data array is not set.
917 * \throw If the spatial discretization of \a this field is NULL.
919 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const
922 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
924 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral2 !");
925 _type->integral(_mesh,getArray(),isWAbs,res);
929 * Returns a value at a given cell of a structured mesh. The cell is specified by its
931 * \param [in] i - a index of node coordinates array along X axis. The cell is
932 * located between the i-th and ( i + 1 )-th nodes along X axis.
933 * \param [in] j - a index of node coordinates array along Y axis. The cell is
934 * located between the j-th and ( j + 1 )-th nodes along Y axis.
935 * \param [in] k - a index of node coordinates array along Z axis. The cell is
936 * located between the k-th and ( k + 1 )-th nodes along Z axis.
937 * \param [out] res - pointer to an array returning a feild value, of size at least
938 * \a this->getNumberOfComponents(), that is to be allocated by the caller.
939 * \throw If the spatial discretization of \a this field is NULL.
940 * \throw If the mesh is not set.
941 * \throw If the mesh is not a structured one.
943 * \if ENABLE_EXAMPLES
944 * \ref cpp_mcfielddouble_getValueOnPos "Here is a C++ example".<br>
945 * \ref py_mcfielddouble_getValueOnPos "Here is a Python example".
948 void MEDCouplingFieldDouble::getValueOnPos(mcIdType i, mcIdType j, mcIdType k, double *res) const
950 const DataArrayDouble *arr=timeDiscr()->getArray();
952 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
954 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
955 _type->getValueOnPos(arr,_mesh,i,j,k,res);
959 * Returns a value of \a this at a given point using spatial discretization.
960 * \param [in] spaceLoc - the point of interest.
961 * \param [out] res - pointer to an array returning a feild value, of size at least
962 * \a this->getNumberOfComponents(), that is to be allocated by the caller.
963 * \throw If the spatial discretization of \a this field is NULL.
964 * \throw If the mesh is not set.
965 * \throw If \a spaceLoc is out of the spatial discretization.
967 * \if ENABLE_EXAMPLES
968 * \ref cpp_mcfielddouble_getValueOn "Here is a C++ example".<br>
969 * \ref py_mcfielddouble_getValueOn "Here is a Python example".
972 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const
974 const DataArrayDouble *arr=timeDiscr()->getArray();
976 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
978 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
979 _type->getValueOn(arr,_mesh,spaceLoc,res);
983 * Returns values of \a this at given points using spatial discretization.
984 * \param [in] spaceLoc - coordinates of points of interest in full-interlace
985 * mode. This array is to be of size ( \a nbOfPoints * \a this->getNumberOfComponents() ).
986 * \param [in] nbOfPoints - number of points of interest.
987 * \return DataArrayDouble * - a new instance of DataArrayDouble holding field
988 * values relating to the input points. This array is of size \a nbOfPoints
989 * tuples per \a this->getNumberOfComponents() components. The caller is to
990 * delete this array using decrRef() as it is no more needed.
991 * \throw If the spatial discretization of \a this field is NULL.
992 * \throw If the mesh is not set.
993 * \throw If any point in \a spaceLoc is out of the spatial discretization.
995 * \if ENABLE_EXAMPLES
996 * \ref cpp_mcfielddouble_getValueOnMulti "Here is a C++ example".<br>
997 * \ref py_mcfielddouble_getValueOnMulti "Here is a Python example".
1000 DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, mcIdType nbOfPoints) const
1002 const DataArrayDouble *arr=timeDiscr()->getArray();
1004 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
1006 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnMulti !");
1007 return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
1011 * Returns a value of \a this field at a given point at a given time using spatial discretization.
1012 * If the time is not covered by \a this->_time_discr, an exception is thrown.
1013 * \param [in] spaceLoc - the point of interest.
1014 * \param [in] time - the time of interest.
1015 * \param [out] res - pointer to an array returning a feild value, of size at least
1016 * \a this->getNumberOfComponents(), that is to be allocated by the caller.
1017 * \throw If the spatial discretization of \a this field is NULL.
1018 * \throw If the mesh is not set.
1019 * \throw If \a spaceLoc is out of the spatial discretization.
1020 * \throw If \a time is not covered by \a this->_time_discr.
1022 * \if ENABLE_EXAMPLES
1023 * \ref cpp_mcfielddouble_getValueOn_time "Here is a C++ example".<br>
1024 * \ref py_mcfielddouble_getValueOn_time "Here is a Python example".
1027 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const
1029 std::vector< const DataArrayDouble *> arrs=timeDiscr()->getArraysForTime(time);
1031 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
1033 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOn !");
1034 std::vector<double> res2;
1035 for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
1037 std::size_t sz=res2.size();
1038 res2.resize(sz+(*iter)->getNumberOfComponents());
1039 _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]);
1041 timeDiscr()->getValueForTime(time,res2,res);
1045 * Apply a linear function to a given component of \a this field, so that
1046 * a component value <em>(x)</em> becomes \f$ a * x + b \f$.
1047 * \param [in] a - the first coefficient of the function.
1048 * \param [in] b - the second coefficient of the function.
1049 * \param [in] compoId - the index of component to modify.
1050 * \throw If the data array(s) is(are) not set.
1052 void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
1054 timeDiscr()->applyLin(a,b,compoId);
1058 * Apply a linear function to all components of \a this field, so that
1059 * values <em>(x)</em> becomes \f$ a * x + b \f$.
1060 * \param [in] a - the first coefficient of the function.
1061 * \param [in] b - the second coefficient of the function.
1062 * \throw If the data array(s) is(are) not set.
1064 void MEDCouplingFieldDouble::applyLin(double a, double b)
1066 timeDiscr()->applyLin(a,b);
1070 * This method sets \a this to a uniform scalar field with one component.
1071 * All tuples will have the same value 'value'.
1072 * An exception is thrown if no underlying mesh is defined.
1074 MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value)
1077 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
1079 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform operator = !");
1080 mcIdType nbOfTuple=_type->getNumberOfTuples(_mesh);
1081 timeDiscr()->setOrCreateUniformValueOnAllComponents(nbOfTuple,value);
1086 * Creates data array(s) of \a this field by using a C function for value generation.
1087 * \param [in] nbOfComp - the number of components for \a this field to have.
1088 * \param [in] func - the function used to compute values of \a this field.
1089 * This function is to compute a field value basing on coordinates of value
1091 * \throw If the mesh is not set.
1092 * \throw If \a func returns \c false.
1093 * \throw If the spatial discretization of \a this field is NULL.
1095 * \if ENABLE_EXAMPLES
1096 * \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example".
1099 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func)
1102 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1104 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
1105 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1106 timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
1110 * Creates data array(s) of \a this field by using a function for value generation.<br>
1111 * The function is applied to coordinates of value location points. For example, if
1112 * \a this field is on cells, the function is applied to cell barycenters.
1113 * For more info on supported expressions that can be used in the function, see \ref
1114 * MEDCouplingArrayApplyFuncExpr. <br>
1115 * The function can include arbitrary named variables
1116 * (e.g. "x","y" or "va44") to refer to components of point coordinates. Names of
1117 * variables are sorted in \b alphabetical \b order to associate a variable name with a
1118 * component. For example, in the expression "2*x+z", "x" stands for the component #0
1119 * and "z" stands for the component #1 (\b not #2)!<br>
1120 * In a general case, a value resulting from the function evaluation is assigned to all
1121 * components of a field value. But there is a possibility to have its own expression for
1122 * each component within one function. For this purpose, there are predefined variable
1123 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1124 * the component #0 etc). A factor of such a variable is added to the
1125 * corresponding component only.<br>
1126 * For example, \a nbOfComp == 4, coordinates of a 3D point are (1.,3.,7.), then
1127 * - "2*x + z" produces (5.,5.,5.,5.)
1128 * - "2*x + 0*y + z" produces (9.,9.,9.,9.)
1129 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1130 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1132 * \param [in] nbOfComp - the number of components for \a this field to have.
1133 * \param [in] func - the function used to compute values of \a this field.
1134 * This function is used to compute a field value basing on coordinates of value
1135 * location point. For example, if \a this field is on cells, the function
1136 * is applied to cell barycenters.
1137 * \throw If the mesh is not set.
1138 * \throw If the spatial discretization of \a this field is NULL.
1139 * \throw If computing \a func fails.
1141 * \if ENABLE_EXAMPLES
1142 * \ref cpp_mcfielddouble_fillFromAnalytic "Here is a C++ example".<br>
1143 * \ref py_mcfielddouble_fillFromAnalytic "Here is a Python example".
1146 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func)
1149 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1151 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
1152 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1153 timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
1157 * Creates data array(s) of \a this field by using a function for value generation.<br>
1158 * The function is applied to coordinates of value location points. For example, if
1159 * \a this field is on cells, the function is applied to cell barycenters.<br>
1160 * This method differs from
1161 * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()"
1162 * by the way how variable
1163 * names, used in the function, are associated with components of coordinates of field
1164 * location points; here, a variable name corresponding to a component is retrieved from
1165 * a corresponding node coordinates array (where it is set via
1166 * DataArrayDouble::setInfoOnComponent()).<br>
1167 * For more info on supported expressions that can be used in the function, see \ref
1168 * MEDCouplingArrayApplyFuncExpr. <br>
1169 * In a general case, a value resulting from the function evaluation is assigned to all
1170 * components of a field value. But there is a possibility to have its own expression for
1171 * each component within one function. For this purpose, there are predefined variable
1172 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1173 * the component #0 etc). A factor of such a variable is added to the
1174 * corresponding component only.<br>
1175 * For example, \a nbOfComp == 4, names of spatial components are "x", "y" and "z",
1176 * coordinates of a 3D point are (1.,3.,7.), then
1177 * - "2*x + z" produces (9.,9.,9.,9.)
1178 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1179 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1181 * \param [in] nbOfComp - the number of components for \a this field to have.
1182 * \param [in] func - the function used to compute values of \a this field.
1183 * This function is used to compute a field value basing on coordinates of value
1184 * location point. For example, if \a this field is on cells, the function
1185 * is applied to cell barycenters.
1186 * \throw If the mesh is not set.
1187 * \throw If the spatial discretization of \a this field is NULL.
1188 * \throw If computing \a func fails.
1190 * \if ENABLE_EXAMPLES
1191 * \ref cpp_mcfielddouble_fillFromAnalytic2 "Here is a C++ example".<br>
1192 * \ref py_mcfielddouble_fillFromAnalytic2 "Here is a Python example".
1195 void MEDCouplingFieldDouble::fillFromAnalyticCompo(int nbOfComp, const std::string& func)
1198 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
1200 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticCompo !");
1201 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1202 timeDiscr()->fillFromAnalyticCompo(loc,nbOfComp,func);
1206 * Creates data array(s) of \a this field by using a function for value generation.<br>
1207 * The function is applied to coordinates of value location points. For example, if
1208 * \a this field is on cells, the function is applied to cell barycenters.<br>
1209 * This method differs from
1210 * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()"
1211 * by the way how variable
1212 * names, used in the function, are associated with components of coordinates of field
1213 * location points; here, a component index of a variable is defined by a
1214 * rank of the variable within the input array \a varsOrder.<br>
1215 * For more info on supported expressions that can be used in the function, see \ref
1216 * MEDCouplingArrayApplyFuncExpr.
1217 * In a general case, a value resulting from the function evaluation is assigned to all
1218 * components of a field value. But there is a possibility to have its own expression for
1219 * each component within one function. For this purpose, there are predefined variable
1220 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1221 * the component #0 etc). A factor of such a variable is added to the
1222 * corresponding component only.<br>
1223 * For example, \a nbOfComp == 4, names of
1224 * spatial components are given in \a varsOrder: ["x", "y","z"], coordinates of a
1225 * 3D point are (1.,3.,7.), then
1226 * - "2*x + z" produces (9.,9.,9.,9.)
1227 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1228 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1230 * \param [in] nbOfComp - the number of components for \a this field to have.
1231 * \param [in] func - the function used to compute values of \a this field.
1232 * This function is used to compute a field value basing on coordinates of value
1233 * location point. For example, if \a this field is on cells, the function
1234 * is applied to cell barycenters.
1235 * \throw If the mesh is not set.
1236 * \throw If the spatial discretization of \a this field is NULL.
1237 * \throw If computing \a func fails.
1239 * \if ENABLE_EXAMPLES
1240 * \ref cpp_mcfielddouble_fillFromAnalytic3 "Here is a C++ example".<br>
1241 * \ref py_mcfielddouble_fillFromAnalytic3 "Here is a Python example".
1244 void MEDCouplingFieldDouble::fillFromAnalyticNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1247 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
1249 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticNamedCompo !");
1250 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1251 timeDiscr()->fillFromAnalyticNamedCompo(loc,nbOfComp,varsOrder,func);
1255 * Modifies values of \a this field by applying a C function to each tuple of all
1257 * \param [in] nbOfComp - the number of components for \a this field to have.
1258 * \param [in] func - the function used to compute values of \a this field.
1259 * This function is to compute a field value basing on a current field value.
1260 * \throw If \a func returns \c false.
1262 * \if ENABLE_EXAMPLES
1263 * \ref cpp_mcfielddouble_applyFunc_c_func "Here is a C++ example".
1266 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
1268 timeDiscr()->applyFunc(nbOfComp,func);
1272 * Fill \a this field with a given value.<br>
1273 * This method is a specialization of other overloaded methods. When \a nbOfComp == 1
1274 * this method is equivalent to MEDCoupling::MEDCouplingFieldDouble::operator=().
1275 * \param [in] nbOfComp - the number of components for \a this field to have.
1276 * \param [in] val - the value to assign to every atomic value of \a this field.
1277 * \throw If the spatial discretization of \a this field is NULL.
1278 * \throw If the mesh is not set.
1280 * \if ENABLE_EXAMPLES
1281 * \ref cpp_mcfielddouble_applyFunc_val "Here is a C++ example".<br>
1282 * \ref py_mcfielddouble_applyFunc_val "Here is a Python example".
1285 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
1288 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
1290 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform applyFunc !");
1291 mcIdType nbOfTuple=_type->getNumberOfTuples(_mesh);
1292 timeDiscr()->setUniformValue(nbOfTuple,nbOfComp,val);
1296 * Modifies values of \a this field by applying a function to each tuple of all
1298 * For more info on supported expressions that can be used in the function, see \ref
1299 * MEDCouplingArrayApplyFuncExpr. <br>
1300 * The function can include arbitrary named variables
1301 * (e.g. "x","y" or "va44") to refer to components of a field value. Names of
1302 * variables are sorted in \b alphabetical \b order to associate a variable name with a
1303 * component. For example, in the expression "2*x+z", "x" stands for the component #0
1304 * and "z" stands for the component #1 (\b not #2)!<br>
1305 * In a general case, a value resulting from the function evaluation is assigned to all
1306 * components of a field value. But there is a possibility to have its own expression for
1307 * each component within one function. For this purpose, there are predefined variable
1308 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1309 * the component #0 etc). A factor of such a variable is added to the
1310 * corresponding component only.<br>
1311 * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then
1312 * - "2*x + z" produces (5.,5.,5.,5.)
1313 * - "2*x + 0*y + z" produces (9.,9.,9.,9.)
1314 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1315 * - "2*y*IVec + z*KVec + x" produces (7.,1.,8.,1.)
1317 * \param [in] nbOfComp - the number of components for \a this field to have.
1318 * \param [in] func - the function used to compute values of \a this field.
1319 * This function is to compute a field value basing on a current field value.
1320 * \throw If computing \a func fails.
1322 * \if ENABLE_EXAMPLES
1323 * \ref cpp_mcfielddouble_applyFunc "Here is a C++ example".<br>
1324 * \ref py_mcfielddouble_applyFunc "Here is a Python example".
1327 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func)
1329 timeDiscr()->applyFunc(nbOfComp,func);
1334 * Modifies values of \a this field by applying a function to each tuple of all
1336 * For more info on supported expressions that can be used in the function, see \ref
1337 * MEDCouplingArrayApplyFuncExpr. <br>
1338 * This method differs from
1339 * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()"
1340 * by the way how variable
1341 * names, used in the function, are associated with components of field values;
1342 * here, a variable name corresponding to a component is retrieved from
1343 * component information of an array (where it is set via
1344 * DataArrayDouble::setInfoOnComponent()).<br>
1345 * In a general case, a value resulting from the function evaluation is assigned to all
1346 * components of a field value. But there is a possibility to have its own expression for
1347 * each component within one function. For this purpose, there are predefined variable
1348 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1349 * the component #0 etc). A factor of such a variable is added to the
1350 * corresponding component only.<br>
1351 * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then
1352 * - "2*x + z" produces (5.,5.,5.,5.)
1353 * - "2*x + 0*y + z" produces (9.,9.,9.,9.)
1354 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1355 * - "2*y*IVec + z*KVec + x" produces (7.,1.,8.,1.)
1357 * \param [in] nbOfComp - the number of components for \a this field to have.
1358 * \param [in] func - the function used to compute values of \a this field.
1359 * This function is to compute a new field value basing on a current field value.
1360 * \throw If computing \a func fails.
1362 * \if ENABLE_EXAMPLES
1363 * \ref cpp_mcfielddouble_applyFunc2 "Here is a C++ example".<br>
1364 * \ref py_mcfielddouble_applyFunc2 "Here is a Python example".
1367 void MEDCouplingFieldDouble::applyFuncCompo(int nbOfComp, const std::string& func)
1369 timeDiscr()->applyFuncCompo(nbOfComp,func);
1373 * Modifies values of \a this field by applying a function to each tuple of all
1375 * This method differs from
1376 * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()"
1377 * by the way how variable
1378 * names, used in the function, are associated with components of field values;
1379 * here, a component index of a variable is defined by a
1380 * rank of the variable within the input array \a varsOrder.<br>
1381 * For more info on supported expressions that can be used in the function, see \ref
1382 * MEDCouplingArrayApplyFuncExpr.
1383 * In a general case, a value resulting from the function evaluation is assigned to all
1384 * components of a field value. But there is a possibility to have its own expression for
1385 * each component within one function. For this purpose, there are predefined variable
1386 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1387 * the component #0 etc). A factor of such a variable is added to the
1388 * corresponding component only.<br>
1389 * For example, \a nbOfComp == 4, names of
1390 * components are given in \a varsOrder: ["x", "y","z"], components of a
1391 * 3D vector are (1.,3.,7.), then
1392 * - "2*x + z" produces (9.,9.,9.,9.)
1393 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1394 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1396 * \param [in] nbOfComp - the number of components for \a this field to have.
1397 * \param [in] func - the function used to compute values of \a this field.
1398 * This function is to compute a new field value basing on a current field value.
1399 * \throw If computing \a func fails.
1401 * \if ENABLE_EXAMPLES
1402 * \ref cpp_mcfielddouble_applyFunc3 "Here is a C++ example".<br>
1403 * \ref py_mcfielddouble_applyFunc3 "Here is a Python example".
1406 void MEDCouplingFieldDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1408 timeDiscr()->applyFuncNamedCompo(nbOfComp,varsOrder,func);
1412 * Modifies values of \a this field by applying a function to each atomic value of all
1413 * data arrays. The function computes a new single value basing on an old single value.
1414 * For more info on supported expressions that can be used in the function, see \ref
1415 * MEDCouplingArrayApplyFuncExpr. <br>
1416 * The function can include **only one** arbitrary named variable
1417 * (e.g. "x","y" or "va44") to refer to a field atomic value. <br>
1418 * In a general case, a value resulting from the function evaluation is assigned to
1419 * a single field value. But there is a possibility to have its own expression for
1420 * each component within one function. For this purpose, there are predefined variable
1421 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1422 * the component #0 etc). A factor of such a variable is added to the
1423 * corresponding component only.<br>
1424 * For example, components of a field value are (1.,3.,7.), then
1425 * - "2*x - 1" produces (1.,5.,13.)
1426 * - "2*x*IVec + (x+3)*KVec" produces (2.,0.,10.)
1427 * - "2*x*IVec + (x+3)*KVec + 1" produces (3.,1.,11.)
1429 * \param [in] func - the function used to compute values of \a this field.
1430 * This function is to compute a field value basing on a current field value.
1431 * \throw If computing \a func fails.
1433 * \if ENABLE_EXAMPLES
1434 * \ref cpp_mcfielddouble_applyFunc_same_nb_comp "Here is a C++ example".<br>
1435 * \ref py_mcfielddouble_applyFunc_same_nb_comp "Here is a Python example".
1438 void MEDCouplingFieldDouble::applyFunc(const std::string& func)
1440 timeDiscr()->applyFunc(func);
1444 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1445 * The field will contain exactly the same number of components after the call.
1446 * Use is not warranted for the moment !
1448 void MEDCouplingFieldDouble::applyFuncFast32(const std::string& func)
1450 timeDiscr()->applyFuncFast32(func);
1454 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1455 * The field will contain exactly the same number of components after the call.
1456 * Use is not warranted for the moment !
1458 void MEDCouplingFieldDouble::applyFuncFast64(const std::string& func)
1460 timeDiscr()->applyFuncFast64(func);
1464 * Returns number of components in the data array. For more info on the data arrays,
1466 * \return int - the number of components in the data array.
1467 * \throw If the data array is not set.
1469 std::size_t MEDCouplingFieldDouble::getNumberOfComponents() const
1472 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
1473 return getArray()->getNumberOfComponents();
1477 * Use MEDCouplingField::getNumberOfTuplesExpected instead of this method. This method will be removed soon, because it is
1478 * confusing compared to getNumberOfComponents() and getNumberOfValues() behaviour.
1480 * Returns number of tuples in \a this field, that depends on
1481 * - the number of entities in the underlying mesh
1482 * - \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field (e.g. number
1483 * of Gauss points if \a this->getTypeOfField() ==
1484 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT").
1486 * The returned value does \b not \b depend on the number of tuples in the data array
1487 * (which has to be equal to the returned value), \b contrary to
1488 * getNumberOfComponents() and getNumberOfValues() that retrieve information from the
1489 * data array (Sorry, it is confusing !).
1490 * So \b this \b method \b behaves \b exactly \b as MEDCouplingField::getNumberOfTuplesExpected \b method.
1492 * \warning No checkConsistencyLight() is done here.
1493 * For more info on the data arrays, see \ref arrays.
1494 * \return int - the number of tuples.
1495 * \throw If the mesh is not set.
1496 * \throw If the spatial discretization of \a this field is NULL.
1497 * \throw If the spatial discretization is not fully defined.
1498 * \sa MEDCouplingField::getNumberOfTuplesExpected
1500 mcIdType MEDCouplingFieldDouble::getNumberOfTuples() const
1503 throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
1505 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getNumberOfTuples !");
1506 return _type->getNumberOfTuples(_mesh);
1510 * Returns number of atomic double values in the data array of \a this field.
1511 * For more info on the data arrays, see \ref arrays.
1512 * \return int - (number of tuples) * (number of components) of the
1514 * \throw If the data array is not set.
1516 mcIdType MEDCouplingFieldDouble::getNumberOfValues() const
1519 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
1520 return getArray()->getNbOfElems();
1524 * Sets own modification time by the most recently modified element of data (the mesh,
1525 * the data array etc). For more info, see \ref MEDCouplingTimeLabelPage.
1527 void MEDCouplingFieldDouble::updateTime() const
1529 MEDCouplingField::updateTime();
1530 updateTimeWith(*timeDiscr());
1533 std::size_t MEDCouplingFieldDouble::getHeapMemorySizeWithoutChildren() const
1535 return MEDCouplingField::getHeapMemorySizeWithoutChildren();
1538 std::vector<const BigMemoryObject *> MEDCouplingFieldDouble::getDirectChildrenWithNull() const
1540 std::vector<const BigMemoryObject *> ret(MEDCouplingField::getDirectChildrenWithNull());
1543 std::vector<const BigMemoryObject *> ret2(timeDiscr()->getDirectChildrenWithNull());
1544 ret.insert(ret.end(),ret2.begin(),ret2.end());
1550 * Returns a value of \a this field of type either
1551 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or
1552 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE".
1553 * \param [in] cellId - an id of cell of interest.
1554 * \param [in] nodeIdInCell - a node index within the cell.
1555 * \param [in] compoId - an index of component.
1556 * \return double - the field value corresponding to the specified parameters.
1557 * \throw If the data array is not set.
1558 * \throw If the mesh is not set.
1559 * \throw If the spatial discretization of \a this field is NULL.
1560 * \throw If \a this field if of type other than
1561 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or
1562 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE".
1564 double MEDCouplingFieldDouble::getIJK(mcIdType cellId, int nodeIdInCell, int compoId) const
1567 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getIJK !");
1568 return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
1572 * Sets the data array.
1573 * \param [in] array - the data array holding values of \a this field. It's size
1574 * should correspond to the mesh and
1575 * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1576 * (see getNumberOfTuples()), but this size is not checked here.
1578 //void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
1581 * Sets the data array holding values corresponding to an end of a time interval
1582 * for which \a this field is defined.
1583 * \param [in] array - the data array holding values of \a this field. It's size
1584 * should correspond to the mesh and
1585 * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1586 * (see getNumberOfTuples()), but this size is not checked here.
1588 //void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
1591 * Sets all data arrays needed to define the field values.
1592 * \param [in] arrs - a vector of DataArrayDouble's holding values of \a this
1593 * field. Size of each array should correspond to the mesh and
1594 * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1595 * (see getNumberOfTuples()), but this size is not checked here.
1596 * \throw If number of arrays in \a arrs does not correspond to type of
1597 * \ref MEDCouplingTemporalDisc "temporal discretization" of \a this field.
1599 //void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs)
1602 * Tries to set an \a other mesh as the support of \a this field. An attempt fails, if
1603 * a current and the \a other meshes are different with use of specified equality
1604 * criteria, and then an exception is thrown.
1605 * \param [in] other - the mesh to use as the field support if this mesh can be
1606 * considered equal to the current mesh.
1607 * \param [in] levOfCheck - defines equality criteria used for mesh comparison. For
1608 * it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which
1609 * is used for mesh comparison.
1610 * \param [in] precOnMesh - a precision used to compare nodes of the two meshes.
1611 * It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith().
1612 * \param [in] eps - a precision used at node renumbering (if needed) to compare field
1613 * values at merged nodes. If the values differ more than \a eps, an
1614 * exception is thrown.
1615 * \throw If the mesh is not set.
1616 * \throw If \a other == NULL.
1617 * \throw If any of the meshes is not well defined.
1618 * \throw If the two meshes do not match.
1619 * \throw If field values at merged nodes (if any) differ more than \a eps.
1621 * \if ENABLE_EXAMPLES
1622 * \ref cpp_mcfielddouble_changeUnderlyingMesh "Here is a C++ example".<br>
1623 * \ref py_mcfielddouble_changeUnderlyingMesh "Here is a Python example".
1626 void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps)
1628 if(_mesh==0 || other==0)
1629 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
1630 DataArrayIdType *cellCor=0,*nodeCor=0;
1631 other->checkGeoEquivalWith(_mesh,levOfCheck,precOnMesh,cellCor,nodeCor);
1632 MCAuto<DataArrayIdType> cellCor2(cellCor),nodeCor2(nodeCor);
1634 renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
1636 renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps);
1641 * Subtracts another field from \a this one in case when the two fields have different
1642 * supporting meshes. The subtraction is performed provided that the tho meshes can be
1643 * considered equal with use of specified equality criteria, else an exception is thrown.
1644 * If the meshes match, the mesh of \a f is set to \a this field (\a this is permuted if
1645 * necessary) and field values are subtracted. No interpolation is done here, only an
1646 * analysis of two underlying mesh is done to see if the meshes are geometrically
1648 * The job of this method consists in calling
1649 * \a this->changeUnderlyingMesh() with \a f->getMesh() as the first parameter, and then
1650 * \a this -= \a f.<br>
1651 * This method requires that \a f and \a this are coherent (checkConsistencyLight()) and that \a f
1652 * and \a this are coherent for a merge.<br>
1653 * "DM" in the method name stands for "different meshes".
1654 * \param [in] f - the field to subtract from this.
1655 * \param [in] levOfCheck - defines equality criteria used for mesh comparison. For
1656 * it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which
1657 * is used for mesh comparison.
1658 * \param [in] precOnMesh - a precision used to compare nodes of the two meshes.
1659 * It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith().
1660 * \param [in] eps - a precision used at node renumbering (if needed) to compare field
1661 * values at merged nodes. If the values differ more than \a eps, an
1662 * exception is thrown.
1663 * \throw If \a f == NULL.
1664 * \throw If any of the meshes is not set or is not well defined.
1665 * \throw If the two meshes do not match.
1666 * \throw If the two fields are not coherent for merge.
1667 * \throw If field values at merged nodes (if any) differ more than \a eps.
1669 * \if ENABLE_EXAMPLES
1670 * \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".<br>
1671 * \ref py_mcfielddouble_substractInPlaceDM "Here is a Python example".
1673 * \sa changeUnderlyingMesh().
1675 void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps)
1677 checkConsistencyLight();
1679 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : input field is NULL !");
1680 f->checkConsistencyLight();
1681 if(!areCompatibleForMerge(f))
1682 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : Fields are not compatible ; unable to apply mergeFields on them !");
1683 changeUnderlyingMesh(f->getMesh(),levOfCheck,precOnMesh,eps);
1688 * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the
1689 * underlying mesh is replaced by a new mesh instance where the coincident nodes are merged.
1690 * \param [in] eps - a precision used to compare nodes of the two meshes.
1691 * \param [in] epsOnVals - a precision used to compare field
1692 * values at merged nodes. If the values differ more than \a epsOnVals, an
1693 * exception is thrown.
1694 * \return bool - \c true if some nodes have been merged and hence \a this field lies
1696 * \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1697 * \throw If the mesh is not well defined.
1698 * \throw If the spatial discretization of \a this field is NULL.
1699 * \throw If the data array is not set.
1700 * \throw If field values at merged nodes (if any) differ more than \a epsOnVals.
1702 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals)
1704 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1706 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1708 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes !");
1709 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1712 MCAuto<DataArrayIdType> arr=meshC2->mergeNodes(eps,ret,ret2);
1713 if(!ret)//no nodes have been merged.
1715 std::vector<DataArrayDouble *> arrays;
1716 timeDiscr()->getArrays(arrays);
1717 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1719 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1725 * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the
1726 * underlying mesh is replaced by a new mesh instance where the coincident nodes are
1728 * In contrast to mergeNodes(), location of merged nodes is changed to be at their barycenter.
1729 * \param [in] eps - a precision used to compare nodes of the two meshes.
1730 * \param [in] epsOnVals - a precision used to compare field
1731 * values at merged nodes. If the values differ more than \a epsOnVals, an
1732 * exception is thrown.
1733 * \return bool - \c true if some nodes have been merged and hence \a this field lies
1735 * \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1736 * \throw If the mesh is not well defined.
1737 * \throw If the spatial discretization of \a this field is NULL.
1738 * \throw If the data array is not set.
1739 * \throw If field values at merged nodes (if any) differ more than \a epsOnVals.
1741 bool MEDCouplingFieldDouble::mergeNodesCenter(double eps, double epsOnVals)
1743 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1745 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1747 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodesCenter !");
1748 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1751 MCAuto<DataArrayIdType> arr=meshC2->mergeNodesCenter(eps,ret,ret2);
1752 if(!ret)//no nodes have been merged.
1754 std::vector<DataArrayDouble *> arrays;
1755 timeDiscr()->getArrays(arrays);
1756 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1758 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1764 * Removes from the underlying mesh nodes not used in any cell. If some nodes are
1765 * removed, the underlying mesh is replaced by a new mesh instance where the unused
1766 * nodes are removed.<br>
1767 * \param [in] epsOnVals - a precision used to compare field
1768 * values at merged nodes. If the values differ more than \a epsOnVals, an
1769 * exception is thrown.
1770 * \return bool - \c true if some nodes have been removed and hence \a this field lies
1772 * \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1773 * \throw If the mesh is not well defined.
1774 * \throw If the spatial discretization of \a this field is NULL.
1775 * \throw If the data array is not set.
1776 * \throw If field values at merged nodes (if any) differ more than \a epsOnVals.
1778 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals)
1780 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1782 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1784 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipCoords !");
1785 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1786 mcIdType oldNbOfNodes=meshC2->getNumberOfNodes();
1787 MCAuto<DataArrayIdType> arr=meshC2->zipCoordsTraducer();
1788 if(meshC2->getNumberOfNodes()!=oldNbOfNodes)
1790 std::vector<DataArrayDouble *> arrays;
1791 timeDiscr()->getArrays(arrays);
1792 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1794 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1802 * Removes duplicates of cells from the understanding mesh. If some cells are
1803 * removed, the underlying mesh is replaced by a new mesh instance where the cells
1804 * duplicates are removed.<br>
1805 * \param [in] compType - specifies a cell comparison technique. Meaning of its
1806 * valid values [0,1,2] is explained in the description of
1807 * MEDCouplingPointSet::zipConnectivityTraducer() which is called by this method.
1808 * \param [in] epsOnVals - a precision used to compare field
1809 * values at merged cells. If the values differ more than \a epsOnVals, an
1810 * exception is thrown.
1811 * \return bool - \c true if some cells have been removed and hence \a this field lies
1813 * \throw If the mesh is not an instance of MEDCouplingUMesh.
1814 * \throw If the mesh is not well defined.
1815 * \throw If the spatial discretization of \a this field is NULL.
1816 * \throw If the data array is not set.
1817 * \throw If field values at merged cells (if any) differ more than \a epsOnVals.
1819 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals)
1821 const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
1823 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipConnectivity : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1825 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipConnectivity !");
1826 MCAuto<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCopy());
1827 mcIdType oldNbOfCells(meshC2->getNumberOfCells());
1828 MCAuto<DataArrayIdType> arr=meshC2->zipConnectivityTraducer(compType);
1829 if(meshC2->getNumberOfCells()!=oldNbOfCells)
1831 std::vector<DataArrayDouble *> arrays;
1832 timeDiscr()->getArrays(arrays);
1833 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1835 _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),ToIdType(meshC2->getNumberOfCells()),*iter);
1843 * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists.
1844 * For the moment, this method is implemented for fields on cells.
1846 * \return a newly allocated field double containing the result that the user should deallocate.
1848 MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const
1850 const MEDCouplingMesh *mesh=getMesh();
1852 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !");
1853 if(getTypeOfField()!=ON_CELLS)
1854 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !");
1855 const MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1856 MCAuto<MEDCouplingFieldDouble> ret(clone(false));
1857 ret->setMesh(umesh);
1858 DataArrayIdType *cellIds=0;
1859 MCAuto<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds);
1860 MCAuto<DataArrayIdType> cellIds2=cellIds;
1861 ret->setMesh(mesh2);
1862 MCAuto<DataArrayIdType> tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end());
1863 std::vector<DataArrayDouble *> arrays;
1864 timeDiscr()->getArrays(arrays);
1866 std::vector<DataArrayDouble *> newArr(arrays.size());
1867 std::vector< MCAuto<DataArrayDouble> > newArr2(arrays.size());
1868 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++)
1872 newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
1873 newArr[i]=newArr2[i];
1876 ret->setArrays(newArr);
1881 * Divides every cell of the underlying mesh into simplices (triangles in 2D and
1882 * tetrahedra in 3D). If some cells are divided, the underlying mesh is replaced by a new
1883 * mesh instance containing the simplices.<br>
1884 * \param [in] policy - specifies a pattern used for splitting. For its description, see
1885 * MEDCouplingUMesh::simplexize().
1886 * \return bool - \c true if some cells have been divided and hence \a this field lies
1888 * \throw If \a policy has an invalid value. For valid values, see the description of
1889 * MEDCouplingUMesh::simplexize().
1890 * \throw If MEDCouplingMesh::simplexize() is not applicable to the underlying mesh.
1891 * \throw If the mesh is not well defined.
1892 * \throw If the spatial discretization of \a this field is NULL.
1893 * \throw If the data array is not set.
1895 bool MEDCouplingFieldDouble::simplexize(int policy)
1898 throw INTERP_KERNEL::Exception("No underlying mesh on this field to perform simplexize !");
1900 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform simplexize !");
1901 std::size_t oldNbOfCells=_mesh->getNumberOfCells();
1902 MCAuto<MEDCouplingMesh> meshC2(_mesh->deepCopy());
1903 MCAuto<DataArrayIdType> arr=meshC2->simplexize(policy);
1904 std::size_t newNbOfCells=meshC2->getNumberOfCells();
1905 if(oldNbOfCells==newNbOfCells)
1907 std::vector<DataArrayDouble *> arrays;
1908 timeDiscr()->getArrays(arrays);
1909 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1911 _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),ToIdType(arr->getNbOfElems()),*iter);
1917 * This method makes the hypothesis that \a this is a Gauss field. This method returns a newly created field on cells with same number of tuples than \a this.
1918 * Each Gauss points in \a this is replaced by a polygon or polyhedron cell with associated region following Voronoi algorithm.
1920 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoize(double eps) const
1922 checkConsistencyLight();
1923 const MEDCouplingMesh *mesh(getMesh());
1924 INTERP_KERNEL::AutoCppPtr<Voronizer> vor;
1925 std::size_t meshDim(mesh->getMeshDimension()),spaceDim(mesh->getSpaceDimension());
1926 if(meshDim==1 && (spaceDim==1 || spaceDim==2 || spaceDim==3))
1927 vor=new Voronizer1D;
1928 else if(meshDim==2 && (spaceDim==2 || spaceDim==3))
1929 vor=new Voronizer2D;
1930 else if(meshDim==3 && spaceDim==3)
1931 vor=new Voronizer3D;
1933 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize : only 2D, 3D surf, and 3D are supported for the moment !");
1934 return voronoizeGen(vor,eps);
1938 * \sa MEDCouplingUMesh::convertQuadraticCellsToLinear
1940 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::convertQuadraticCellsToLinear() const
1942 checkConsistencyLight();
1943 switch(getTypeOfField())
1947 const MEDCouplingMesh *mesh(getMesh());
1949 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
1950 MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1951 umesh=umesh->clone(false);
1952 umesh->convertQuadraticCellsToLinear();
1953 MCAuto<DataArrayIdType> o2n(umesh->zipCoordsTraducer());
1954 MCAuto<DataArrayIdType> n2o(o2n->invertArrayO2N2N2O(umesh->getNumberOfNodes()));
1955 MCAuto<DataArrayDouble> arr(getArray()->selectByTupleIdSafe(n2o->begin(),n2o->end()));
1956 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_NODES));
1958 ret->setMesh(umesh);
1959 ret->copyAllTinyAttrFrom(this);
1964 const MEDCouplingMesh *mesh(getMesh());
1966 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
1967 MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1968 umesh=umesh->clone(false);
1969 umesh->convertQuadraticCellsToLinear();
1971 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
1972 ret->setArray(const_cast<DataArrayDouble *>(getArray()));
1973 ret->setMesh(umesh);
1974 ret->copyAllTinyAttrFrom(this);
1979 const MEDCouplingMesh *mesh(getMesh());
1981 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
1982 MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1983 std::set<INTERP_KERNEL::NormalizedCellType> gt(umesh->getAllGeoTypes());
1984 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_GAUSS_PT));
1986 const MEDCouplingFieldDiscretization *disc(getDiscretization());
1987 const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
1989 throw INTERP_KERNEL::Exception("convertQuadraticCellsToLinear : Not a ON_GAUSS_PT field");
1990 std::set<INTERP_KERNEL::NormalizedCellType> gt2(umesh->getAllGeoTypes());
1991 std::vector< MCAuto<DataArrayIdType> > cellIdsV;
1992 std::vector< MCAuto<MEDCouplingUMesh> > meshesV;
1993 std::vector< MEDCouplingGaussLocalization > glV;
1994 bool isZipReq(false);
1995 for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=gt.begin();it!=gt.end();it++)
1997 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it));
1998 MCAuto<DataArrayIdType> cellIds(umesh->giveCellsWithType(*it));
1999 cellIdsV.push_back(cellIds);
2000 MCAuto<MEDCouplingUMesh> part(umesh->buildPartOfMySelf(cellIds->begin(),cellIds->end()));
2001 mcIdType id(disc2->getGaussLocalizationIdOfOneType(*it));
2002 const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(id));
2003 if(!cm.isQuadratic())
2010 part->convertQuadraticCellsToLinear();
2011 INTERP_KERNEL::GaussInfo gi(*it,gl.getGaussCoords(),gl.getNumberOfGaussPt(),gl.getRefCoords(),gl.getNumberOfPtsInRefCell());
2012 INTERP_KERNEL::GaussInfo gi2(gi.convertToLinear());
2013 MEDCouplingGaussLocalization gl2(gi2.getGeoType(),gi2.getRefCoords(),gi2.getGaussCoords(),gl.getWeights());
2016 meshesV.push_back(part);
2020 std::vector< const MEDCouplingUMesh * > meshesPtr(VecAutoToVecOfCstPt(meshesV));
2021 umesh=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshesPtr);
2022 std::vector< const DataArrayIdType * > zeCellIds(VecAutoToVecOfCstPt(cellIdsV));
2023 MCAuto<DataArrayIdType> zeIds(DataArrayIdType::Aggregate(zeCellIds));
2024 umesh->renumberCells(zeIds->begin());
2025 umesh->setName(mesh->getName());
2030 ret->setArray(const_cast<DataArrayDouble *>(getArray()));
2031 ret->setMesh(umesh);
2032 for(std::vector< MEDCouplingGaussLocalization >::const_iterator it=glV.begin();it!=glV.end();it++)
2033 ret->setGaussLocalizationOnType((*it).getType(),(*it).getRefCoords(),(*it).getGaussCoords(),(*it).getWeights());
2034 ret->copyAllTinyAttrFrom(this);
2035 ret->checkConsistencyLight();
2039 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : Only available for fields on nodes and on cells !");
2044 * This is expected to be a 3 components vector field on nodes (if not an exception will be thrown). \a this is also expected to lie on a MEDCouplingPointSet mesh.
2045 * Finally \a this is also expected to be consistent.
2046 * In these conditions this method returns a newly created field (to be dealed by the caller).
2047 * The returned field will also 3 compo vector field be on nodes lying on the same mesh than \a this.
2049 * For each 3 compo tuple \a tup in \a this the returned tuple is the result of the transformation of \a tup in the new referential. This referential is defined by \a Ur, \a Uteta, \a Uz.
2050 * \a Ur is the vector between \a center point and the associated node with \a tuple. \a Uz is \a vect normalized. And Uteta is the cross product of \a Uz with \a Ur.
2052 * \sa DataArrayDouble::fromCartToCylGiven
2054 MEDCouplingFieldDouble *MEDCouplingFieldDouble::computeVectorFieldCyl(const double center[3], const double vect[3]) const
2056 checkConsistencyLight();
2057 const DataArrayDouble *coo(getMesh()->getDirectAccessOfCoordsArrIfInStructure());
2058 MEDCouplingTimeDiscretization *td(timeDiscr()->computeVectorFieldCyl(coo,center,vect));
2059 td->copyTinyAttrFrom(*timeDiscr());
2060 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2061 ret->setMesh(getMesh());
2062 ret->setName(getName());
2067 * Creates a new MEDCouplingFieldDouble filled with the doubly contracted product of
2068 * every tensor of \a this 6-componental field.
2069 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2070 * each tuple is calculated from the tuple <em>(t)</em> of \a this field as
2071 * follows: \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2072 * This new field lies on the same mesh as \a this one. The caller is to delete
2073 * this field using decrRef() as it is no more needed.
2074 * \throw If \a this->getNumberOfComponents() != 6.
2075 * \throw If the spatial discretization of \a this field is NULL.
2077 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const
2080 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform doublyContractedProduct !");
2081 MEDCouplingTimeDiscretization *td(timeDiscr()->doublyContractedProduct());
2082 td->copyTinyAttrFrom(*timeDiscr());
2083 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2084 ret->setName("DoublyContractedProduct");
2085 ret->setMesh(getMesh());
2090 * Creates a new MEDCouplingFieldDouble filled with the determinant of a square
2091 * matrix defined by every tuple of \a this field, having either 4, 6 or 9 components.
2092 * The case of 6 components corresponds to that of the upper triangular matrix.
2093 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2094 * each tuple is the determinant of matrix of the corresponding tuple of \a this
2095 * field. This new field lies on the same mesh as \a this one. The caller is to
2096 * delete this field using decrRef() as it is no more needed.
2097 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2098 * \throw If the spatial discretization of \a this field is NULL.
2100 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const
2103 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform determinant !");
2104 MEDCouplingTimeDiscretization *td(timeDiscr()->determinant());
2105 td->copyTinyAttrFrom(*timeDiscr());
2106 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2107 ret->setName("Determinant");
2108 ret->setMesh(getMesh());
2114 * Creates a new MEDCouplingFieldDouble with 3 components filled with 3 eigenvalues of
2115 * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2116 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2117 * having 3 components, whose each tuple contains the eigenvalues of the matrix of
2118 * corresponding tuple of \a this field. This new field lies on the same mesh as
2119 * \a this one. The caller is to delete this field using decrRef() as it is no
2121 * \throw If \a this->getNumberOfComponents() != 6.
2122 * \throw If the spatial discretization of \a this field is NULL.
2124 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const
2127 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenValues !");
2128 MEDCouplingTimeDiscretization *td(timeDiscr()->eigenValues());
2129 td->copyTinyAttrFrom(*timeDiscr());
2130 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2131 ret->setName("EigenValues");
2132 ret->setMesh(getMesh());
2137 * Creates a new MEDCouplingFieldDouble with 9 components filled with 3 eigenvectors of
2138 * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2139 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2140 * having 9 components, whose each tuple contains the eigenvectors of the matrix of
2141 * corresponding tuple of \a this field. This new field lies on the same mesh as
2142 * \a this one. The caller is to delete this field using decrRef() as it is no
2144 * \throw If \a this->getNumberOfComponents() != 6.
2145 * \throw If the spatial discretization of \a this field is NULL.
2147 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const
2150 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenVectors !");
2151 MEDCouplingTimeDiscretization *td(timeDiscr()->eigenVectors());
2152 td->copyTinyAttrFrom(*timeDiscr());
2153 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2154 ret->setName("EigenVectors");
2155 ret->setMesh(getMesh());
2160 * Creates a new MEDCouplingFieldDouble filled with the inverse matrix of
2161 * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2162 * components. The case of 6 components corresponds to that of the upper triangular
2164 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2165 * having the same number of components as \a this one, whose each tuple
2166 * contains the inverse matrix of the matrix of corresponding tuple of \a this
2167 * field. This new field lies on the same mesh as \a this one. The caller is to
2168 * delete this field using decrRef() as it is no more needed.
2169 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2170 * \throw If the spatial discretization of \a this field is NULL.
2172 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const
2175 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform inverse !");
2176 MEDCouplingTimeDiscretization *td(timeDiscr()->inverse());
2177 td->copyTinyAttrFrom(*timeDiscr());
2178 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2179 ret->setName("Inversion");
2180 ret->setMesh(getMesh());
2185 * Creates a new MEDCouplingFieldDouble filled with the trace of
2186 * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2187 * components. The case of 6 components corresponds to that of the upper triangular
2189 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2190 * having 1 component, whose each tuple is the trace of the matrix of
2191 * corresponding tuple of \a this field.
2192 * This new field lies on the same mesh as \a this one. The caller is to
2193 * delete this field using decrRef() as it is no more needed.
2194 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2195 * \throw If the spatial discretization of \a this field is NULL.
2197 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const
2200 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform trace !");
2201 MEDCouplingTimeDiscretization *td(timeDiscr()->trace());
2202 td->copyTinyAttrFrom(*timeDiscr());
2203 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2204 ret->setName("Trace");
2205 ret->setMesh(getMesh());
2210 * Creates a new MEDCouplingFieldDouble filled with the stress deviator tensor of
2211 * a stress tensor defined by every tuple of \a this 6-componental field.
2212 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2213 * having same number of components and tuples as \a this field,
2214 * whose each tuple contains the stress deviator tensor of the stress tensor of
2215 * corresponding tuple of \a this field. This new field lies on the same mesh as
2216 * \a this one. The caller is to delete this field using decrRef() as it is no
2218 * \throw If \a this->getNumberOfComponents() != 6.
2219 * \throw If the spatial discretization of \a this field is NULL.
2221 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const
2224 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform deviator !");
2225 MEDCouplingTimeDiscretization *td(timeDiscr()->deviator());
2226 td->copyTinyAttrFrom(*timeDiscr());
2227 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2228 ret->setName("Deviator");
2229 ret->setMesh(getMesh());
2234 * Creates a new MEDCouplingFieldDouble filled with the magnitude of
2235 * every vector of \a this field.
2236 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2237 * having one component, whose each tuple is the magnitude of the vector
2238 * of corresponding tuple of \a this field. This new field lies on the
2239 * same mesh as \a this one. The caller is to
2240 * delete this field using decrRef() as it is no more needed.
2241 * \throw If the spatial discretization of \a this field is NULL.
2243 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const
2246 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform magnitude !");
2247 MEDCouplingTimeDiscretization *td(timeDiscr()->magnitude());
2248 td->copyTinyAttrFrom(*timeDiscr());
2249 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2250 ret->setName("Magnitude");
2251 ret->setMesh(getMesh());
2256 * Creates a new scalar MEDCouplingFieldDouble filled with the maximal value among
2257 * values of every tuple of \a this field.
2258 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2259 * This new field lies on the same mesh as \a this one. The caller is to
2260 * delete this field using decrRef() as it is no more needed.
2261 * \throw If the spatial discretization of \a this field is NULL.
2263 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const
2266 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform maxPerTuple !");
2267 MEDCouplingTimeDiscretization *td(timeDiscr()->maxPerTuple());
2268 td->copyTinyAttrFrom(*timeDiscr());
2269 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2270 std::ostringstream oss;
2271 oss << "Max_" << getName();
2272 ret->setName(oss.str());
2273 ret->setMesh(getMesh());
2278 * Changes number of components in \a this field. If \a newNbOfComp is less
2279 * than \a this->getNumberOfComponents() then each tuple
2280 * is truncated to have \a newNbOfComp components, keeping first components. If \a
2281 * newNbOfComp is more than \a this->getNumberOfComponents() then
2282 * each tuple is populated with \a dftValue to have \a newNbOfComp components.
2283 * \param [in] newNbOfComp - number of components for the new field to have.
2284 * \param [in] dftValue - value assigned to new values added to \a this field.
2285 * \throw If \a this is not allocated.
2287 void MEDCouplingFieldDouble::changeNbOfComponents(std::size_t newNbOfComp, double dftValue)
2289 timeDiscr()->changeNbOfComponents(newNbOfComp,dftValue);
2293 * Creates a new MEDCouplingFieldDouble composed of selected components of \a this field.
2294 * The new MEDCouplingFieldDouble has the same number of tuples but includes components
2295 * specified by \a compoIds parameter. So that getNbOfElems() of the result field
2296 * can be either less, same or more than \a this->getNumberOfValues().
2297 * \param [in] compoIds - sequence of zero based indices of components to include
2298 * into the new field.
2299 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble that the caller
2300 * is to delete using decrRef() as it is no more needed.
2301 * \throw If a component index (\a i) is not valid:
2302 * \a i < 0 || \a i >= \a this->getNumberOfComponents().
2304 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<std::size_t>& compoIds) const
2307 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform keepSelectedComponents !");
2308 MEDCouplingTimeDiscretization *td(timeDiscr()->keepSelectedComponents(compoIds));
2309 td->copyTinyAttrFrom(*timeDiscr());
2310 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2311 ret->setName(getName());
2312 ret->setMesh(getMesh());
2317 * Copy all components in a specified order from another field.
2318 * The number of tuples in \a this and the other field can be different.
2319 * \param [in] f - the field to copy data from.
2320 * \param [in] compoIds - sequence of zero based indices of components, data of which is
2322 * \throw If the two fields have different number of data arrays.
2323 * \throw If a data array is set in one of fields and is not set in the other.
2324 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2325 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2327 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<std::size_t>& compoIds)
2329 timeDiscr()->setSelectedComponents(f->timeDiscr(),compoIds);
2333 * Sorts value within every tuple of \a this field.
2334 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2335 * in descending order.
2336 * \throw If a data array is not allocated.
2338 void MEDCouplingFieldDouble::sortPerTuple(bool asc)
2340 timeDiscr()->sortPerTuple(asc);
2344 * Creates a new MEDCouplingFieldDouble by concatenating two given fields.
2346 * the first field precede values of the second field within the result field.
2347 * \param [in] f1 - the first field.
2348 * \param [in] f2 - the second field.
2349 * \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2350 * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef()
2351 * as it is no more needed.
2352 * \throw If the fields are not compatible for the merge.
2353 * \throw If the spatial discretization of \a f1 is NULL.
2354 * \throw If the time discretization of \a f1 is NULL.
2356 * \if ENABLE_EXAMPLES
2357 * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2358 * \ref py_mcfielddouble_MergeFields "Here is a Python example".
2361 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2363 std::vector<const MEDCouplingFieldDouble *> a(2);
2365 return MergeFields(a);
2369 * Creates a new MEDCouplingFieldDouble by concatenating all given fields.
2370 * Values of the *i*-th field precede values of the (*i*+1)-th field within the result.
2371 * If there is only one field in \a a, a deepCopy() (except time information of mesh and
2372 * field) of the field is returned.
2373 * Generally speaking the first field in \a a is used to assign tiny attributes of the
2375 * \param [in] a - a vector of fields (MEDCouplingFieldDouble) to concatenate.
2376 * \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2377 * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef()
2378 * as it is no more needed.
2379 * \throw If \a a is empty.
2380 * \throw If the fields are not compatible for the merge.
2382 * \if ENABLE_EXAMPLES
2383 * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2384 * \ref py_mcfielddouble_MergeFields "Here is a Python example".
2387 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a)
2390 throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : input array is empty !");
2391 std::vector< MCAuto<MEDCouplingUMesh> > ms(a.size());
2392 std::vector< const MEDCouplingUMesh *> ms2(a.size());
2393 std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
2394 std::vector< const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
2395 std::vector<const MEDCouplingFieldDiscretization *> fds(a.size());
2396 const MEDCouplingFieldDouble *ref((*it++));
2398 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of nullptr instance in first place of input vector !");
2399 if(!ref->getDiscretization())
2400 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : nullptr spatial discretization !");
2401 for(;it!=a.end();it++)
2402 if(!ref->areCompatibleForMerge(*it))
2403 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2404 for(std::size_t i=0;i<a.size();i++)
2407 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of nullptr instance in input vector !");
2409 { ms[i]=a[i]->getMesh()->buildUnstructured(); ms2[i]=ms[i]; }
2411 { ms[i]=0; ms2[i]=0; }
2412 tds[i]=a[i]->timeDiscr();
2413 fds[i]=a[i]->getDiscretization();
2415 MEDCouplingTimeDiscretization *td(tds[0]->aggregate(tds));
2416 MCAuto<MEDCouplingFieldDiscretization> fda(fds[0]->aggregate(fds));
2417 td->copyTinyAttrFrom(*(a[0]->timeDiscr()));
2418 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(a[0]->getNature(),td,fda.retn()));
2419 ret->setName(a[0]->getName());
2420 ret->setDescription(a[0]->getDescription());
2423 MCAuto<MEDCouplingUMesh> m(MEDCouplingUMesh::MergeUMeshes(ms2));
2424 m->copyTinyInfoFrom(ms2[0]);
2431 * Creates a new MEDCouplingFieldDouble by concatenating components of two given fields.
2432 * The number of components in the result field is a sum of the number of components of
2433 * given fields. The number of tuples in the result field is same as that of each of given
2435 * Number of tuples in the given fields must be the same.
2436 * \param [in] f1 - a field to include in the result field.
2437 * \param [in] f2 - another field to include in the result field.
2438 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2439 * The caller is to delete this result field using decrRef() as it is no more
2441 * \throw If the fields are not compatible for a meld (areCompatibleForMeld()).
2442 * \throw If any of data arrays is not allocated.
2443 * \throw If \a f1->getNumberOfTuples() != \a f2->getNumberOfTuples()
2445 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2448 throw INTERP_KERNEL::Exception("MeldFields : null input pointer !");
2449 if(!f1->areCompatibleForMeld(f2))
2450 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
2451 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->meld(f2->timeDiscr()));
2452 td->copyTinyAttrFrom(*f1->timeDiscr());
2453 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2454 ret->setMesh(f1->getMesh());
2459 * Returns a new MEDCouplingFieldDouble containing a dot product of two given fields,
2460 * so that the i-th tuple of the result field is a sum of products of j-th components of
2461 * i-th tuples of given fields (\f$ f_i = \sum_{j=1}^n f1_j * f2_j \f$).
2462 * Number of tuples and components in the given fields must be the same.
2463 * \param [in] f1 - a given field.
2464 * \param [in] f2 - another given field.
2465 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2466 * The caller is to delete this result field using decrRef() as it is no more
2468 * \throw If either \a f1 or \a f2 is NULL.
2469 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2470 * differ not only in values.
2472 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2475 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !");
2476 if(!f1->areStrictlyCompatibleForMulDiv(f2))
2477 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them! Check support mesh, and spatial and time discretisation.");
2478 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->dot(f2->timeDiscr()));
2479 td->copyTinyAttrFrom(*f1->timeDiscr());
2480 MEDCouplingFieldDouble *ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2481 ret->setMesh(f1->getMesh());
2486 * Returns a new MEDCouplingFieldDouble containing a cross product of two given fields,
2488 * the i-th tuple of the result field is a 3D vector which is a cross
2489 * product of two vectors defined by the i-th tuples of given fields.
2490 * Number of tuples in the given fields must be the same.
2491 * Number of components in the given fields must be 3.
2492 * \param [in] f1 - a given field.
2493 * \param [in] f2 - another given field.
2494 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2495 * The caller is to delete this result field using decrRef() as it is no more
2497 * \throw If either \a f1 or \a f2 is NULL.
2498 * \throw If \a f1->getNumberOfComponents() != 3
2499 * \throw If \a f2->getNumberOfComponents() != 3
2500 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2501 * differ not only in values.
2503 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2506 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !");
2507 if(!f1->areStrictlyCompatibleForMulDiv(f2))
2508 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation.");
2509 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->crossProduct(f2->timeDiscr()));
2510 td->copyTinyAttrFrom(*f1->timeDiscr());
2511 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2512 ret->setMesh(f1->getMesh());
2517 * Returns a new MEDCouplingFieldDouble containing maximal values of two given fields.
2518 * Number of tuples and components in the given fields must be the same.
2519 * \param [in] f1 - a field to compare values with another one.
2520 * \param [in] f2 - another field to compare values with the first one.
2521 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2522 * The caller is to delete this result field using decrRef() as it is no more
2524 * \throw If either \a f1 or \a f2 is NULL.
2525 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2526 * differ not only in values.
2528 * \if ENABLE_EXAMPLES
2529 * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2530 * \ref py_mcfielddouble_MaxFields "Here is a Python example".
2533 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2536 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MaxFields : input field is NULL !");
2537 if(!f1->areStrictlyCompatible(f2))
2538 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MaxFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2539 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->max(f2->timeDiscr()));
2540 td->copyTinyAttrFrom(*f1->timeDiscr());
2541 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2542 ret->setMesh(f1->getMesh());
2547 * Returns a new MEDCouplingFieldDouble containing minimal values of two given fields.
2548 * Number of tuples and components in the given fields must be the same.
2549 * \param [in] f1 - a field to compare values with another one.
2550 * \param [in] f2 - another field to compare values with the first one.
2551 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2552 * The caller is to delete this result field using decrRef() as it is no more
2554 * \throw If either \a f1 or \a f2 is NULL.
2555 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2556 * differ not only in values.
2558 * \if ENABLE_EXAMPLES
2559 * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2560 * \ref py_mcfielddouble_MaxFields "Here is a Python example".
2563 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2566 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MinFields : input field is NULL !");
2567 if(!f1->areStrictlyCompatible(f2))
2568 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MinFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2569 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->min(f2->timeDiscr()));
2570 td->copyTinyAttrFrom(*f1->timeDiscr());
2571 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2572 ret->setMesh(f1->getMesh());
2577 * Returns a copy of \a this field in which sign of all values is reversed.
2578 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble
2579 * containing the same number of tuples and components as \a this field.
2580 * The caller is to delete this result field using decrRef() as it is no more
2582 * \throw If the spatial discretization of \a this field is NULL.
2583 * \throw If a data array is not allocated.
2585 MEDCouplingFieldDouble *MEDCouplingFieldDouble::negate() const
2588 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform negate !");
2589 MEDCouplingTimeDiscretization *td(timeDiscr()->negate());
2590 td->copyTinyAttrFrom(*timeDiscr());
2591 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2592 ret->setMesh(getMesh());
2597 * Returns a new MEDCouplingFieldDouble containing sum values of corresponding values of
2598 * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] + _f2_ [ i, j ] ).
2599 * Number of tuples and components in the given fields must be the same.
2600 * \param [in] f1 - a field to sum up.
2601 * \param [in] f2 - another field to sum up.
2602 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2603 * The caller is to delete this result field using decrRef() as it is no more
2605 * \throw If either \a f1 or \a f2 is NULL.
2606 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2607 * differ not only in values.
2609 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2612 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::AddFields : input field is NULL !");
2613 if(!f1->areStrictlyCompatible(f2))
2614 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply AddFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2615 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->add(f2->timeDiscr()));
2616 td->copyTinyAttrFrom(*f1->timeDiscr());
2617 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2618 ret->setMesh(f1->getMesh());
2623 * Adds values of another MEDCouplingFieldDouble to values of \a this one
2624 * ( _this_ [ i, j ] += _other_ [ i, j ] ) using DataArrayDouble::addEqual().
2625 * The two fields must have same number of tuples, components and same underlying mesh.
2626 * \param [in] other - the field to add to \a this one.
2627 * \return const MEDCouplingFieldDouble & - a reference to \a this field.
2628 * \throw If \a other is NULL.
2629 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2630 * differ not only in values.
2632 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other)
2634 if(!areStrictlyCompatible(&other))
2635 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply += on them! Check support mesh, field nature, and spatial and time discretisation.");
2636 timeDiscr()->addEqual(other.timeDiscr());
2641 * Returns a new MEDCouplingFieldDouble containing subtraction of corresponding values of
2642 * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] - _f2_ [ i, j ] ).
2643 * Number of tuples and components in the given fields must be the same.
2644 * \param [in] f1 - a field to subtract from.
2645 * \param [in] f2 - a field to subtract.
2646 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2647 * The caller is to delete this result field using decrRef() as it is no more
2649 * \throw If either \a f1 or \a f2 is NULL.
2650 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2651 * differ not only in values.
2653 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2656 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::SubstractFields : input field is NULL !");
2657 if(!f1->areStrictlyCompatible(f2))
2658 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply SubstractFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2659 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->substract(f2->timeDiscr()));
2660 td->copyTinyAttrFrom(*f1->timeDiscr());
2661 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2662 ret->setMesh(f1->getMesh());
2667 * Subtract values of another MEDCouplingFieldDouble from values of \a this one
2668 * ( _this_ [ i, j ] -= _other_ [ i, j ] ) using DataArrayDouble::substractEqual().
2669 * The two fields must have same number of tuples, components and same underlying mesh.
2670 * \param [in] other - the field to subtract from \a this one.
2671 * \return const MEDCouplingFieldDouble & - a reference to \a this field.
2672 * \throw If \a other is NULL.
2673 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2674 * differ not only in values.
2676 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other)
2678 if(!areStrictlyCompatible(&other))
2679 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply -= on them! Check support mesh, field nature, and spatial and time discretisation.");
2680 timeDiscr()->substractEqual(other.timeDiscr());
2685 * Returns a new MEDCouplingFieldDouble containing product values of
2686 * two given fields. There are 2 valid cases.
2687 * 1. The fields have same number of tuples and components. Then each value of
2688 * the result field (_f_) is a product of the corresponding values of _f1_ and
2689 * _f2_, i.e. _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, j ].
2690 * 2. The fields have same number of tuples and one field, say _f2_, has one
2692 * _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, 0 ].
2694 * The two fields must have same number of tuples and same underlying mesh.
2695 * \param [in] f1 - a factor field.
2696 * \param [in] f2 - another factor field.
2697 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2698 * The caller is to delete this result field using decrRef() as it is no more
2700 * \throw If either \a f1 or \a f2 is NULL.
2701 * \throw If the fields are not compatible for multiplication (areCompatibleForMul()),
2702 * i.e. they differ not only in values and possibly number of components.
2704 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2707 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MultiplyFields : input field is NULL !");
2708 if(!f1->areCompatibleForMul(f2))
2709 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MultiplyFields on them! Check support mesh, and spatial and time discretisation.");
2710 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->multiply(f2->timeDiscr()));
2711 td->copyTinyAttrFrom(*f1->timeDiscr());
2712 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2713 ret->setMesh(f1->getMesh());
2718 * Multiply values of another MEDCouplingFieldDouble to values of \a this one
2719 * using DataArrayDouble::multiplyEqual().
2720 * The two fields must have same number of tuples and same underlying mesh.
2721 * There are 2 valid cases.
2722 * 1. The fields have same number of components. Then each value of
2723 * \a other is multiplied to the corresponding value of \a this field, i.e.
2724 * _this_ [ i, j ] *= _other_ [ i, j ].
2725 * 2. The _other_ field has one component. Then
2726 * _this_ [ i, j ] *= _other_ [ i, 0 ].
2728 * The two fields must have same number of tuples and same underlying mesh.
2729 * \param [in] other - an field to multiply to \a this one.
2730 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2731 * The caller is to delete this result field using decrRef() as it is no more
2733 * \throw If \a other is NULL.
2734 * \throw If the fields are not strictly compatible for multiplication
2735 * (areCompatibleForMul()),
2736 * i.e. they differ not only in values and possibly in number of components.
2738 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other)
2740 if(!areCompatibleForMul(&other))
2741 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply *= on them! Check support mesh, and spatial and time discretisation.");
2742 timeDiscr()->multiplyEqual(other.timeDiscr());
2748 * Returns a new MEDCouplingFieldDouble containing division of two given fields.
2749 * There are 2 valid cases.
2750 * 1. The fields have same number of tuples and components. Then each value of
2751 * the result field (_f_) is a division of the corresponding values of \a f1 and
2752 * \a f2, i.e. _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, j ].
2753 * 2. The fields have same number of tuples and _f2_ has one component. Then
2754 * _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, 0 ].
2756 * \param [in] f1 - a numerator field.
2757 * \param [in] f2 - a denominator field.
2758 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2759 * The caller is to delete this result field using decrRef() as it is no more
2761 * \throw If either \a f1 or \a f2 is NULL.
2762 * \throw If the fields are not compatible for division (areCompatibleForDiv()),
2763 * i.e. they differ not only in values and possibly in number of components.
2765 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2768 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DivideFields : input field is NULL !");
2769 if(!f1->areCompatibleForDiv(f2))
2770 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DivideFields on them! Check support mesh, and spatial and time discretisation.");
2771 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->divide(f2->timeDiscr()));
2772 td->copyTinyAttrFrom(*f1->timeDiscr());
2773 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2774 ret->setMesh(f1->getMesh());
2779 * Divide values of \a this field by values of another MEDCouplingFieldDouble
2780 * using DataArrayDouble::divideEqual().
2781 * The two fields must have same number of tuples and same underlying mesh.
2782 * There are 2 valid cases.
2783 * 1. The fields have same number of components. Then each value of
2784 * \a this field is divided by the corresponding value of \a other one, i.e.
2785 * _this_ [ i, j ] /= _other_ [ i, j ].
2786 * 2. The \a other field has one component. Then
2787 * _this_ [ i, j ] /= _other_ [ i, 0 ].
2789 * \warning No check of division by zero is performed!
2790 * \param [in] other - an field to divide \a this one by.
2791 * \throw If \a other is NULL.
2792 * \throw If the fields are not compatible for division (areCompatibleForDiv()),
2793 * i.e. they differ not only in values and possibly in number of components.
2795 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other)
2797 if(!areCompatibleForDiv(&other))
2798 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply /= on them! Check support mesh, and spatial and time discretisation.");
2799 timeDiscr()->divideEqual(other.timeDiscr());
2805 * Directly called by MEDCouplingFieldDouble::operator^.
2807 * \sa MEDCouplingFieldDouble::operator^
2809 MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2812 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::PowFields : input field is NULL !");
2813 if(!f1->areCompatibleForMul(f2))
2814 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply PowFields on them! Check support mesh, and spatial and time discretisation.");
2815 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->pow(f2->timeDiscr()));
2816 td->copyTinyAttrFrom(*f1->timeDiscr());
2817 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2818 ret->setMesh(f1->getMesh());
2823 * Directly call MEDCouplingFieldDouble::PowFields static method.
2825 * \sa MEDCouplingFieldDouble::PowFields
2827 MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const
2829 return PowFields(this,&other);
2832 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other)
2834 if(!areCompatibleForDiv(&other))
2835 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply ^= on them! Check support mesh, and spatial and time discretisation.");
2836 timeDiscr()->powEqual(other.timeDiscr());
2842 * Writes the field series \a fs and the mesh the fields lie on in the VTK file \a fileName.
2843 * If \a fs is empty no file is written.
2844 * The result file is valid provided that no exception is thrown.
2845 * \warning All the fields must be named and lie on the same non NULL mesh.
2846 * \param [in] fileName - the name of a VTK file to write in.
2847 * \param [in] fs - the fields to write.
2848 * \param [in] isBinary - specifies the VTK format of the written file. By default true (Binary mode)
2849 * \throw If \a fs[ 0 ] == NULL.
2850 * \throw If the fields lie not on the same mesh.
2851 * \throw If the mesh is not set.
2852 * \throw If any of the fields has no name.
2854 * \if ENABLE_EXAMPLES
2855 * \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".<br>
2856 * \ref py_mcfielddouble_WriteVTK "Here is a Python example".
2859 std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector<const MEDCouplingFieldDouble *>& fs, bool isBinary)
2862 return std::string();
2863 std::size_t nfs=fs.size();
2865 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field is NULL !");
2866 const MEDCouplingMesh *m=fs[0]->getMesh();
2868 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field lies on NULL mesh !");
2869 for(std::size_t i=1;i<nfs;i++)
2870 if(fs[i]->getMesh()!=m)
2871 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.");
2873 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !");
2874 std::string ret(m->getVTKFileNameOf(fileName));
2875 MCAuto<DataArrayByte> byteArr;
2877 { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); }
2878 std::ostringstream coss,noss;
2879 for(std::size_t i=0;i<nfs;i++)
2881 const MEDCouplingFieldDouble *cur=fs[i];
2882 std::string name(cur->getName());
2885 std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
2886 throw INTERP_KERNEL::Exception(oss.str());
2888 TypeOfField typ=cur->getTypeOfField();
2890 cur->getArray()->writeVTK(coss,8,cur->getName(),byteArr);
2891 else if(typ==ON_NODES)
2892 cur->getArray()->writeVTK(noss,8,cur->getName(),byteArr);
2894 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : only node and cell fields supported for the moment !");
2896 m->writeVTKAdvanced(ret,coss.str(),noss.str(),byteArr);
2900 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoizeGen(const Voronizer *vor, double eps) const
2902 checkConsistencyLight();
2904 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoizeGen : null pointer !");
2905 MCAuto<MEDCouplingFieldDouble> fieldToWO;
2906 const MEDCouplingMesh *inpMeshBase(getMesh());
2907 MCAuto<MEDCouplingUMesh> inpMesh(inpMeshBase->buildUnstructured());
2908 std::string meshName(inpMesh->getName());
2909 if(!inpMesh->isPresenceOfQuadratic())
2910 fieldToWO=clone(false);
2913 fieldToWO=convertQuadraticCellsToLinear();
2914 inpMeshBase=fieldToWO->getMesh();
2915 inpMesh=inpMeshBase->buildUnstructured();
2917 mcIdType nbCells(inpMesh->getNumberOfCells());
2918 const MEDCouplingFieldDiscretization *disc(fieldToWO->getDiscretization());
2919 const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
2921 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : Not a ON_GAUSS_PT field");
2922 mcIdType nbLocs(disc2->getNbOfGaussLocalization());
2923 std::vector< MCAuto<MEDCouplingUMesh> > cells(nbCells);
2924 for(mcIdType i=0;i<nbLocs;i++)
2926 const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(i));
2927 if(gl.getDimension()!=vor->getDimension())
2928 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : not a 2D one !");
2929 MCAuto<MEDCouplingUMesh> mesh(gl.buildRefCell());
2930 const std::vector<double>& coo(gl.getGaussCoords());
2931 MCAuto<DataArrayDouble> coo2(DataArrayDouble::NewFromStdVector(coo));
2932 coo2->rearrange(vor->getDimension());
2934 MCAuto<MEDCouplingUMesh> coo3(MEDCouplingUMesh::Build0DMeshFromCoords(coo2));
2936 MCAuto<MEDCouplingUMesh> vorCellsForCurDisc(vor->doIt(mesh,coo2,eps));
2937 std::vector<mcIdType> ids;
2938 MCAuto<DataArrayDouble> ptsInReal;
2939 disc2->getCellIdsHavingGaussLocalization(i,ids);
2941 MCAuto<MEDCouplingUMesh> subMesh(inpMesh->buildPartOfMySelf(&ids[0],&ids[0]+ids.size()));
2942 ptsInReal=gl.localizePtsInRefCooForEachCell(vorCellsForCurDisc->getCoords(),subMesh);
2944 mcIdType nbPtsPerCell(vorCellsForCurDisc->getNumberOfNodes());
2945 for(mcIdType j=0;j<ToIdType(ids.size());j++)
2947 MCAuto<MEDCouplingUMesh> elt(vorCellsForCurDisc->clone(false));
2948 MCAuto<DataArrayDouble> coo4(ptsInReal->selectByTupleIdSafeSlice(j*nbPtsPerCell,(j+1)*nbPtsPerCell,1));
2949 elt->setCoords(coo4);
2953 std::vector< const MEDCouplingUMesh * > cellsPtr(VecAutoToVecOfCstPt(cells));
2954 MCAuto<MEDCouplingUMesh> outMesh(MEDCouplingUMesh::MergeUMeshes(cellsPtr));
2955 outMesh->setName(meshName);
2956 MCAuto<MEDCouplingFieldDouble> onCells(MEDCouplingFieldDouble::New(ON_CELLS));
2957 onCells->setMesh(outMesh);
2959 MCAuto<DataArrayDouble> arr(fieldToWO->getArray()->deepCopy());
2960 onCells->setArray(arr);
2962 onCells->setTimeUnit(getTimeUnit());
2965 double a(getTime(b,c));
2966 onCells->setTime(a,b,c);
2968 onCells->setName(getName());
2972 MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr()
2974 MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
2977 MEDCouplingTimeDiscretization *retc(dynamic_cast<MEDCouplingTimeDiscretization *>(ret));
2979 throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");
2983 const MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr() const
2985 const MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
2988 const MEDCouplingTimeDiscretization *retc(dynamic_cast<const MEDCouplingTimeDiscretization *>(ret));
2990 throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");