1 // Copyright (C) 2007-2022 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 "MEDCouplingFieldInt64.hxx"
26 #include "MEDCouplingFieldFloat.hxx"
27 #include "MEDCouplingUMesh.hxx"
28 #include "MEDCouplingTimeDiscretization.hxx"
29 #include "MEDCouplingFieldDiscretization.hxx"
31 #include "MEDCouplingVoronoi.hxx"
32 #include "MEDCouplingNatureOfField.hxx"
33 #include "MEDCouplingMemArray.txx"
35 #include "InterpKernelAutoPtr.hxx"
36 #include "InterpKernelGaussCoords.hxx"
43 using namespace MEDCoupling;
45 template class MEDCoupling::MEDCouplingFieldT<double>;
48 * Creates a new MEDCouplingFieldDouble, of given spatial type and time discretization.
49 * For more info, see \ref MEDCouplingFirstSteps3.
50 * \param [in] type - the type of spatial discretization of the created field, one of
51 * (\ref MEDCoupling::ON_CELLS "ON_CELLS",
52 * \ref MEDCoupling::ON_NODES "ON_NODES",
53 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT",
54 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE",
55 * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR").
56 * \param [in] td - the type of time discretization of the created field, one of
57 * (\ref MEDCoupling::NO_TIME "NO_TIME",
58 * \ref MEDCoupling::ONE_TIME "ONE_TIME",
59 * \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME",
60 * \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
61 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
62 * caller is to delete this field using decrRef() as it is no more needed.
64 MEDCouplingFieldDouble* MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td)
66 return new MEDCouplingFieldDouble(type,td);
70 * Creates a new MEDCouplingFieldDouble, of a given time discretization and with a
71 * spatial type and supporting mesh copied from a given
72 * \ref MEDCouplingFieldTemplatesPage "field template".
73 * For more info, see \ref MEDCouplingFirstSteps3.
74 * \warning This method does not deeply copy neither the mesh nor the spatial
75 * discretization. Only a shallow copy (reference) is done for the mesh and the spatial
77 * \param [in] ft - the \ref MEDCouplingFieldTemplatesPage "field template" defining
78 * the spatial discretization and the supporting mesh.
79 * \param [in] td - the type of time discretization of the created field, one of
80 * (\ref MEDCoupling::NO_TIME "NO_TIME",
81 * \ref MEDCoupling::ONE_TIME "ONE_TIME",
82 * \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME",
83 * \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
84 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
85 * caller is to delete this field using decrRef() as it is no more needed.
87 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td)
89 return new MEDCouplingFieldDouble(ft,td);
93 * Sets a time \a unit of \a this field. For more info, see \ref MEDCouplingFirstSteps3.
94 * \param [in] unit \a unit (string) in which time is measured.
96 //void MEDCouplingFieldDouble::setTimeUnit(const std::string& unit)
99 * Returns a time unit of \a this field.
100 * \return a string describing units in which time is measured.
102 //std::string MEDCouplingFieldDouble::getTimeUnit() const
106 * This method if possible the time information (time unit, time iteration, time unit and time value) with its support
107 * that is to say its mesh.
109 * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is
112 void MEDCouplingFieldDouble::synchronizeTimeWithSupport()
114 timeDiscr()->synchronizeTimeWith(_mesh);
118 * Returns a new MEDCouplingFieldDouble which is a copy of \a this one. The data
119 * of \a this field is copied either deep or shallow depending on \a recDeepCpy
120 * parameter. But the underlying mesh is always shallow copied.
121 * Data that can be copied either deeply or shallow are:
122 * - \ref MEDCouplingTemporalDisc "temporal discretization" data that holds array(s)
124 * - \ref MEDCouplingSpatialDisc "a spatial discretization".
126 * \c clone(false) is rather dedicated for advanced users that want to limit the amount
127 * of memory. It allows the user to perform methods like operator+(), operator*()
128 * etc. with \a this and the returned field. If the user wants to duplicate deeply the
129 * underlying mesh he should call cloneWithMesh() method or deepCopy() instead.
130 * \warning The underlying \b mesh of the returned field is **always the same**
131 * (pointer) as \a this one **whatever the value** of \a recDeepCpy parameter.
132 * \param [in] recDeepCpy - if \c true, the copy of the underlying data arrays is
133 * deep, else all data arrays of \a this field are shared by the new field.
134 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The
135 * caller is to delete this field using decrRef() as it is no more needed.
136 * \sa cloneWithMesh()
138 MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
140 return new MEDCouplingFieldDouble(*this,recDeepCpy);
144 * Returns a new MEDCouplingFieldDouble which is a deep copy of \a this one **including
146 * The result of this method is exactly the same as that of \c cloneWithMesh(true).
147 * So the resulting field can not be used together with \a this one in the methods
148 * like operator+(), operator*() etc. To avoid deep copying the underlying mesh,
149 * the user can call clone().
150 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The
151 * caller is to delete this field using decrRef() as it is no more needed.
152 * \sa cloneWithMesh()
154 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCopy() const
156 return cloneWithMesh(true);
160 * Creates a new MEDCouplingFieldDouble of given
161 * \ref MEDCouplingTemporalDisc "temporal discretization". The result field either
162 * shares the data array(s) with \a this field, or holds a deep copy of it, depending on
163 * \a deepCopy parameter. But the underlying \b mesh is always **shallow copied**.
164 * \param [in] td - the type of time discretization of the created field, one of
165 * (\ref MEDCoupling::NO_TIME "NO_TIME",
166 * \ref MEDCoupling::ONE_TIME "ONE_TIME",
167 * \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME",
168 * \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
169 * \param [in] deepCpy - if \c true, the copy of the underlying data arrays is
170 * deep, else all data arrays of \a this field are shared by the new field.
171 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
172 * caller is to delete this field using decrRef() as it is no more needed.
174 * \if ENABLE_EXAMPLES
175 * \ref cpp_mcfielddouble_buildNewTimeReprFromThis "Here is a C++ example."<br>
176 * \ref py_mcfielddouble_buildNewTimeReprFromThis "Here is a Python example."
180 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const
182 MEDCouplingTimeDiscretization *tdo=timeDiscr()->buildNewTimeReprFromThis(td,deepCpy);
183 MCAuto<MEDCouplingFieldDiscretization> disc;
186 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),tdo,disc.retn()));
187 ret->setMesh(getMesh());
188 ret->setName(getName());
189 ret->setDescription(getDescription());
194 * This method converts a field on nodes (\a this) to a cell field (returned field). The conversion is a \b non \b conservative remapping !
195 * 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
196 * to each cell the average of values on nodes constituting this cell.
198 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
199 * 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.
200 * \throw If \a this spatial discretization is empty or not ON_NODES.
201 * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkConsistencyLight).
203 * \warning This method is a \b non \b conservative method of remapping from node spatial discretization to cell spatial discretization.
204 * If a conservative method of interpolation is required MEDCoupling::MEDCouplingRemapper class should be used instead with "P1P0" method.
206 MEDCouplingFieldDouble *MEDCouplingFieldDouble::nodeToCellDiscretization() const
208 checkConsistencyLight();
209 TypeOfField tf(getTypeOfField());
211 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::nodeToCellDiscretization : this field is expected to be on ON_NODES !");
212 MCAuto<MEDCouplingFieldDouble> ret(clone(false));
213 MCAuto<MEDCouplingFieldDiscretizationP0> nsp(new MEDCouplingFieldDiscretizationP0);
214 ret->setDiscretization(nsp);
215 const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkConsistencyLight call
216 mcIdType nbCells=ToIdType(m->getNumberOfCells());
217 std::vector<DataArrayDouble *> arrs(getArrays());
218 std::size_t sz(arrs.size());
219 std::vector< MCAuto<DataArrayDouble> > outArrsSafe(sz); std::vector<DataArrayDouble *> outArrs(sz);
220 for(std::size_t j=0;j<sz;j++)
222 std::size_t nbCompo(arrs[j]->getNumberOfComponents());
223 outArrsSafe[j]=DataArrayDouble::New(); outArrsSafe[j]->alloc(nbCells,nbCompo);
224 outArrsSafe[j]->copyStringInfoFrom(*arrs[j]);
225 outArrs[j]=outArrsSafe[j];
226 double *pt(outArrsSafe[j]->getPointer());
227 const double *srcPt(arrs[j]->begin());
228 for(mcIdType i=0;i<nbCells;i++,pt+=nbCompo)
230 std::vector<mcIdType> nodeIds;
231 m->getNodeIdsOfCell(i,nodeIds);
232 std::fill(pt,pt+nbCompo,0.);
233 std::size_t nbNodesInCell(nodeIds.size());
234 for(std::size_t k=0;k<nbNodesInCell;k++)
235 std::transform(srcPt+nodeIds[k]*nbCompo,srcPt+(nodeIds[k]+1)*nbCompo,pt,pt,std::plus<double>());
237 std::transform(pt,pt+nbCompo,pt,std::bind(std::multiplies<double>(),std::placeholders::_1,1./((double)nbNodesInCell)));
240 std::ostringstream oss; oss << "MEDCouplingFieldDouble::nodeToCellDiscretization : Cell id #" << i << " has been detected to have no nodes !";
241 throw INTERP_KERNEL::Exception(oss.str());
245 ret->setArrays(outArrs);
250 * This method converts a field on cell (\a this) to a node field (returned field). The conversion is a \b non \b conservative remapping !
251 * 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
252 * 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.).
254 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
255 * 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.
256 * \throw If \a this spatial discretization is empty or not ON_CELLS.
257 * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkConsistencyLight).
259 * \warning This method is a \b non \b conservative method of remapping from cell spatial discretization to node spatial discretization.
260 * If a conservative method of interpolation is required MEDCoupling::MEDCouplingRemapper class should be used instead with "P0P1" method.
262 MEDCouplingFieldDouble *MEDCouplingFieldDouble::cellToNodeDiscretization() const
264 checkConsistencyLight();
265 TypeOfField tf(getTypeOfField());
267 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::cellToNodeDiscretization : this field is expected to be on ON_CELLS !");
268 MCAuto<MEDCouplingFieldDouble> ret(clone(false));
269 MCAuto<MEDCouplingFieldDiscretizationP1> nsp(new MEDCouplingFieldDiscretizationP1);
270 ret->setDiscretization(nsp);
271 const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkConsistencyLight call
272 MCAuto<DataArrayIdType> rn(DataArrayIdType::New()),rni(DataArrayIdType::New());
273 m->getReverseNodalConnectivity(rn,rni);
274 MCAuto<DataArrayIdType> rni2(rni->deltaShiftIndex());
275 MCAuto<DataArrayDouble> rni3(rni2->convertToDblArr()); rni2=0;
276 std::vector<DataArrayDouble *> arrs(getArrays());
277 std::size_t sz(arrs.size());
278 std::vector< MCAuto<DataArrayDouble> > outArrsSafe(sz); std::vector<DataArrayDouble *> outArrs(sz);
279 for(std::size_t j=0;j<sz;j++)
281 MCAuto<DataArrayDouble> tmp(arrs[j]->selectByTupleIdSafe(rn->begin(),rn->end()));
282 outArrsSafe[j]=(tmp->accumulatePerChunck(rni->begin(),rni->end())); tmp=0;
283 outArrsSafe[j]->divideEqual(rni3);
284 outArrsSafe[j]->copyStringInfoFrom(*arrs[j]);
285 outArrs[j]=outArrsSafe[j];
287 ret->setArrays(outArrs);
292 * Returns a string describing \a this field. The string includes info on
295 * - \ref MEDCouplingSpatialDisc "spatial discretization",
296 * - \ref MEDCouplingTemporalDisc "time discretization",
299 * - contents of data arrays.
301 * \return std::string - the string describing \a this field.
303 std::string MEDCouplingFieldDouble::advancedRepr() const
305 std::ostringstream ret;
306 ret << "FieldDouble with name : \"" << getName() << "\"\n";
307 ret << "Description of field is : \"" << getDescription() << "\"\n";
309 { ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; }
311 { ret << "FieldDouble has no space discretization set !\n"; }
313 { ret << "FieldDouble time discretization is : " << timeDiscr()->getStringRepr() << "\n"; }
315 { ret << "FieldDouble has no time discretization set !\n"; }
317 ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
319 ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr();
321 ret << "Mesh support information : No mesh set !\n";
322 std::vector<DataArrayDouble *> arrays;
323 timeDiscr()->getArrays(arrays);
325 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++)
327 ret << "Array #" << arrayId << " :\n__________\n";
329 (*iter)->reprWithoutNameStream(ret);
331 ret << "Array empty !";
337 std::string MEDCouplingFieldDouble::writeVTK(const std::string& fileName, bool isBinary) const
339 std::vector<const MEDCouplingFieldDouble *> fs(1,this);
340 return MEDCouplingFieldDouble::WriteVTK(fileName,fs,isBinary);
344 * This method states if \a this and 'other' are compatibles each other before performing any treatment.
345 * This method is good for methods like : mergeFields.
346 * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields.
348 bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const
350 if(!MEDCouplingField::areCompatibleForMerge(other))
352 const MEDCouplingFieldDouble *otherC(dynamic_cast<const MEDCouplingFieldDouble *>(other));
355 if(!timeDiscr()->areCompatible(otherC->timeDiscr()))
361 * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible,
362 * except that \a this and other can have different number of components.
364 bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const
366 if(!MEDCouplingField::areStrictlyCompatible(other))
368 if(!timeDiscr()->areCompatibleForMeld(other->timeDiscr()))
374 * Permutes values of \a this field according to a given permutation array for node
375 * renumbering. The underlying mesh is deeply copied and its nodes are also permuted.
376 * The number of nodes can change, contrary to renumberCells().
377 * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
378 * to be equal to \a this->getMesh()->getNumberOfNodes().
379 * \param [in] eps - a precision used to compare field values at merged nodes. If
380 * the values differ more than \a eps, an exception is thrown.
381 * \throw If the mesh is not set.
382 * \throw If the spatial discretization of \a this field is NULL.
383 * \throw If \a check == \c true and \a old2NewBg contains equal ids.
384 * \throw If mesh nature does not allow renumbering (e.g. structured mesh).
385 * \throw If values at merged nodes differ more than \a eps.
387 * \if ENABLE_EXAMPLES
388 * \ref cpp_mcfielddouble_renumberNodes "Here is a C++ example".<br>
389 * \ref py_mcfielddouble_renumberNodes "Here is a Python example".
392 void MEDCouplingFieldDouble::renumberNodes(const mcIdType *old2NewBg, double eps)
394 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
396 throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !");
397 mcIdType nbOfNodes=meshC->getNumberOfNodes();
398 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
399 mcIdType newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1;
400 renumberNodesWithoutMesh(old2NewBg,newNbOfNodes,eps);
401 meshC2->renumberNodes(old2NewBg,newNbOfNodes);
406 * Permutes values of \a this field according to a given permutation array for nodes
407 * renumbering. The underlying mesh is \b not permuted.
408 * The number of nodes can change, contrary to renumberCells().
409 * A given epsilon specifies a threshold of error in case of two nodes are merged but
410 * the difference of values on these nodes are higher than \a eps.
411 * This method performs a part of job of renumberNodes(), excluding node renumbering
412 * in mesh. The reasonable use of this
413 * method is only for multi-field instances lying on the same mesh to avoid a
414 * systematic duplication and renumbering of _mesh attribute.
415 * \warning Use this method with a lot of care!
416 * \warning In case of an exception thrown, the contents of the data array can be
417 * partially modified until the exception occurs.
418 * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
419 * to be equal to \a this->getMesh()->getNumberOfNodes().
420 * \param [in] newNbOfNodes - a number of nodes in the mesh after renumbering.
421 * \param [in] eps - a precision used to compare field values at merged nodes. If
422 * the values differ more than \a eps, an exception is thrown.
423 * \throw If the mesh is not set.
424 * \throw If the spatial discretization of \a this field is NULL.
425 * \throw If values at merged nodes differ more than \a eps.
427 void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const mcIdType *old2NewBg, mcIdType newNbOfNodes, double eps)
430 throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !");
431 std::vector<DataArrayDouble *> arrays;
432 timeDiscr()->getArrays(arrays);
433 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
435 _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter);
439 * Returns all tuple ids of \a this scalar field that fit the range [\a vmin,
440 * \a vmax]. This method calls DataArrayDouble::findIdsInRange().
441 * \param [in] vmin - a lower boundary of the range. Tuples with values less than \a
442 * vmin are not included in the result array.
443 * \param [in] vmax - an upper boundary of the range. Tuples with values more than \a
444 * vmax are not included in the result array.
445 * \return DataArrayIdType * - a new instance of DataArrayIdType holding ids of selected
446 * tuples. The caller is to delete this array using decrRef() as it is no
448 * \throw If the data array is not set.
449 * \throw If \a this->getNumberOfComponents() != 1.
451 DataArrayIdType *MEDCouplingFieldDouble::findIdsInRange(double vmin, double vmax) const
454 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::findIdsInRange : no default array set !");
455 return getArray()->findIdsInRange(vmin,vmax);
459 typename Traits<U>::FieldType *ConvertToUField(const MEDCouplingFieldDouble *self)
461 MCAuto<MEDCouplingFieldTemplate> tmp(MEDCouplingFieldTemplate::New(*self));
463 double t0(self->getTime(t1,t2));
464 MCAuto<typename Traits<U>::FieldType > ret(Traits<U>::FieldType::New(*tmp,self->getTimeDiscretization()));
465 ret->setTime(t0,t1,t2);
468 MCAuto<typename Traits<U>::ArrayType> arr(self->getArray()->convertToOtherTypeOfArr<U>());
474 MEDCouplingFieldInt32 *MEDCouplingFieldDouble::convertToIntField() const
476 return ConvertToUField<int>(this);
478 MEDCouplingFieldInt64 *MEDCouplingFieldDouble::convertToInt64Field() const
480 return ConvertToUField<Int64>(this);
482 MEDCouplingFieldFloat *MEDCouplingFieldDouble::convertToFloatField() const
484 return ConvertToUField<float>(this);
487 MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(type,MEDCouplingTimeDiscretization::New(td))
492 * ** WARINING : This method do not deeply copy neither mesh nor spatial discretization. Only a shallow copy (reference) is done for mesh and spatial discretization ! **
494 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(ft,MEDCouplingTimeDiscretization::New(td),false)
498 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCpy):MEDCouplingFieldT<double>(other,deepCpy)
502 MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingFieldT<double>(type,n,td)
507 * Accumulate values of a given component of \a this field.
508 * \param [in] compId - the index of the component of interest.
509 * \return double - a sum value of *compId*-th component.
510 * \throw If the data array is not set.
511 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
514 double MEDCouplingFieldDouble::accumulate(int compId) const
517 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
518 return getArray()->accumulate(compId);
522 * Accumulates values of each component of \a this array.
523 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
524 * by the caller, that is filled by this method with sum value for each
526 * \throw If the data array is not set.
528 void MEDCouplingFieldDouble::accumulate(double *res) const
531 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
532 getArray()->accumulate(res);
536 * Returns the maximal value within \a this scalar field. Values of all arrays stored
537 * in \a this->_time_discr are checked.
538 * \return double - the maximal value among all values of \a this field.
539 * \throw If \a this->getNumberOfComponents() != 1
540 * \throw If the data array is not set.
541 * \throw If there is an empty data array in \a this field.
543 double MEDCouplingFieldDouble::getMaxValue() const
545 std::vector<DataArrayDouble *> arrays;
546 timeDiscr()->getArrays(arrays);
547 double ret(-std::numeric_limits<double>::max());
548 bool isExistingArr=false;
549 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
555 ret=std::max(ret,(*iter)->getMaxValue(loc));
559 throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !");
564 * Returns the maximal value and all its locations within \a this scalar field.
565 * Only the first of available data arrays is checked.
566 * \param [out] tupleIds - a new instance of DataArrayIdType containing indices of
567 * tuples holding the maximal value. The caller is to delete it using
568 * decrRef() as it is no more needed.
569 * \return double - the maximal value among all values of the first array of \a this filed.
570 * \throw If \a this->getNumberOfComponents() != 1.
571 * \throw If there is an empty data array in \a this field.
573 double MEDCouplingFieldDouble::getMaxValue2(DataArrayIdType*& tupleIds) const
575 std::vector<DataArrayDouble *> arrays;
576 timeDiscr()->getArrays(arrays);
577 double ret(-std::numeric_limits<double>::max());
578 bool isExistingArr=false;
580 MCAuto<DataArrayIdType> ret1;
581 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
586 DataArrayIdType *tmp;
587 ret=std::max(ret,(*iter)->getMaxValue2(tmp));
588 MCAuto<DataArrayIdType> tmpSafe(tmp);
589 if(!((const DataArrayIdType *)ret1))
594 throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !");
595 tupleIds=ret1.retn();
600 * Returns the minimal value within \a this scalar field. Values of all arrays stored
601 * in \a this->_time_discr are checked.
602 * \return double - the minimal value among all values of \a this field.
603 * \throw If \a this->getNumberOfComponents() != 1
604 * \throw If the data array is not set.
605 * \throw If there is an empty data array in \a this field.
607 double MEDCouplingFieldDouble::getMinValue() const
609 std::vector<DataArrayDouble *> arrays;
610 timeDiscr()->getArrays(arrays);
611 double ret(std::numeric_limits<double>::max());
612 bool isExistingArr=false;
613 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
619 ret=std::min(ret,(*iter)->getMinValue(loc));
623 throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !");
628 * Returns the minimal value and all its locations within \a this scalar field.
629 * Only the first of available data arrays is checked.
630 * \param [out] tupleIds - a new instance of DataArrayIdType containing indices of
631 * tuples holding the minimal value. The caller is to delete it using
632 * decrRef() as it is no more needed.
633 * \return double - the minimal value among all values of the first array of \a this filed.
634 * \throw If \a this->getNumberOfComponents() != 1.
635 * \throw If there is an empty data array in \a this field.
637 double MEDCouplingFieldDouble::getMinValue2(DataArrayIdType*& tupleIds) const
639 std::vector<DataArrayDouble *> arrays;
640 timeDiscr()->getArrays(arrays);
641 double ret(-std::numeric_limits<double>::max());
642 bool isExistingArr=false;
644 MCAuto<DataArrayIdType> ret1;
645 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
650 DataArrayIdType *tmp;
651 ret=std::max(ret,(*iter)->getMinValue2(tmp));
652 MCAuto<DataArrayIdType> tmpSafe(tmp);
653 if(!((const DataArrayIdType *)ret1))
658 throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !");
659 tupleIds=ret1.retn();
664 * Returns the average value of \a this scalar field.
665 * \return double - the average value over all values of the data array.
666 * \throw If \a this->getNumberOfComponents() != 1
667 * \throw If the data array is not set or it is empty.
669 double MEDCouplingFieldDouble::getAverageValue() const
672 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !");
673 return getArray()->getAverageValue();
677 * This method returns the euclidean norm of \a this field.
679 * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]}
681 * \throw If the data array is not set.
683 double MEDCouplingFieldDouble::norm2() const
686 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !");
687 return getArray()->norm2();
692 * Computes the weighted average of values of each component of \a this field, the weights being the
693 * values returned by buildMeasureField().
694 * \param [out] res - pointer to an array of result sum values, of size at least \a
695 * this->getNumberOfComponents(), that is to be allocated by the caller.
696 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by
697 * buildMeasureField(). It makes this method slower. If you are sure that all
698 * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs ==
699 * \c false to speed up the method.
700 * \throw If the mesh is not set.
701 * \throw If the data array is not set.
703 void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const
706 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
707 MCAuto<MEDCouplingFieldDouble> w=buildMeasureField(isWAbs);
708 double deno=w->getArray()->accumulate((std::size_t)0);
709 MCAuto<DataArrayDouble> arr=getArray()->deepCopy();
710 arr->multiplyEqual(w->getArray());
711 arr->accumulate(res);
712 std::size_t nCompo = getArray()->getNumberOfComponents();
713 std::transform(res,res+nCompo,res,std::bind(std::multiplies<double>(),std::placeholders::_1,1./deno));
717 * Computes the weighted average of values of a given component of \a this field, the weights being the
718 * values returned by buildMeasureField().
719 * \param [in] compId - an index of the component of interest.
720 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by
721 * buildMeasureField(). It makes this method slower. If you are sure that all
722 * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs ==
723 * \c false to speed up the method.
724 * \throw If the mesh is not set.
725 * \throw If the data array is not set.
726 * \throw If \a compId is not valid.
727 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
729 double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const
731 std::size_t nbComps=getArray()->getNumberOfComponents();
732 if(compId<0 || compId>=ToIdType(nbComps))
734 std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
735 throw INTERP_KERNEL::Exception(oss.str());
737 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
738 getWeightedAverageValue(res,isWAbs);
743 * Returns the \c normL1 of values of a given component of \a this field:
745 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
747 * \param [in] compId - an index of the component of interest.
748 * \throw If the mesh is not set.
749 * \throw If the spatial discretization of \a this field is NULL.
750 * \throw If \a compId is not valid.
751 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
753 double MEDCouplingFieldDouble::normL1(int compId) const
756 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1 !");
758 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
759 std::size_t nbComps=getArray()->getNumberOfComponents();
760 if(compId<0 || compId>=ToIdType(nbComps))
762 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
763 throw INTERP_KERNEL::Exception(oss.str());
765 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
766 _type->normL1(_mesh,getArray(),res);
771 * Returns the \c normL1 of values of each component of \a this field:
773 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
775 * \param [out] res - pointer to an array of result values, of size at least \a
776 * this->getNumberOfComponents(), that is to be allocated by the caller.
777 * \throw If the mesh is not set.
778 * \throw If the spatial discretization of \a this field is NULL.
780 void MEDCouplingFieldDouble::normL1(double *res) const
783 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
785 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
786 _type->normL1(_mesh,getArray(),res);
790 * Returns the \c normL2 of values of a given component of \a this field:
792 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
794 * \param [in] compId - an index of the component of interest.
795 * \throw If the mesh is not set.
796 * \throw If the spatial discretization of \a this field is NULL.
797 * \throw If \a compId is not valid.
798 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
800 double MEDCouplingFieldDouble::normL2(int compId) const
803 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
805 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
806 std::size_t nbComps=getArray()->getNumberOfComponents();
807 if(compId<0 || compId>=ToIdType(nbComps))
809 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
810 throw INTERP_KERNEL::Exception(oss.str());
812 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
813 _type->normL2(_mesh,getArray(),res);
818 * Returns the \c normL2 of values of each component of \a this field:
820 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
822 * \param [out] res - pointer to an array of result values, of size at least \a
823 * this->getNumberOfComponents(), that is to be allocated by the caller.
824 * \throw If the mesh is not set.
825 * \throw If the spatial discretization of \a this field is NULL.
827 void MEDCouplingFieldDouble::normL2(double *res) const
830 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
832 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
833 _type->normL2(_mesh,getArray(),res);
837 * Returns the \c infinite norm of values of a given component of \a this field:
839 * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
841 * \param [in] compId - an index of the component of interest.
842 * \throw If \a compId is not valid.
843 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
844 * \throw If the data array is not set.
846 double MEDCouplingFieldDouble::normMax(int compId) const
849 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
850 std::size_t nbComps=getArray()->getNumberOfComponents();
851 if(compId<0 || compId>=ToIdType(nbComps))
853 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normMax : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
854 throw INTERP_KERNEL::Exception(oss.str());
856 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
857 getArray()->normMaxPerComponent(res);
862 * Returns the \c infinite norm of values of each component of \a this field:
864 * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
866 * \param [out] res - pointer to an array of result values, of size at least \a
867 * this->getNumberOfComponents(), that is to be allocated by the caller.
868 * \throw If the data array is not set.
871 void MEDCouplingFieldDouble::normMax(double *res) const
874 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
875 getArray()->normMaxPerComponent(res);
879 * Computes a sum of values of a given component of \a this field multiplied by
880 * values returned by buildMeasureField().
881 * This method is useful to check the conservativity of interpolation method.
882 * \param [in] compId - an index of the component of interest.
883 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by
884 * buildMeasureField() that makes this method slower. If a user is sure that all
885 * cells of the underlying mesh have correct orientation, he can put \a isWAbs ==
886 * \c false that speeds up this method.
887 * \throw If the mesh is not set.
888 * \throw If the data array is not set.
889 * \throw If \a compId is not valid.
890 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
892 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const
895 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
897 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral !");
898 std::size_t nbComps=getArray()->getNumberOfComponents();
899 if(compId<0 || compId>=ToIdType(nbComps))
901 std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
902 throw INTERP_KERNEL::Exception(oss.str());
904 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
905 _type->integral(_mesh,getArray(),isWAbs,res);
910 * Computes a sum of values of each component of \a this field multiplied by
911 * values returned by buildMeasureField().
912 * This method is useful to check the conservativity of interpolation method.
913 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by
914 * buildMeasureField() that makes this method slower. If a user is sure that all
915 * cells of the underlying mesh have correct orientation, he can put \a isWAbs ==
916 * \c false that speeds up this method.
917 * \param [out] res - pointer to an array of result sum values, of size at least \a
918 * this->getNumberOfComponents(), that is to be allocated by the caller.
919 * \throw If the mesh is not set.
920 * \throw If the data array is not set.
921 * \throw If the spatial discretization of \a this field is NULL.
923 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const
926 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
928 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral2 !");
929 _type->integral(_mesh,getArray(),isWAbs,res);
933 * Returns a value at a given cell of a structured mesh. The cell is specified by its
935 * \param [in] i - a index of node coordinates array along X axis. The cell is
936 * located between the i-th and ( i + 1 )-th nodes along X axis.
937 * \param [in] j - a index of node coordinates array along Y axis. The cell is
938 * located between the j-th and ( j + 1 )-th nodes along Y axis.
939 * \param [in] k - a index of node coordinates array along Z axis. The cell is
940 * located between the k-th and ( k + 1 )-th nodes along Z axis.
941 * \param [out] res - pointer to an array returning a feild value, of size at least
942 * \a this->getNumberOfComponents(), that is to be allocated by the caller.
943 * \throw If the spatial discretization of \a this field is NULL.
944 * \throw If the mesh is not set.
945 * \throw If the mesh is not a structured one.
947 * \if ENABLE_EXAMPLES
948 * \ref cpp_mcfielddouble_getValueOnPos "Here is a C++ example".<br>
949 * \ref py_mcfielddouble_getValueOnPos "Here is a Python example".
952 void MEDCouplingFieldDouble::getValueOnPos(mcIdType i, mcIdType j, mcIdType k, double *res) const
954 const DataArrayDouble *arr=timeDiscr()->getArray();
956 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
958 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
959 _type->getValueOnPos(arr,_mesh,i,j,k,res);
963 * Returns a value of \a this at a given point using spatial discretization.
964 * \param [in] spaceLoc - the point of interest.
965 * \param [out] res - pointer to an array returning a feild value, of size at least
966 * \a this->getNumberOfComponents(), that is to be allocated by the caller.
967 * \throw If the spatial discretization of \a this field is NULL.
968 * \throw If the mesh is not set.
969 * \throw If \a spaceLoc is out of the spatial discretization.
971 * \if ENABLE_EXAMPLES
972 * \ref cpp_mcfielddouble_getValueOn "Here is a C++ example".<br>
973 * \ref py_mcfielddouble_getValueOn "Here is a Python example".
976 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const
978 const DataArrayDouble *arr=timeDiscr()->getArray();
980 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
982 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
983 _type->getValueOn(arr,_mesh,spaceLoc,res);
987 * Returns values of \a this at given points using spatial discretization.
988 * \param [in] spaceLoc - coordinates of points of interest in full-interlace
989 * mode. This array is to be of size ( \a nbOfPoints * \a this->getNumberOfComponents() ).
990 * \param [in] nbOfPoints - number of points of interest.
991 * \return DataArrayDouble * - a new instance of DataArrayDouble holding field
992 * values relating to the input points. This array is of size \a nbOfPoints
993 * tuples per \a this->getNumberOfComponents() components. The caller is to
994 * delete this array using decrRef() as it is no more needed.
995 * \throw If the spatial discretization of \a this field is NULL.
996 * \throw If the mesh is not set.
997 * \throw If any point in \a spaceLoc is out of the spatial discretization.
999 * \if ENABLE_EXAMPLES
1000 * \ref cpp_mcfielddouble_getValueOnMulti "Here is a C++ example".<br>
1001 * \ref py_mcfielddouble_getValueOnMulti "Here is a Python example".
1004 DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, mcIdType nbOfPoints) const
1006 const DataArrayDouble *arr=timeDiscr()->getArray();
1008 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
1010 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnMulti !");
1011 return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
1015 * Returns a value of \a this field at a given point at a given time using spatial discretization.
1016 * If the time is not covered by \a this->_time_discr, an exception is thrown.
1017 * \param [in] spaceLoc - the point of interest.
1018 * \param [in] time - the time of interest.
1019 * \param [out] res - pointer to an array returning a feild value, of size at least
1020 * \a this->getNumberOfComponents(), that is to be allocated by the caller.
1021 * \throw If the spatial discretization of \a this field is NULL.
1022 * \throw If the mesh is not set.
1023 * \throw If \a spaceLoc is out of the spatial discretization.
1024 * \throw If \a time is not covered by \a this->_time_discr.
1026 * \if ENABLE_EXAMPLES
1027 * \ref cpp_mcfielddouble_getValueOn_time "Here is a C++ example".<br>
1028 * \ref py_mcfielddouble_getValueOn_time "Here is a Python example".
1031 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const
1033 std::vector< const DataArrayDouble *> arrs=timeDiscr()->getArraysForTime(time);
1035 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
1037 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOn !");
1038 std::vector<double> res2;
1039 for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
1041 std::size_t sz=res2.size();
1042 res2.resize(sz+(*iter)->getNumberOfComponents());
1043 _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]);
1045 timeDiscr()->getValueForTime(time,res2,res);
1049 * Apply a linear function to a given component of \a this field, so that
1050 * a component value <em>(x)</em> becomes \f$ a * x + b \f$.
1051 * \param [in] a - the first coefficient of the function.
1052 * \param [in] b - the second coefficient of the function.
1053 * \param [in] compoId - the index of component to modify.
1054 * \throw If the data array(s) is(are) not set.
1056 void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
1058 timeDiscr()->applyLin(a,b,compoId);
1062 * Apply a linear function to all components of \a this field, so that
1063 * values <em>(x)</em> becomes \f$ a * x + b \f$.
1064 * \param [in] a - the first coefficient of the function.
1065 * \param [in] b - the second coefficient of the function.
1066 * \throw If the data array(s) is(are) not set.
1068 void MEDCouplingFieldDouble::applyLin(double a, double b)
1070 timeDiscr()->applyLin(a,b);
1074 * This method sets \a this to a uniform scalar field with one component.
1075 * All tuples will have the same value 'value'.
1076 * An exception is thrown if no underlying mesh is defined.
1078 MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value)
1081 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
1083 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform operator = !");
1084 mcIdType nbOfTuple=_type->getNumberOfTuples(_mesh);
1085 timeDiscr()->setOrCreateUniformValueOnAllComponents(nbOfTuple,value);
1090 * Creates data array(s) of \a this field by using a C function for value generation.
1091 * \param [in] nbOfComp - the number of components for \a this field to have.
1092 * \param [in] func - the function used to compute values of \a this field.
1093 * This function is to compute a field value basing on coordinates of value
1095 * \throw If the mesh is not set.
1096 * \throw If \a func returns \c false.
1097 * \throw If the spatial discretization of \a this field is NULL.
1099 * \if ENABLE_EXAMPLES
1100 * \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example".
1103 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func)
1106 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1108 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
1109 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1110 timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
1114 * Creates data array(s) of \a this field by using a function for value generation.<br>
1115 * The function is applied to coordinates of value location points. For example, if
1116 * \a this field is on cells, the function is applied to cell barycenters.
1117 * For more info on supported expressions that can be used in the function, see \ref
1118 * MEDCouplingArrayApplyFuncExpr. <br>
1119 * The function can include arbitrary named variables
1120 * (e.g. "x","y" or "va44") to refer to components of point coordinates. Names of
1121 * variables are sorted in \b alphabetical \b order to associate a variable name with a
1122 * component. For example, in the expression "2*x+z", "x" stands for the component #0
1123 * and "z" stands for the component #1 (\b not #2)!<br>
1124 * In a general case, a value resulting from the function evaluation is assigned to all
1125 * components of a field value. But there is a possibility to have its own expression for
1126 * each component within one function. For this purpose, there are predefined variable
1127 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1128 * the component #0 etc). A factor of such a variable is added to the
1129 * corresponding component only.<br>
1130 * For example, \a nbOfComp == 4, coordinates of a 3D point are (1.,3.,7.), then
1131 * - "2*x + z" produces (5.,5.,5.,5.)
1132 * - "2*x + 0*y + z" produces (9.,9.,9.,9.)
1133 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1134 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1136 * \param [in] nbOfComp - the number of components for \a this field to have.
1137 * \param [in] func - the function used to compute values of \a this field.
1138 * This function is used to compute a field value basing on coordinates of value
1139 * location point. For example, if \a this field is on cells, the function
1140 * is applied to cell barycenters.
1141 * \throw If the mesh is not set.
1142 * \throw If the spatial discretization of \a this field is NULL.
1143 * \throw If computing \a func fails.
1145 * \if ENABLE_EXAMPLES
1146 * \ref cpp_mcfielddouble_fillFromAnalytic "Here is a C++ example".<br>
1147 * \ref py_mcfielddouble_fillFromAnalytic "Here is a Python example".
1150 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func)
1153 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1155 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
1156 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1157 timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
1161 * Creates data array(s) of \a this field by using a function for value generation.<br>
1162 * The function is applied to coordinates of value location points. For example, if
1163 * \a this field is on cells, the function is applied to cell barycenters.<br>
1164 * This method differs from
1165 * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()"
1166 * by the way how variable
1167 * names, used in the function, are associated with components of coordinates of field
1168 * location points; here, a variable name corresponding to a component is retrieved from
1169 * a corresponding node coordinates array (where it is set via
1170 * DataArrayDouble::setInfoOnComponent()).<br>
1171 * For more info on supported expressions that can be used in the function, see \ref
1172 * MEDCouplingArrayApplyFuncExpr. <br>
1173 * In a general case, a value resulting from the function evaluation is assigned to all
1174 * components of a field value. But there is a possibility to have its own expression for
1175 * each component within one function. For this purpose, there are predefined variable
1176 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1177 * the component #0 etc). A factor of such a variable is added to the
1178 * corresponding component only.<br>
1179 * For example, \a nbOfComp == 4, names of spatial components are "x", "y" and "z",
1180 * coordinates of a 3D point are (1.,3.,7.), then
1181 * - "2*x + z" produces (9.,9.,9.,9.)
1182 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1183 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1185 * \param [in] nbOfComp - the number of components for \a this field to have.
1186 * \param [in] func - the function used to compute values of \a this field.
1187 * This function is used to compute a field value basing on coordinates of value
1188 * location point. For example, if \a this field is on cells, the function
1189 * is applied to cell barycenters.
1190 * \throw If the mesh is not set.
1191 * \throw If the spatial discretization of \a this field is NULL.
1192 * \throw If computing \a func fails.
1194 * \if ENABLE_EXAMPLES
1195 * \ref cpp_mcfielddouble_fillFromAnalytic2 "Here is a C++ example".<br>
1196 * \ref py_mcfielddouble_fillFromAnalytic2 "Here is a Python example".
1199 void MEDCouplingFieldDouble::fillFromAnalyticCompo(int nbOfComp, const std::string& func)
1202 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
1204 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticCompo !");
1205 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1206 timeDiscr()->fillFromAnalyticCompo(loc,nbOfComp,func);
1210 * Creates data array(s) of \a this field by using a function for value generation.<br>
1211 * The function is applied to coordinates of value location points. For example, if
1212 * \a this field is on cells, the function is applied to cell barycenters.<br>
1213 * This method differs from
1214 * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()"
1215 * by the way how variable
1216 * names, used in the function, are associated with components of coordinates of field
1217 * location points; here, a component index of a variable is defined by a
1218 * rank of the variable within the input array \a varsOrder.<br>
1219 * For more info on supported expressions that can be used in the function, see \ref
1220 * MEDCouplingArrayApplyFuncExpr.
1221 * In a general case, a value resulting from the function evaluation is assigned to all
1222 * components of a field value. But there is a possibility to have its own expression for
1223 * each component within one function. For this purpose, there are predefined variable
1224 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1225 * the component #0 etc). A factor of such a variable is added to the
1226 * corresponding component only.<br>
1227 * For example, \a nbOfComp == 4, names of
1228 * spatial components are given in \a varsOrder: ["x", "y","z"], coordinates of a
1229 * 3D point are (1.,3.,7.), then
1230 * - "2*x + z" produces (9.,9.,9.,9.)
1231 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1232 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1234 * \param [in] nbOfComp - the number of components for \a this field to have.
1235 * \param [in] func - the function used to compute values of \a this field.
1236 * This function is used to compute a field value basing on coordinates of value
1237 * location point. For example, if \a this field is on cells, the function
1238 * is applied to cell barycenters.
1239 * \throw If the mesh is not set.
1240 * \throw If the spatial discretization of \a this field is NULL.
1241 * \throw If computing \a func fails.
1243 * \if ENABLE_EXAMPLES
1244 * \ref cpp_mcfielddouble_fillFromAnalytic3 "Here is a C++ example".<br>
1245 * \ref py_mcfielddouble_fillFromAnalytic3 "Here is a Python example".
1248 void MEDCouplingFieldDouble::fillFromAnalyticNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1251 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
1253 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticNamedCompo !");
1254 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1255 timeDiscr()->fillFromAnalyticNamedCompo(loc,nbOfComp,varsOrder,func);
1259 * Modifies values of \a this field by applying a C function to each tuple of all
1261 * \param [in] nbOfComp - the number of components for \a this field to have.
1262 * \param [in] func - the function used to compute values of \a this field.
1263 * This function is to compute a field value basing on a current field value.
1264 * \throw If \a func returns \c false.
1266 * \if ENABLE_EXAMPLES
1267 * \ref cpp_mcfielddouble_applyFunc_c_func "Here is a C++ example".
1270 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
1272 timeDiscr()->applyFunc(nbOfComp,func);
1276 * Fill \a this field with a given value.<br>
1277 * This method is a specialization of other overloaded methods. When \a nbOfComp == 1
1278 * this method is equivalent to MEDCoupling::MEDCouplingFieldDouble::operator=().
1279 * \param [in] nbOfComp - the number of components for \a this field to have.
1280 * \param [in] val - the value to assign to every atomic value of \a this field.
1281 * \throw If the spatial discretization of \a this field is NULL.
1282 * \throw If the mesh is not set.
1284 * \if ENABLE_EXAMPLES
1285 * \ref cpp_mcfielddouble_applyFunc_val "Here is a C++ example".<br>
1286 * \ref py_mcfielddouble_applyFunc_val "Here is a Python example".
1289 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
1292 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
1294 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform applyFunc !");
1295 mcIdType nbOfTuple=_type->getNumberOfTuples(_mesh);
1296 timeDiscr()->setUniformValue(nbOfTuple,nbOfComp,val);
1300 * Modifies values of \a this field by applying a function to each tuple of all
1302 * For more info on supported expressions that can be used in the function, see \ref
1303 * MEDCouplingArrayApplyFuncExpr. <br>
1304 * The function can include arbitrary named variables
1305 * (e.g. "x","y" or "va44") to refer to components of a field value. Names of
1306 * variables are sorted in \b alphabetical \b order to associate a variable name with a
1307 * component. For example, in the expression "2*x+z", "x" stands for the component #0
1308 * and "z" stands for the component #1 (\b not #2)!<br>
1309 * In a general case, a value resulting from the function evaluation is assigned to all
1310 * components of a field value. But there is a possibility to have its own expression for
1311 * each component within one function. For this purpose, there are predefined variable
1312 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1313 * the component #0 etc). A factor of such a variable is added to the
1314 * corresponding component only.<br>
1315 * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then
1316 * - "2*x + z" produces (5.,5.,5.,5.)
1317 * - "2*x + 0*y + z" produces (9.,9.,9.,9.)
1318 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1319 * - "2*y*IVec + z*KVec + x" produces (7.,1.,8.,1.)
1321 * \param [in] nbOfComp - the number of components for \a this field to have.
1322 * \param [in] func - the function used to compute values of \a this field.
1323 * This function is to compute a field value basing on a current field value.
1324 * \throw If computing \a func fails.
1326 * \if ENABLE_EXAMPLES
1327 * \ref cpp_mcfielddouble_applyFunc "Here is a C++ example".<br>
1328 * \ref py_mcfielddouble_applyFunc "Here is a Python example".
1331 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func)
1333 timeDiscr()->applyFunc(nbOfComp,func);
1338 * Modifies values of \a this field by applying a function to each tuple of all
1340 * For more info on supported expressions that can be used in the function, see \ref
1341 * MEDCouplingArrayApplyFuncExpr. <br>
1342 * This method differs from
1343 * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()"
1344 * by the way how variable
1345 * names, used in the function, are associated with components of field values;
1346 * here, a variable name corresponding to a component is retrieved from
1347 * component information of an array (where it is set via
1348 * DataArrayDouble::setInfoOnComponent()).<br>
1349 * In a general case, a value resulting from the function evaluation is assigned to all
1350 * components of a field value. But there is a possibility to have its own expression for
1351 * each component within one function. For this purpose, there are predefined variable
1352 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1353 * the component #0 etc). A factor of such a variable is added to the
1354 * corresponding component only.<br>
1355 * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then
1356 * - "2*x + z" produces (5.,5.,5.,5.)
1357 * - "2*x + 0*y + z" produces (9.,9.,9.,9.)
1358 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1359 * - "2*y*IVec + z*KVec + x" produces (7.,1.,8.,1.)
1361 * \param [in] nbOfComp - the number of components for \a this field to have.
1362 * \param [in] func - the function used to compute values of \a this field.
1363 * This function is to compute a new field value basing on a current field value.
1364 * \throw If computing \a func fails.
1366 * \if ENABLE_EXAMPLES
1367 * \ref cpp_mcfielddouble_applyFunc2 "Here is a C++ example".<br>
1368 * \ref py_mcfielddouble_applyFunc2 "Here is a Python example".
1371 void MEDCouplingFieldDouble::applyFuncCompo(int nbOfComp, const std::string& func)
1373 timeDiscr()->applyFuncCompo(nbOfComp,func);
1377 * Modifies values of \a this field by applying a function to each tuple of all
1379 * This method differs from
1380 * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()"
1381 * by the way how variable
1382 * names, used in the function, are associated with components of field values;
1383 * here, a component index of a variable is defined by a
1384 * rank of the variable within the input array \a varsOrder.<br>
1385 * For more info on supported expressions that can be used in the function, see \ref
1386 * MEDCouplingArrayApplyFuncExpr.
1387 * In a general case, a value resulting from the function evaluation is assigned to all
1388 * components of a field value. But there is a possibility to have its own expression for
1389 * each component within one function. For this purpose, there are predefined variable
1390 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1391 * the component #0 etc). A factor of such a variable is added to the
1392 * corresponding component only.<br>
1393 * For example, \a nbOfComp == 4, names of
1394 * components are given in \a varsOrder: ["x", "y","z"], components of a
1395 * 3D vector are (1.,3.,7.), then
1396 * - "2*x + z" produces (9.,9.,9.,9.)
1397 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1398 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1400 * \param [in] nbOfComp - the number of components for \a this field to have.
1401 * \param [in] func - the function used to compute values of \a this field.
1402 * This function is to compute a new field value basing on a current field value.
1403 * \throw If computing \a func fails.
1405 * \if ENABLE_EXAMPLES
1406 * \ref cpp_mcfielddouble_applyFunc3 "Here is a C++ example".<br>
1407 * \ref py_mcfielddouble_applyFunc3 "Here is a Python example".
1410 void MEDCouplingFieldDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1412 timeDiscr()->applyFuncNamedCompo(nbOfComp,varsOrder,func);
1416 * Modifies values of \a this field by applying a function to each atomic value of all
1417 * data arrays. The function computes a new single value basing on an old single value.
1418 * For more info on supported expressions that can be used in the function, see \ref
1419 * MEDCouplingArrayApplyFuncExpr. <br>
1420 * The function can include **only one** arbitrary named variable
1421 * (e.g. "x","y" or "va44") to refer to a field atomic value. <br>
1422 * In a general case, a value resulting from the function evaluation is assigned to
1423 * a single field value. But there is a possibility to have its own expression for
1424 * each component within one function. For this purpose, there are predefined variable
1425 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1426 * the component #0 etc). A factor of such a variable is added to the
1427 * corresponding component only.<br>
1428 * For example, components of a field value are (1.,3.,7.), then
1429 * - "2*x - 1" produces (1.,5.,13.)
1430 * - "2*x*IVec + (x+3)*KVec" produces (2.,0.,10.)
1431 * - "2*x*IVec + (x+3)*KVec + 1" produces (3.,1.,11.)
1433 * \param [in] func - the function used to compute values of \a this field.
1434 * This function is to compute a field value basing on a current field value.
1435 * \throw If computing \a func fails.
1437 * \if ENABLE_EXAMPLES
1438 * \ref cpp_mcfielddouble_applyFunc_same_nb_comp "Here is a C++ example".<br>
1439 * \ref py_mcfielddouble_applyFunc_same_nb_comp "Here is a Python example".
1442 void MEDCouplingFieldDouble::applyFunc(const std::string& func)
1444 timeDiscr()->applyFunc(func);
1448 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1449 * The field will contain exactly the same number of components after the call.
1450 * Use is not warranted for the moment !
1452 void MEDCouplingFieldDouble::applyFuncFast32(const std::string& func)
1454 timeDiscr()->applyFuncFast32(func);
1458 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1459 * The field will contain exactly the same number of components after the call.
1460 * Use is not warranted for the moment !
1462 void MEDCouplingFieldDouble::applyFuncFast64(const std::string& func)
1464 timeDiscr()->applyFuncFast64(func);
1468 * Returns number of components in the data array. For more info on the data arrays,
1470 * \return int - the number of components in the data array.
1471 * \throw If the data array is not set.
1473 std::size_t MEDCouplingFieldDouble::getNumberOfComponents() const
1476 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
1477 return getArray()->getNumberOfComponents();
1481 * Use MEDCouplingField::getNumberOfTuplesExpected instead of this method. This method will be removed soon, because it is
1482 * confusing compared to getNumberOfComponents() and getNumberOfValues() behaviour.
1484 * Returns number of tuples in \a this field, that depends on
1485 * - the number of entities in the underlying mesh
1486 * - \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field (e.g. number
1487 * of Gauss points if \a this->getTypeOfField() ==
1488 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT").
1490 * The returned value does \b not \b depend on the number of tuples in the data array
1491 * (which has to be equal to the returned value), \b contrary to
1492 * getNumberOfComponents() and getNumberOfValues() that retrieve information from the
1493 * data array (Sorry, it is confusing !).
1494 * So \b this \b method \b behaves \b exactly \b as MEDCouplingField::getNumberOfTuplesExpected \b method.
1496 * \warning No checkConsistencyLight() is done here.
1497 * For more info on the data arrays, see \ref arrays.
1498 * \return int - the number of tuples.
1499 * \throw If the mesh is not set.
1500 * \throw If the spatial discretization of \a this field is NULL.
1501 * \throw If the spatial discretization is not fully defined.
1502 * \sa MEDCouplingField::getNumberOfTuplesExpected
1504 mcIdType MEDCouplingFieldDouble::getNumberOfTuples() const
1507 throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
1509 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getNumberOfTuples !");
1510 return _type->getNumberOfTuples(_mesh);
1514 * Returns number of atomic double values in the data array of \a this field.
1515 * For more info on the data arrays, see \ref arrays.
1516 * \return int - (number of tuples) * (number of components) of the
1518 * \throw If the data array is not set.
1520 mcIdType MEDCouplingFieldDouble::getNumberOfValues() const
1523 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
1524 return getArray()->getNbOfElems();
1528 * Sets own modification time by the most recently modified element of data (the mesh,
1529 * the data array etc). For more info, see \ref MEDCouplingTimeLabelPage.
1531 void MEDCouplingFieldDouble::updateTime() const
1533 MEDCouplingField::updateTime();
1534 updateTimeWith(*timeDiscr());
1537 std::size_t MEDCouplingFieldDouble::getHeapMemorySizeWithoutChildren() const
1539 return MEDCouplingField::getHeapMemorySizeWithoutChildren();
1542 std::vector<const BigMemoryObject *> MEDCouplingFieldDouble::getDirectChildrenWithNull() const
1544 std::vector<const BigMemoryObject *> ret(MEDCouplingField::getDirectChildrenWithNull());
1547 std::vector<const BigMemoryObject *> ret2(timeDiscr()->getDirectChildrenWithNull());
1548 ret.insert(ret.end(),ret2.begin(),ret2.end());
1554 * Returns a value of \a this field of type either
1555 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or
1556 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE".
1557 * \param [in] cellId - an id of cell of interest.
1558 * \param [in] nodeIdInCell - a node index within the cell.
1559 * \param [in] compoId - an index of component.
1560 * \return double - the field value corresponding to the specified parameters.
1561 * \throw If the data array is not set.
1562 * \throw If the mesh is not set.
1563 * \throw If the spatial discretization of \a this field is NULL.
1564 * \throw If \a this field if of type other than
1565 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or
1566 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE".
1568 double MEDCouplingFieldDouble::getIJK(mcIdType cellId, int nodeIdInCell, int compoId) const
1571 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getIJK !");
1572 return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
1576 * Sets the data array.
1577 * \param [in] array - the data array holding values of \a this field. It's size
1578 * should correspond to the mesh and
1579 * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1580 * (see getNumberOfTuples()), but this size is not checked here.
1582 //void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
1585 * Sets the data array holding values corresponding to an end of a time interval
1586 * for which \a this field is defined.
1587 * \param [in] array - the data array holding values of \a this field. It's size
1588 * should correspond to the mesh and
1589 * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1590 * (see getNumberOfTuples()), but this size is not checked here.
1592 //void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
1595 * Sets all data arrays needed to define the field values.
1596 * \param [in] arrs - a vector of DataArrayDouble's holding values of \a this
1597 * field. Size of each array should correspond to the mesh and
1598 * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1599 * (see getNumberOfTuples()), but this size is not checked here.
1600 * \throw If number of arrays in \a arrs does not correspond to type of
1601 * \ref MEDCouplingTemporalDisc "temporal discretization" of \a this field.
1603 //void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs)
1606 * Tries to set an \a other mesh as the support of \a this field. An attempt fails, if
1607 * a current and the \a other meshes are different with use of specified equality
1608 * criteria, and then an exception is thrown.
1609 * \param [in] other - the mesh to use as the field support if this mesh can be
1610 * considered equal to the current mesh.
1611 * \param [in] levOfCheck - defines equality criteria used for mesh comparison. For
1612 * it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which
1613 * is used for mesh comparison.
1614 * \param [in] precOnMesh - a precision used to compare nodes of the two meshes.
1615 * It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith().
1616 * \param [in] eps - a precision used at node renumbering (if needed) to compare field
1617 * values at merged nodes. If the values differ more than \a eps, an
1618 * exception is thrown.
1619 * \throw If the mesh is not set.
1620 * \throw If \a other == NULL.
1621 * \throw If any of the meshes is not well defined.
1622 * \throw If the two meshes do not match.
1623 * \throw If field values at merged nodes (if any) differ more than \a eps.
1625 * \if ENABLE_EXAMPLES
1626 * \ref cpp_mcfielddouble_changeUnderlyingMesh "Here is a C++ example".<br>
1627 * \ref py_mcfielddouble_changeUnderlyingMesh "Here is a Python example".
1630 void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps)
1632 if(_mesh==0 || other==0)
1633 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
1634 DataArrayIdType *cellCor=0,*nodeCor=0;
1635 other->checkGeoEquivalWith(_mesh,levOfCheck,precOnMesh,cellCor,nodeCor);
1636 MCAuto<DataArrayIdType> cellCor2(cellCor),nodeCor2(nodeCor);
1638 renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
1640 renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps);
1645 * Subtracts another field from \a this one in case when the two fields have different
1646 * supporting meshes. The subtraction is performed provided that the tho meshes can be
1647 * considered equal with use of specified equality criteria, else an exception is thrown.
1648 * If the meshes match, the mesh of \a f is set to \a this field (\a this is permuted if
1649 * necessary) and field values are subtracted. No interpolation is done here, only an
1650 * analysis of two underlying mesh is done to see if the meshes are geometrically
1652 * The job of this method consists in calling
1653 * \a this->changeUnderlyingMesh() with \a f->getMesh() as the first parameter, and then
1654 * \a this -= \a f.<br>
1655 * This method requires that \a f and \a this are coherent (checkConsistencyLight()) and that \a f
1656 * and \a this are coherent for a merge.<br>
1657 * "DM" in the method name stands for "different meshes".
1658 * \param [in] f - the field to subtract from this.
1659 * \param [in] levOfCheck - defines equality criteria used for mesh comparison. For
1660 * it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which
1661 * is used for mesh comparison.
1662 * \param [in] precOnMesh - a precision used to compare nodes of the two meshes.
1663 * It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith().
1664 * \param [in] eps - a precision used at node renumbering (if needed) to compare field
1665 * values at merged nodes. If the values differ more than \a eps, an
1666 * exception is thrown.
1667 * \throw If \a f == NULL.
1668 * \throw If any of the meshes is not set or is not well defined.
1669 * \throw If the two meshes do not match.
1670 * \throw If the two fields are not coherent for merge.
1671 * \throw If field values at merged nodes (if any) differ more than \a eps.
1673 * \if ENABLE_EXAMPLES
1674 * \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".<br>
1675 * \ref py_mcfielddouble_substractInPlaceDM "Here is a Python example".
1677 * \sa changeUnderlyingMesh().
1679 void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps)
1681 checkConsistencyLight();
1683 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : input field is NULL !");
1684 f->checkConsistencyLight();
1685 if(!areCompatibleForMerge(f))
1686 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : Fields are not compatible ; unable to apply mergeFields on them !");
1687 changeUnderlyingMesh(f->getMesh(),levOfCheck,precOnMesh,eps);
1692 * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the
1693 * underlying mesh is replaced by a new mesh instance where the coincident nodes are merged.
1694 * \param [in] eps - a precision used to compare nodes of the two meshes.
1695 * \param [in] epsOnVals - a precision used to compare field
1696 * values at merged nodes. If the values differ more than \a epsOnVals, an
1697 * exception is thrown.
1698 * \return bool - \c true if some nodes have been merged and hence \a this field lies
1700 * \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1701 * \throw If the mesh is not well defined.
1702 * \throw If the spatial discretization of \a this field is NULL.
1703 * \throw If the data array is not set.
1704 * \throw If field values at merged nodes (if any) differ more than \a epsOnVals.
1706 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals)
1708 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1710 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1712 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes !");
1713 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1716 MCAuto<DataArrayIdType> arr=meshC2->mergeNodes(eps,ret,ret2);
1717 if(!ret)//no nodes have been merged.
1719 std::vector<DataArrayDouble *> arrays;
1720 timeDiscr()->getArrays(arrays);
1721 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1723 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1729 * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the
1730 * underlying mesh is replaced by a new mesh instance where the coincident nodes are
1732 * In contrast to mergeNodes(), location of merged nodes is changed to be at their barycenter.
1733 * \param [in] eps - a precision used to compare nodes of the two meshes.
1734 * \param [in] epsOnVals - a precision used to compare field
1735 * values at merged nodes. If the values differ more than \a epsOnVals, an
1736 * exception is thrown.
1737 * \return bool - \c true if some nodes have been merged and hence \a this field lies
1739 * \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1740 * \throw If the mesh is not well defined.
1741 * \throw If the spatial discretization of \a this field is NULL.
1742 * \throw If the data array is not set.
1743 * \throw If field values at merged nodes (if any) differ more than \a epsOnVals.
1745 bool MEDCouplingFieldDouble::mergeNodesCenter(double eps, double epsOnVals)
1747 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1749 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1751 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodesCenter !");
1752 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1755 MCAuto<DataArrayIdType> arr=meshC2->mergeNodesCenter(eps,ret,ret2);
1756 if(!ret)//no nodes have been merged.
1758 std::vector<DataArrayDouble *> arrays;
1759 timeDiscr()->getArrays(arrays);
1760 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1762 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1768 * Removes from the underlying mesh nodes not used in any cell. If some nodes are
1769 * removed, the underlying mesh is replaced by a new mesh instance where the unused
1770 * nodes are removed.<br>
1771 * \param [in] epsOnVals - a precision used to compare field
1772 * values at merged nodes. If the values differ more than \a epsOnVals, an
1773 * exception is thrown.
1774 * \return bool - \c true if some nodes have been removed and hence \a this field lies
1776 * \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1777 * \throw If the mesh is not well defined.
1778 * \throw If the spatial discretization of \a this field is NULL.
1779 * \throw If the data array is not set.
1780 * \throw If field values at merged nodes (if any) differ more than \a epsOnVals.
1782 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals)
1784 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1786 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1788 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipCoords !");
1789 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
1790 mcIdType oldNbOfNodes=meshC2->getNumberOfNodes();
1791 MCAuto<DataArrayIdType> arr=meshC2->zipCoordsTraducer();
1792 if(meshC2->getNumberOfNodes()!=oldNbOfNodes)
1794 std::vector<DataArrayDouble *> arrays;
1795 timeDiscr()->getArrays(arrays);
1796 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1798 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1806 * Removes duplicates of cells from the understanding mesh. If some cells are
1807 * removed, the underlying mesh is replaced by a new mesh instance where the cells
1808 * duplicates are removed.<br>
1809 * \param [in] compType - specifies a cell comparison technique. Meaning of its
1810 * valid values [0,1,2] is explained in the description of
1811 * MEDCouplingPointSet::zipConnectivityTraducer() which is called by this method.
1812 * \param [in] epsOnVals - a precision used to compare field
1813 * values at merged cells. If the values differ more than \a epsOnVals, an
1814 * exception is thrown.
1815 * \return bool - \c true if some cells have been removed and hence \a this field lies
1817 * \throw If the mesh is not an instance of MEDCouplingUMesh.
1818 * \throw If the mesh is not well defined.
1819 * \throw If the spatial discretization of \a this field is NULL.
1820 * \throw If the data array is not set.
1821 * \throw If field values at merged cells (if any) differ more than \a epsOnVals.
1823 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals)
1825 const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
1827 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipConnectivity : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1829 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipConnectivity !");
1830 MCAuto<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCopy());
1831 mcIdType oldNbOfCells(meshC2->getNumberOfCells());
1832 MCAuto<DataArrayIdType> arr=meshC2->zipConnectivityTraducer(compType);
1833 if(meshC2->getNumberOfCells()!=oldNbOfCells)
1835 std::vector<DataArrayDouble *> arrays;
1836 timeDiscr()->getArrays(arrays);
1837 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1839 _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),ToIdType(meshC2->getNumberOfCells()),*iter);
1847 * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists.
1848 * For the moment, this method is implemented for fields on cells.
1850 * \return a newly allocated field double containing the result that the user should deallocate.
1852 MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const
1854 const MEDCouplingMesh *mesh=getMesh();
1856 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !");
1857 if(getTypeOfField()!=ON_CELLS)
1858 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !");
1859 const MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1860 MCAuto<MEDCouplingFieldDouble> ret(clone(false));
1861 ret->setMesh(umesh);
1862 DataArrayIdType *cellIds=0;
1863 MCAuto<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds);
1864 MCAuto<DataArrayIdType> cellIds2=cellIds;
1865 ret->setMesh(mesh2);
1866 MCAuto<DataArrayIdType> tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end());
1867 std::vector<DataArrayDouble *> arrays;
1868 timeDiscr()->getArrays(arrays);
1870 std::vector<DataArrayDouble *> newArr(arrays.size());
1871 std::vector< MCAuto<DataArrayDouble> > newArr2(arrays.size());
1872 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++)
1876 newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
1877 newArr[i]=newArr2[i];
1880 ret->setArrays(newArr);
1885 * Divides every cell of the underlying mesh into simplices (triangles in 2D and
1886 * tetrahedra in 3D). If some cells are divided, the underlying mesh is replaced by a new
1887 * mesh instance containing the simplices.<br>
1888 * \param [in] policy - specifies a pattern used for splitting. For its description, see
1889 * MEDCouplingUMesh::simplexize().
1890 * \return bool - \c true if some cells have been divided and hence \a this field lies
1892 * \throw If \a policy has an invalid value. For valid values, see the description of
1893 * MEDCouplingUMesh::simplexize().
1894 * \throw If MEDCouplingMesh::simplexize() is not applicable to the underlying mesh.
1895 * \throw If the mesh is not well defined.
1896 * \throw If the spatial discretization of \a this field is NULL.
1897 * \throw If the data array is not set.
1899 bool MEDCouplingFieldDouble::simplexize(int policy)
1902 throw INTERP_KERNEL::Exception("No underlying mesh on this field to perform simplexize !");
1904 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform simplexize !");
1905 std::size_t oldNbOfCells=_mesh->getNumberOfCells();
1906 MCAuto<MEDCouplingMesh> meshC2(_mesh->deepCopy());
1907 MCAuto<DataArrayIdType> arr=meshC2->simplexize(policy);
1908 std::size_t newNbOfCells=meshC2->getNumberOfCells();
1909 if(oldNbOfCells==newNbOfCells)
1911 std::vector<DataArrayDouble *> arrays;
1912 timeDiscr()->getArrays(arrays);
1913 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1915 _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),ToIdType(arr->getNbOfElems()),*iter);
1921 * 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.
1922 * Each Gauss points in \a this is replaced by a polygon or polyhedron cell with associated region following Voronoi algorithm.
1924 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoize(double eps) const
1926 checkConsistencyLight();
1927 const MEDCouplingMesh *mesh(getMesh());
1928 INTERP_KERNEL::AutoCppPtr<Voronizer> vor;
1929 std::size_t meshDim(mesh->getMeshDimension()),spaceDim(mesh->getSpaceDimension());
1930 if(meshDim==1 && (spaceDim==1 || spaceDim==2 || spaceDim==3))
1931 vor=new Voronizer1D;
1932 else if(meshDim==2 && (spaceDim==2 || spaceDim==3))
1933 vor=new Voronizer2D;
1934 else if(meshDim==3 && spaceDim==3)
1935 vor=new Voronizer3D;
1937 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize : only 2D, 3D surf, and 3D are supported for the moment !");
1938 return voronoizeGen(vor,eps);
1942 * \sa MEDCouplingUMesh::convertQuadraticCellsToLinear
1944 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::convertQuadraticCellsToLinear() const
1946 checkConsistencyLight();
1947 switch(getTypeOfField())
1951 const MEDCouplingMesh *mesh(getMesh());
1953 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
1954 MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1955 umesh=umesh->clone(false);
1956 umesh->convertQuadraticCellsToLinear();
1957 MCAuto<DataArrayIdType> o2n(umesh->zipCoordsTraducer());
1958 MCAuto<DataArrayIdType> n2o(o2n->invertArrayO2N2N2O(umesh->getNumberOfNodes()));
1959 MCAuto<DataArrayDouble> arr(getArray()->selectByTupleIdSafe(n2o->begin(),n2o->end()));
1960 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_NODES));
1962 ret->setMesh(umesh);
1963 ret->copyAllTinyAttrFrom(this);
1968 const MEDCouplingMesh *mesh(getMesh());
1970 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
1971 MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1972 umesh=umesh->clone(false);
1973 umesh->convertQuadraticCellsToLinear();
1975 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS));
1976 ret->setArray(const_cast<DataArrayDouble *>(getArray()));
1977 ret->setMesh(umesh);
1978 ret->copyAllTinyAttrFrom(this);
1983 const MEDCouplingMesh *mesh(getMesh());
1985 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !");
1986 MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1987 std::set<INTERP_KERNEL::NormalizedCellType> gt(umesh->getAllGeoTypes());
1988 MCAuto<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_GAUSS_PT));
1990 const MEDCouplingFieldDiscretization *disc(getDiscretization());
1991 const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
1993 throw INTERP_KERNEL::Exception("convertQuadraticCellsToLinear : Not a ON_GAUSS_PT field");
1994 std::set<INTERP_KERNEL::NormalizedCellType> gt2(umesh->getAllGeoTypes());
1995 std::vector< MCAuto<DataArrayIdType> > cellIdsV;
1996 std::vector< MCAuto<MEDCouplingUMesh> > meshesV;
1997 std::vector< MEDCouplingGaussLocalization > glV;
1998 bool isZipReq(false);
1999 for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=gt.begin();it!=gt.end();it++)
2001 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it));
2002 MCAuto<DataArrayIdType> cellIds(umesh->giveCellsWithType(*it));
2003 cellIdsV.push_back(cellIds);
2004 MCAuto<MEDCouplingUMesh> part(umesh->buildPartOfMySelf(cellIds->begin(),cellIds->end()));
2005 mcIdType id(disc2->getGaussLocalizationIdOfOneType(*it));
2006 const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(id));
2007 if(!cm.isQuadratic())
2014 part->convertQuadraticCellsToLinear();
2015 INTERP_KERNEL::GaussInfo gi(*it,gl.getGaussCoords(),gl.getNumberOfGaussPt(),gl.getRefCoords(),gl.getNumberOfPtsInRefCell());
2016 INTERP_KERNEL::GaussInfo gi2(gi.convertToLinear());
2017 MEDCouplingGaussLocalization gl2(gi2.getGeoType(),gi2.getRefCoords(),gi2.getGaussCoords(),gl.getWeights());
2020 meshesV.push_back(part);
2024 std::vector< const MEDCouplingUMesh * > meshesPtr(VecAutoToVecOfCstPt(meshesV));
2025 umesh=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshesPtr);
2026 std::vector< const DataArrayIdType * > zeCellIds(VecAutoToVecOfCstPt(cellIdsV));
2027 MCAuto<DataArrayIdType> zeIds(DataArrayIdType::Aggregate(zeCellIds));
2028 umesh->renumberCells(zeIds->begin());
2029 umesh->setName(mesh->getName());
2034 ret->setArray(const_cast<DataArrayDouble *>(getArray()));
2035 ret->setMesh(umesh);
2036 for(std::vector< MEDCouplingGaussLocalization >::const_iterator it=glV.begin();it!=glV.end();it++)
2037 ret->setGaussLocalizationOnType((*it).getType(),(*it).getRefCoords(),(*it).getGaussCoords(),(*it).getWeights());
2038 ret->copyAllTinyAttrFrom(this);
2039 ret->checkConsistencyLight();
2043 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : Only available for fields on nodes and on cells !");
2048 * 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.
2049 * Finally \a this is also expected to be consistent.
2050 * In these conditions this method returns a newly created field (to be dealed by the caller).
2051 * The returned field will also 3 compo vector field be on nodes lying on the same mesh than \a this.
2053 * 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.
2054 * \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.
2056 * \sa DataArrayDouble::fromCartToCylGiven
2058 MEDCouplingFieldDouble *MEDCouplingFieldDouble::computeVectorFieldCyl(const double center[3], const double vect[3]) const
2060 checkConsistencyLight();
2061 const DataArrayDouble *coo(getMesh()->getDirectAccessOfCoordsArrIfInStructure());
2062 MEDCouplingTimeDiscretization *td(timeDiscr()->computeVectorFieldCyl(coo,center,vect));
2063 td->copyTinyAttrFrom(*timeDiscr());
2064 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2065 ret->setMesh(getMesh());
2066 ret->setName(getName());
2071 * Creates a new MEDCouplingFieldDouble filled with the doubly contracted product of
2072 * every tensor of \a this 6-componental field.
2073 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2074 * each tuple is calculated from the tuple <em>(t)</em> of \a this field as
2075 * follows: \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2076 * This new field lies on the same mesh as \a this one. The caller is to delete
2077 * this field using decrRef() as it is no more needed.
2078 * \throw If \a this->getNumberOfComponents() != 6.
2079 * \throw If the spatial discretization of \a this field is NULL.
2081 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const
2084 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform doublyContractedProduct !");
2085 MEDCouplingTimeDiscretization *td(timeDiscr()->doublyContractedProduct());
2086 td->copyTinyAttrFrom(*timeDiscr());
2087 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2088 ret->setName("DoublyContractedProduct");
2089 ret->setMesh(getMesh());
2094 * Creates a new MEDCouplingFieldDouble filled with the determinant of a square
2095 * matrix defined by every tuple of \a this field, having either 4, 6 or 9 components.
2096 * The case of 6 components corresponds to that of the upper triangular matrix.
2097 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2098 * each tuple is the determinant of matrix of the corresponding tuple of \a this
2099 * field. This new field lies on the same mesh as \a this one. The caller is to
2100 * delete this field using decrRef() as it is no more needed.
2101 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2102 * \throw If the spatial discretization of \a this field is NULL.
2104 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const
2107 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform determinant !");
2108 MEDCouplingTimeDiscretization *td(timeDiscr()->determinant());
2109 td->copyTinyAttrFrom(*timeDiscr());
2110 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2111 ret->setName("Determinant");
2112 ret->setMesh(getMesh());
2118 * Creates a new MEDCouplingFieldDouble with 3 components filled with 3 eigenvalues of
2119 * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2120 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2121 * having 3 components, whose each tuple contains the eigenvalues of the matrix of
2122 * corresponding tuple of \a this field. This new field lies on the same mesh as
2123 * \a this one. The caller is to delete this field using decrRef() as it is no
2125 * \throw If \a this->getNumberOfComponents() != 6.
2126 * \throw If the spatial discretization of \a this field is NULL.
2128 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const
2131 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenValues !");
2132 MEDCouplingTimeDiscretization *td(timeDiscr()->eigenValues());
2133 td->copyTinyAttrFrom(*timeDiscr());
2134 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2135 ret->setName("EigenValues");
2136 ret->setMesh(getMesh());
2141 * Creates a new MEDCouplingFieldDouble with 9 components filled with 3 eigenvectors of
2142 * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2143 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2144 * having 9 components, whose each tuple contains the eigenvectors of the matrix of
2145 * corresponding tuple of \a this field. This new field lies on the same mesh as
2146 * \a this one. The caller is to delete this field using decrRef() as it is no
2148 * \throw If \a this->getNumberOfComponents() != 6.
2149 * \throw If the spatial discretization of \a this field is NULL.
2151 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const
2154 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenVectors !");
2155 MEDCouplingTimeDiscretization *td(timeDiscr()->eigenVectors());
2156 td->copyTinyAttrFrom(*timeDiscr());
2157 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2158 ret->setName("EigenVectors");
2159 ret->setMesh(getMesh());
2164 * Creates a new MEDCouplingFieldDouble filled with the inverse matrix of
2165 * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2166 * components. The case of 6 components corresponds to that of the upper triangular
2168 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2169 * having the same number of components as \a this one, whose each tuple
2170 * contains the inverse matrix of the matrix of corresponding tuple of \a this
2171 * field. This new field lies on the same mesh as \a this one. The caller is to
2172 * delete this field using decrRef() as it is no more needed.
2173 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2174 * \throw If the spatial discretization of \a this field is NULL.
2176 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const
2179 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform inverse !");
2180 MEDCouplingTimeDiscretization *td(timeDiscr()->inverse());
2181 td->copyTinyAttrFrom(*timeDiscr());
2182 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2183 ret->setName("Inversion");
2184 ret->setMesh(getMesh());
2189 * Creates a new MEDCouplingFieldDouble filled with the trace of
2190 * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2191 * components. The case of 6 components corresponds to that of the upper triangular
2193 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2194 * having 1 component, whose each tuple is the trace of the matrix of
2195 * corresponding tuple of \a this field.
2196 * This new field lies on the same mesh as \a this one. The caller is to
2197 * delete this field using decrRef() as it is no more needed.
2198 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2199 * \throw If the spatial discretization of \a this field is NULL.
2201 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const
2204 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform trace !");
2205 MEDCouplingTimeDiscretization *td(timeDiscr()->trace());
2206 td->copyTinyAttrFrom(*timeDiscr());
2207 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2208 ret->setName("Trace");
2209 ret->setMesh(getMesh());
2214 * Creates a new MEDCouplingFieldDouble filled with the stress deviator tensor of
2215 * a stress tensor defined by every tuple of \a this 6-componental field.
2216 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2217 * having same number of components and tuples as \a this field,
2218 * whose each tuple contains the stress deviator tensor of the stress tensor of
2219 * corresponding tuple of \a this field. This new field lies on the same mesh as
2220 * \a this one. The caller is to delete this field using decrRef() as it is no
2222 * \throw If \a this->getNumberOfComponents() != 6.
2223 * \throw If the spatial discretization of \a this field is NULL.
2225 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const
2228 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform deviator !");
2229 MEDCouplingTimeDiscretization *td(timeDiscr()->deviator());
2230 td->copyTinyAttrFrom(*timeDiscr());
2231 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2232 ret->setName("Deviator");
2233 ret->setMesh(getMesh());
2238 * Creates a new MEDCouplingFieldDouble filled with the magnitude of
2239 * every vector of \a this field.
2240 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2241 * having one component, whose each tuple is the magnitude of the vector
2242 * of corresponding tuple of \a this field. This new field lies on the
2243 * same mesh as \a this one. The caller is to
2244 * delete this field using decrRef() as it is no more needed.
2245 * \throw If the spatial discretization of \a this field is NULL.
2247 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const
2250 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform magnitude !");
2251 MEDCouplingTimeDiscretization *td(timeDiscr()->magnitude());
2252 td->copyTinyAttrFrom(*timeDiscr());
2253 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2254 ret->setName("Magnitude");
2255 ret->setMesh(getMesh());
2260 * Creates a new scalar MEDCouplingFieldDouble filled with the maximal value among
2261 * values of every tuple of \a this field.
2262 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2263 * This new field lies on the same mesh as \a this one. The caller is to
2264 * delete this field using decrRef() as it is no more needed.
2265 * \throw If the spatial discretization of \a this field is NULL.
2267 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const
2270 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform maxPerTuple !");
2271 MEDCouplingTimeDiscretization *td(timeDiscr()->maxPerTuple());
2272 td->copyTinyAttrFrom(*timeDiscr());
2273 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2274 std::ostringstream oss;
2275 oss << "Max_" << getName();
2276 ret->setName(oss.str());
2277 ret->setMesh(getMesh());
2282 * Changes number of components in \a this field. If \a newNbOfComp is less
2283 * than \a this->getNumberOfComponents() then each tuple
2284 * is truncated to have \a newNbOfComp components, keeping first components. If \a
2285 * newNbOfComp is more than \a this->getNumberOfComponents() then
2286 * each tuple is populated with \a dftValue to have \a newNbOfComp components.
2287 * \param [in] newNbOfComp - number of components for the new field to have.
2288 * \param [in] dftValue - value assigned to new values added to \a this field.
2289 * \throw If \a this is not allocated.
2291 void MEDCouplingFieldDouble::changeNbOfComponents(std::size_t newNbOfComp, double dftValue)
2293 timeDiscr()->changeNbOfComponents(newNbOfComp,dftValue);
2297 * Creates a new MEDCouplingFieldDouble composed of selected components of \a this field.
2298 * The new MEDCouplingFieldDouble has the same number of tuples but includes components
2299 * specified by \a compoIds parameter. So that getNbOfElems() of the result field
2300 * can be either less, same or more than \a this->getNumberOfValues().
2301 * \param [in] compoIds - sequence of zero based indices of components to include
2302 * into the new field.
2303 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble that the caller
2304 * is to delete using decrRef() as it is no more needed.
2305 * \throw If a component index (\a i) is not valid:
2306 * \a i < 0 || \a i >= \a this->getNumberOfComponents().
2308 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<std::size_t>& compoIds) const
2311 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform keepSelectedComponents !");
2312 MEDCouplingTimeDiscretization *td(timeDiscr()->keepSelectedComponents(compoIds));
2313 td->copyTinyAttrFrom(*timeDiscr());
2314 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2315 ret->setName(getName());
2316 ret->setMesh(getMesh());
2321 * Copy all components in a specified order from another field.
2322 * The number of tuples in \a this and the other field can be different.
2323 * \param [in] f - the field to copy data from.
2324 * \param [in] compoIds - sequence of zero based indices of components, data of which is
2326 * \throw If the two fields have different number of data arrays.
2327 * \throw If a data array is set in one of fields and is not set in the other.
2328 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2329 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2331 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<std::size_t>& compoIds)
2333 timeDiscr()->setSelectedComponents(f->timeDiscr(),compoIds);
2337 * Sorts value within every tuple of \a this field.
2338 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2339 * in descending order.
2340 * \throw If a data array is not allocated.
2342 void MEDCouplingFieldDouble::sortPerTuple(bool asc)
2344 timeDiscr()->sortPerTuple(asc);
2348 * Creates a new MEDCouplingFieldDouble by concatenating two given fields.
2350 * the first field precede values of the second field within the result field.
2351 * \param [in] f1 - the first field.
2352 * \param [in] f2 - the second field.
2353 * \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2354 * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef()
2355 * as it is no more needed.
2356 * \throw If the fields are not compatible for the merge.
2357 * \throw If the spatial discretization of \a f1 is NULL.
2358 * \throw If the time discretization of \a f1 is NULL.
2360 * \if ENABLE_EXAMPLES
2361 * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2362 * \ref py_mcfielddouble_MergeFields "Here is a Python example".
2365 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2367 std::vector<const MEDCouplingFieldDouble *> a(2);
2369 return MergeFields(a);
2373 * Creates a new MEDCouplingFieldDouble by concatenating all given fields.
2374 * Values of the *i*-th field precede values of the (*i*+1)-th field within the result.
2375 * If there is only one field in \a a, a deepCopy() (except time information of mesh and
2376 * field) of the field is returned.
2377 * Generally speaking the first field in \a a is used to assign tiny attributes of the
2379 * \param [in] a - a vector of fields (MEDCouplingFieldDouble) to concatenate.
2380 * \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2381 * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef()
2382 * as it is no more needed.
2383 * \throw If \a a is empty.
2384 * \throw If the fields are not compatible for the merge.
2386 * \if ENABLE_EXAMPLES
2387 * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2388 * \ref py_mcfielddouble_MergeFields "Here is a Python example".
2391 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a)
2394 throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : input array is empty !");
2395 std::vector< MCAuto<MEDCouplingUMesh> > ms(a.size());
2396 std::vector< const MEDCouplingUMesh *> ms2(a.size());
2397 std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
2398 std::vector< const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
2399 std::vector<const MEDCouplingFieldDiscretization *> fds(a.size());
2400 const MEDCouplingFieldDouble *ref((*it++));
2402 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of nullptr instance in first place of input vector !");
2403 if(!ref->getDiscretization())
2404 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : nullptr spatial discretization !");
2405 for(;it!=a.end();it++)
2406 if(!ref->areCompatibleForMerge(*it))
2407 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2408 for(std::size_t i=0;i<a.size();i++)
2411 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of nullptr instance in input vector !");
2413 { ms[i]=a[i]->getMesh()->buildUnstructured(); ms2[i]=ms[i]; }
2415 { ms[i]=0; ms2[i]=0; }
2416 tds[i]=a[i]->timeDiscr();
2417 fds[i]=a[i]->getDiscretization();
2419 MEDCouplingTimeDiscretization *td(tds[0]->aggregate(tds));
2420 MCAuto<MEDCouplingFieldDiscretization> fda(fds[0]->aggregate(fds));
2421 td->copyTinyAttrFrom(*(a[0]->timeDiscr()));
2422 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(a[0]->getNature(),td,fda.retn()));
2423 ret->setName(a[0]->getName());
2424 ret->setDescription(a[0]->getDescription());
2427 MCAuto<MEDCouplingUMesh> m(MEDCouplingUMesh::MergeUMeshes(ms2));
2428 m->copyTinyInfoFrom(ms2[0]);
2435 * Creates a new MEDCouplingFieldDouble by concatenating components of two given fields.
2436 * The number of components in the result field is a sum of the number of components of
2437 * given fields. The number of tuples in the result field is same as that of each of given
2439 * Number of tuples in the given fields must be the same.
2440 * \param [in] f1 - a field to include in the result field.
2441 * \param [in] f2 - another field to include in the result field.
2442 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2443 * The caller is to delete this result field using decrRef() as it is no more
2445 * \throw If the fields are not compatible for a meld (areCompatibleForMeld()).
2446 * \throw If any of data arrays is not allocated.
2447 * \throw If \a f1->getNumberOfTuples() != \a f2->getNumberOfTuples()
2449 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2452 throw INTERP_KERNEL::Exception("MeldFields : null input pointer !");
2453 if(!f1->areCompatibleForMeld(f2))
2454 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
2455 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->meld(f2->timeDiscr()));
2456 td->copyTinyAttrFrom(*f1->timeDiscr());
2457 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2458 ret->setMesh(f1->getMesh());
2463 * Returns a new MEDCouplingFieldDouble containing a dot product of two given fields,
2464 * so that the i-th tuple of the result field is a sum of products of j-th components of
2465 * i-th tuples of given fields (\f$ f_i = \sum_{j=1}^n f1_j * f2_j \f$).
2466 * Number of tuples and components in the given fields must be the same.
2467 * \param [in] f1 - a given field.
2468 * \param [in] f2 - another given field.
2469 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2470 * The caller is to delete this result field using decrRef() as it is no more
2472 * \throw If either \a f1 or \a f2 is NULL.
2473 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2474 * differ not only in values.
2476 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2479 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !");
2480 if(!f1->areStrictlyCompatibleForMulDiv(f2))
2481 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them! Check support mesh, and spatial and time discretisation.");
2482 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->dot(f2->timeDiscr()));
2483 td->copyTinyAttrFrom(*f1->timeDiscr());
2484 MEDCouplingFieldDouble *ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2485 ret->setMesh(f1->getMesh());
2490 * Returns a new MEDCouplingFieldDouble containing a cross product of two given fields,
2492 * the i-th tuple of the result field is a 3D vector which is a cross
2493 * product of two vectors defined by the i-th tuples of given fields.
2494 * Number of tuples in the given fields must be the same.
2495 * Number of components in the given fields must be 3.
2496 * \param [in] f1 - a given field.
2497 * \param [in] f2 - another given field.
2498 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2499 * The caller is to delete this result field using decrRef() as it is no more
2501 * \throw If either \a f1 or \a f2 is NULL.
2502 * \throw If \a f1->getNumberOfComponents() != 3
2503 * \throw If \a f2->getNumberOfComponents() != 3
2504 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2505 * differ not only in values.
2507 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2510 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !");
2511 if(!f1->areStrictlyCompatibleForMulDiv(f2))
2512 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation.");
2513 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->crossProduct(f2->timeDiscr()));
2514 td->copyTinyAttrFrom(*f1->timeDiscr());
2515 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2516 ret->setMesh(f1->getMesh());
2521 * Returns a new MEDCouplingFieldDouble containing maximal values of two given fields.
2522 * Number of tuples and components in the given fields must be the same.
2523 * \param [in] f1 - a field to compare values with another one.
2524 * \param [in] f2 - another field to compare values with the first one.
2525 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2526 * The caller is to delete this result field using decrRef() as it is no more
2528 * \throw If either \a f1 or \a f2 is NULL.
2529 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2530 * differ not only in values.
2532 * \if ENABLE_EXAMPLES
2533 * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2534 * \ref py_mcfielddouble_MaxFields "Here is a Python example".
2537 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2540 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MaxFields : input field is NULL !");
2541 if(!f1->areStrictlyCompatible(f2))
2542 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MaxFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2543 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->max(f2->timeDiscr()));
2544 td->copyTinyAttrFrom(*f1->timeDiscr());
2545 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2546 ret->setMesh(f1->getMesh());
2551 * Returns a new MEDCouplingFieldDouble containing minimal values of two given fields.
2552 * Number of tuples and components in the given fields must be the same.
2553 * \param [in] f1 - a field to compare values with another one.
2554 * \param [in] f2 - another field to compare values with the first one.
2555 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2556 * The caller is to delete this result field using decrRef() as it is no more
2558 * \throw If either \a f1 or \a f2 is NULL.
2559 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2560 * differ not only in values.
2562 * \if ENABLE_EXAMPLES
2563 * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2564 * \ref py_mcfielddouble_MaxFields "Here is a Python example".
2567 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2570 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MinFields : input field is NULL !");
2571 if(!f1->areStrictlyCompatible(f2))
2572 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MinFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2573 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->min(f2->timeDiscr()));
2574 td->copyTinyAttrFrom(*f1->timeDiscr());
2575 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2576 ret->setMesh(f1->getMesh());
2581 * Returns a copy of \a this field in which sign of all values is reversed.
2582 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble
2583 * containing the same number of tuples and components as \a this field.
2584 * The caller is to delete this result field using decrRef() as it is no more
2586 * \throw If the spatial discretization of \a this field is NULL.
2587 * \throw If a data array is not allocated.
2589 MEDCouplingFieldDouble *MEDCouplingFieldDouble::negate() const
2592 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform negate !");
2593 MEDCouplingTimeDiscretization *td(timeDiscr()->negate());
2594 td->copyTinyAttrFrom(*timeDiscr());
2595 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2596 ret->setMesh(getMesh());
2601 * Returns a new MEDCouplingFieldDouble containing sum values of corresponding values of
2602 * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] + _f2_ [ i, j ] ).
2603 * Number of tuples and components in the given fields must be the same.
2604 * \param [in] f1 - a field to sum up.
2605 * \param [in] f2 - another field to sum up.
2606 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2607 * The caller is to delete this result field using decrRef() as it is no more
2609 * \throw If either \a f1 or \a f2 is NULL.
2610 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2611 * differ not only in values.
2613 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2616 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::AddFields : input field is NULL !");
2617 if(!f1->areStrictlyCompatible(f2))
2618 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply AddFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2619 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->add(f2->timeDiscr()));
2620 td->copyTinyAttrFrom(*f1->timeDiscr());
2621 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2622 ret->setMesh(f1->getMesh());
2627 * Adds values of another MEDCouplingFieldDouble to values of \a this one
2628 * ( _this_ [ i, j ] += _other_ [ i, j ] ) using DataArrayDouble::addEqual().
2629 * The two fields must have same number of tuples, components and same underlying mesh.
2630 * \param [in] other - the field to add to \a this one.
2631 * \return const MEDCouplingFieldDouble & - a reference to \a this field.
2632 * \throw If \a other is NULL.
2633 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2634 * differ not only in values.
2636 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other)
2638 if(!areStrictlyCompatible(&other))
2639 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply += on them! Check support mesh, field nature, and spatial and time discretisation.");
2640 timeDiscr()->addEqual(other.timeDiscr());
2645 * Returns a new MEDCouplingFieldDouble containing subtraction of corresponding values of
2646 * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] - _f2_ [ i, j ] ).
2647 * Number of tuples and components in the given fields must be the same.
2648 * \param [in] f1 - a field to subtract from.
2649 * \param [in] f2 - a field to subtract.
2650 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2651 * The caller is to delete this result field using decrRef() as it is no more
2653 * \throw If either \a f1 or \a f2 is NULL.
2654 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2655 * differ not only in values.
2657 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2660 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::SubstractFields : input field is NULL !");
2661 if(!f1->areStrictlyCompatible(f2))
2662 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply SubstractFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2663 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->substract(f2->timeDiscr()));
2664 td->copyTinyAttrFrom(*f1->timeDiscr());
2665 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2666 ret->setMesh(f1->getMesh());
2671 * Subtract values of another MEDCouplingFieldDouble from values of \a this one
2672 * ( _this_ [ i, j ] -= _other_ [ i, j ] ) using DataArrayDouble::substractEqual().
2673 * The two fields must have same number of tuples, components and same underlying mesh.
2674 * \param [in] other - the field to subtract from \a this one.
2675 * \return const MEDCouplingFieldDouble & - a reference to \a this field.
2676 * \throw If \a other is NULL.
2677 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2678 * differ not only in values.
2680 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other)
2682 if(!areStrictlyCompatible(&other))
2683 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply -= on them! Check support mesh, field nature, and spatial and time discretisation.");
2684 timeDiscr()->substractEqual(other.timeDiscr());
2689 * Returns a new MEDCouplingFieldDouble containing product values of
2690 * two given fields. There are 2 valid cases.
2691 * 1. The fields have same number of tuples and components. Then each value of
2692 * the result field (_f_) is a product of the corresponding values of _f1_ and
2693 * _f2_, i.e. _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, j ].
2694 * 2. The fields have same number of tuples and one field, say _f2_, has one
2696 * _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, 0 ].
2698 * The two fields must have same number of tuples and same underlying mesh.
2699 * \param [in] f1 - a factor field.
2700 * \param [in] f2 - another factor field.
2701 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2702 * The caller is to delete this result field using decrRef() as it is no more
2704 * \throw If either \a f1 or \a f2 is NULL.
2705 * \throw If the fields are not compatible for multiplication (areCompatibleForMul()),
2706 * i.e. they differ not only in values and possibly number of components.
2708 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2711 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MultiplyFields : input field is NULL !");
2712 if(!f1->areCompatibleForMul(f2))
2713 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MultiplyFields on them! Check support mesh, and spatial and time discretisation.");
2714 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->multiply(f2->timeDiscr()));
2715 td->copyTinyAttrFrom(*f1->timeDiscr());
2716 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2717 ret->setMesh(f1->getMesh());
2722 * Multiply values of another MEDCouplingFieldDouble to values of \a this one
2723 * using DataArrayDouble::multiplyEqual().
2724 * The two fields must have same number of tuples and same underlying mesh.
2725 * There are 2 valid cases.
2726 * 1. The fields have same number of components. Then each value of
2727 * \a other is multiplied to the corresponding value of \a this field, i.e.
2728 * _this_ [ i, j ] *= _other_ [ i, j ].
2729 * 2. The _other_ field has one component. Then
2730 * _this_ [ i, j ] *= _other_ [ i, 0 ].
2732 * The two fields must have same number of tuples and same underlying mesh.
2733 * \param [in] other - an field to multiply to \a this one.
2734 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2735 * The caller is to delete this result field using decrRef() as it is no more
2737 * \throw If \a other is NULL.
2738 * \throw If the fields are not strictly compatible for multiplication
2739 * (areCompatibleForMul()),
2740 * i.e. they differ not only in values and possibly in number of components.
2742 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other)
2744 if(!areCompatibleForMul(&other))
2745 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply *= on them! Check support mesh, and spatial and time discretisation.");
2746 timeDiscr()->multiplyEqual(other.timeDiscr());
2752 * Returns a new MEDCouplingFieldDouble containing division of two given fields.
2753 * There are 2 valid cases.
2754 * 1. The fields have same number of tuples and components. Then each value of
2755 * the result field (_f_) is a division of the corresponding values of \a f1 and
2756 * \a f2, i.e. _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, j ].
2757 * 2. The fields have same number of tuples and _f2_ has one component. Then
2758 * _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, 0 ].
2760 * \param [in] f1 - a numerator field.
2761 * \param [in] f2 - a denominator field.
2762 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2763 * The caller is to delete this result field using decrRef() as it is no more
2765 * \throw If either \a f1 or \a f2 is NULL.
2766 * \throw If the fields are not compatible for division (areCompatibleForDiv()),
2767 * i.e. they differ not only in values and possibly in number of components.
2769 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2772 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DivideFields : input field is NULL !");
2773 if(!f1->areCompatibleForDiv(f2))
2774 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DivideFields on them! Check support mesh, and spatial and time discretisation.");
2775 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->divide(f2->timeDiscr()));
2776 td->copyTinyAttrFrom(*f1->timeDiscr());
2777 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2778 ret->setMesh(f1->getMesh());
2783 * Divide values of \a this field by values of another MEDCouplingFieldDouble
2784 * using DataArrayDouble::divideEqual().
2785 * The two fields must have same number of tuples and same underlying mesh.
2786 * There are 2 valid cases.
2787 * 1. The fields have same number of components. Then each value of
2788 * \a this field is divided by the corresponding value of \a other one, i.e.
2789 * _this_ [ i, j ] /= _other_ [ i, j ].
2790 * 2. The \a other field has one component. Then
2791 * _this_ [ i, j ] /= _other_ [ i, 0 ].
2793 * \warning No check of division by zero is performed!
2794 * \param [in] other - an field to divide \a this one by.
2795 * \throw If \a other is NULL.
2796 * \throw If the fields are not compatible for division (areCompatibleForDiv()),
2797 * i.e. they differ not only in values and possibly in number of components.
2799 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other)
2801 if(!areCompatibleForDiv(&other))
2802 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply /= on them! Check support mesh, and spatial and time discretisation.");
2803 timeDiscr()->divideEqual(other.timeDiscr());
2809 * Directly called by MEDCouplingFieldDouble::operator^.
2811 * \sa MEDCouplingFieldDouble::operator^
2813 MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2816 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::PowFields : input field is NULL !");
2817 if(!f1->areCompatibleForMul(f2))
2818 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply PowFields on them! Check support mesh, and spatial and time discretisation.");
2819 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->pow(f2->timeDiscr()));
2820 td->copyTinyAttrFrom(*f1->timeDiscr());
2821 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2822 ret->setMesh(f1->getMesh());
2827 * Directly call MEDCouplingFieldDouble::PowFields static method.
2829 * \sa MEDCouplingFieldDouble::PowFields
2831 MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const
2833 return PowFields(this,&other);
2836 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other)
2838 if(!areCompatibleForDiv(&other))
2839 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply ^= on them! Check support mesh, and spatial and time discretisation.");
2840 timeDiscr()->powEqual(other.timeDiscr());
2846 * Writes the field series \a fs and the mesh the fields lie on in the VTK file \a fileName.
2847 * If \a fs is empty no file is written.
2848 * The result file is valid provided that no exception is thrown.
2849 * \warning All the fields must be named and lie on the same non NULL mesh.
2850 * \param [in] fileName - the name of a VTK file to write in.
2851 * \param [in] fs - the fields to write.
2852 * \param [in] isBinary - specifies the VTK format of the written file. By default true (Binary mode)
2853 * \throw If \a fs[ 0 ] == NULL.
2854 * \throw If the fields lie not on the same mesh.
2855 * \throw If the mesh is not set.
2856 * \throw If any of the fields has no name.
2858 * \if ENABLE_EXAMPLES
2859 * \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".<br>
2860 * \ref py_mcfielddouble_WriteVTK "Here is a Python example".
2863 std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector<const MEDCouplingFieldDouble *>& fs, bool isBinary)
2866 return std::string();
2867 std::size_t nfs=fs.size();
2869 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field is NULL !");
2870 const MEDCouplingMesh *m=fs[0]->getMesh();
2872 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field lies on NULL mesh !");
2873 for(std::size_t i=1;i<nfs;i++)
2874 if(fs[i]->getMesh()!=m)
2875 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.");
2877 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !");
2878 std::string ret(m->getVTKFileNameOf(fileName));
2879 MCAuto<DataArrayByte> byteArr;
2881 { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); }
2882 std::ostringstream coss,noss;
2883 for(std::size_t i=0;i<nfs;i++)
2885 const MEDCouplingFieldDouble *cur=fs[i];
2886 std::string name(cur->getName());
2889 std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
2890 throw INTERP_KERNEL::Exception(oss.str());
2892 TypeOfField typ=cur->getTypeOfField();
2894 cur->getArray()->writeVTK(coss,8,cur->getName(),byteArr);
2895 else if(typ==ON_NODES)
2896 cur->getArray()->writeVTK(noss,8,cur->getName(),byteArr);
2898 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : only node and cell fields supported for the moment !");
2900 m->writeVTKAdvanced(ret,coss.str(),noss.str(),byteArr);
2904 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoizeGen(const Voronizer *vor, double eps) const
2906 checkConsistencyLight();
2908 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoizeGen : null pointer !");
2909 MCAuto<MEDCouplingFieldDouble> fieldToWO;
2910 const MEDCouplingMesh *inpMeshBase(getMesh());
2911 MCAuto<MEDCouplingUMesh> inpMesh(inpMeshBase->buildUnstructured());
2912 std::string meshName(inpMesh->getName());
2913 if(!inpMesh->isPresenceOfQuadratic())
2914 fieldToWO=clone(false);
2917 fieldToWO=convertQuadraticCellsToLinear();
2918 inpMeshBase=fieldToWO->getMesh();
2919 inpMesh=inpMeshBase->buildUnstructured();
2921 mcIdType nbCells(inpMesh->getNumberOfCells());
2922 const MEDCouplingFieldDiscretization *disc(fieldToWO->getDiscretization());
2923 const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
2925 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : Not a ON_GAUSS_PT field");
2926 mcIdType nbLocs(disc2->getNbOfGaussLocalization());
2927 std::vector< MCAuto<MEDCouplingUMesh> > cells(nbCells);
2928 for(mcIdType i=0;i<nbLocs;i++)
2930 const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(i));
2931 if(gl.getDimension()!=vor->getDimension())
2932 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : not a 2D one !");
2933 MCAuto<MEDCouplingUMesh> mesh(gl.buildRefCell());
2934 const std::vector<double>& coo(gl.getGaussCoords());
2935 MCAuto<DataArrayDouble> coo2(DataArrayDouble::NewFromStdVector(coo));
2936 coo2->rearrange(vor->getDimension());
2938 MCAuto<MEDCouplingUMesh> coo3(MEDCouplingUMesh::Build0DMeshFromCoords(coo2));
2940 MCAuto<MEDCouplingUMesh> vorCellsForCurDisc(vor->doIt(mesh,coo2,eps));
2941 std::vector<mcIdType> ids;
2942 MCAuto<DataArrayDouble> ptsInReal;
2943 disc2->getCellIdsHavingGaussLocalization(i,ids);
2945 MCAuto<MEDCouplingUMesh> subMesh(inpMesh->buildPartOfMySelf(&ids[0],&ids[0]+ids.size()));
2946 ptsInReal=gl.localizePtsInRefCooForEachCell(vorCellsForCurDisc->getCoords(),subMesh);
2948 mcIdType nbPtsPerCell(vorCellsForCurDisc->getNumberOfNodes());
2949 for(mcIdType j=0;j<ToIdType(ids.size());j++)
2951 MCAuto<MEDCouplingUMesh> elt(vorCellsForCurDisc->clone(false));
2952 MCAuto<DataArrayDouble> coo4(ptsInReal->selectByTupleIdSafeSlice(j*nbPtsPerCell,(j+1)*nbPtsPerCell,1));
2953 elt->setCoords(coo4);
2957 std::vector< const MEDCouplingUMesh * > cellsPtr(VecAutoToVecOfCstPt(cells));
2958 MCAuto<MEDCouplingUMesh> outMesh(MEDCouplingUMesh::MergeUMeshes(cellsPtr));
2959 outMesh->setName(meshName);
2960 MCAuto<MEDCouplingFieldDouble> onCells(MEDCouplingFieldDouble::New(ON_CELLS));
2961 onCells->setMesh(outMesh);
2963 MCAuto<DataArrayDouble> arr(fieldToWO->getArray()->deepCopy());
2964 onCells->setArray(arr);
2966 onCells->setTimeUnit(getTimeUnit());
2969 double a(getTime(b,c));
2970 onCells->setTime(a,b,c);
2972 onCells->setName(getName());
2976 MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr()
2978 MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
2981 MEDCouplingTimeDiscretization *retc(dynamic_cast<MEDCouplingTimeDiscretization *>(ret));
2983 throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");
2987 const MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr() const
2989 const MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
2992 const MEDCouplingTimeDiscretization *retc(dynamic_cast<const MEDCouplingTimeDiscretization *>(ret));
2994 throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");