1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCouplingFieldDouble.hxx"
22 #include "MEDCouplingFieldTemplate.hxx"
23 #include "MEDCouplingFieldT.txx"
24 #include "MEDCouplingFieldInt.hxx"
25 #include "MEDCouplingUMesh.hxx"
26 #include "MEDCouplingTimeDiscretization.hxx"
27 #include "MEDCouplingFieldDiscretization.hxx"
29 #include "MEDCouplingVoronoi.hxx"
30 #include "MEDCouplingNatureOfField.hxx"
32 #include "InterpKernelAutoPtr.hxx"
39 using namespace MEDCoupling;
41 template class MEDCouplingFieldT<double>;
44 * Creates a new MEDCouplingFieldDouble, of given spatial type and time discretization.
45 * For more info, see \ref MEDCouplingFirstSteps3.
46 * \param [in] type - the type of spatial discretization of the created field, one of
47 * (\ref MEDCoupling::ON_CELLS "ON_CELLS",
48 * \ref MEDCoupling::ON_NODES "ON_NODES",
49 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT",
50 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE",
51 * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR").
52 * \param [in] td - the type of time discretization of the created field, one of
53 * (\ref MEDCoupling::NO_TIME "NO_TIME",
54 * \ref MEDCoupling::ONE_TIME "ONE_TIME",
55 * \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME",
56 * \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
57 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
58 * caller is to delete this field using decrRef() as it is no more needed.
60 MEDCouplingFieldDouble* MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td)
62 return new MEDCouplingFieldDouble(type,td);
66 * Creates a new MEDCouplingFieldDouble, of a given time discretization and with a
67 * spatial type and supporting mesh copied from a given
68 * \ref MEDCouplingFieldTemplatesPage "field template".
69 * For more info, see \ref MEDCouplingFirstSteps3.
70 * \warning This method does not deeply copy neither the mesh nor the spatial
71 * discretization. Only a shallow copy (reference) is done for the mesh and the spatial
73 * \param [in] ft - the \ref MEDCouplingFieldTemplatesPage "field template" defining
74 * the spatial discretization and the supporting mesh.
75 * \param [in] td - the type of time discretization of the created field, one of
76 * (\ref MEDCoupling::NO_TIME "NO_TIME",
77 * \ref MEDCoupling::ONE_TIME "ONE_TIME",
78 * \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME",
79 * \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
80 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
81 * caller is to delete this field using decrRef() as it is no more needed.
83 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td)
85 return new MEDCouplingFieldDouble(ft,td);
89 * Sets a time \a unit of \a this field. For more info, see \ref MEDCouplingFirstSteps3.
90 * \param [in] unit \a unit (string) in which time is measured.
92 //void MEDCouplingFieldDouble::setTimeUnit(const std::string& unit)
95 * Returns a time unit of \a this field.
96 * \return a string describing units in which time is measured.
98 //std::string MEDCouplingFieldDouble::getTimeUnit() const
102 * This method if possible the time information (time unit, time iteration, time unit and time value) with its support
103 * that is to say its mesh.
105 * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is
108 void MEDCouplingFieldDouble::synchronizeTimeWithSupport()
110 timeDiscr()->synchronizeTimeWith(_mesh);
114 * Returns a new MEDCouplingFieldDouble which is a copy of \a this one. The data
115 * of \a this field is copied either deep or shallow depending on \a recDeepCpy
116 * parameter. But the underlying mesh is always shallow copied.
117 * Data that can be copied either deeply or shallow are:
118 * - \ref MEDCouplingTemporalDisc "temporal discretization" data that holds array(s)
120 * - \ref MEDCouplingSpatialDisc "a spatial discretization".
122 * \c clone(false) is rather dedicated for advanced users that want to limit the amount
123 * of memory. It allows the user to perform methods like operator+(), operator*()
124 * etc. with \a this and the returned field. If the user wants to duplicate deeply the
125 * underlying mesh he should call cloneWithMesh() method or deepCopy() instead.
126 * \warning The underlying \b mesh of the returned field is **always the same**
127 * (pointer) as \a this one **whatever the value** of \a recDeepCpy parameter.
128 * \param [in] recDeepCpy - if \c true, the copy of the underlying data arrays is
129 * deep, else all data arrays of \a this field are shared by the new field.
130 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The
131 * caller is to delete this field using decrRef() as it is no more needed.
132 * \sa cloneWithMesh()
134 MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
136 return new MEDCouplingFieldDouble(*this,recDeepCpy);
140 * Returns a new MEDCouplingFieldDouble which is a deep copy of \a this one **including
142 * The result of this method is exactly the same as that of \c cloneWithMesh(true).
143 * So the resulting field can not be used together with \a this one in the methods
144 * like operator+(), operator*() etc. To avoid deep copying the underlying mesh,
145 * the user can call clone().
146 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The
147 * caller is to delete this field using decrRef() as it is no more needed.
148 * \sa cloneWithMesh()
150 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCopy() const
152 return cloneWithMesh(true);
156 * Creates a new MEDCouplingFieldDouble of given
157 * \ref MEDCouplingTemporalDisc "temporal discretization". The result field either
158 * shares the data array(s) with \a this field, or holds a deep copy of it, depending on
159 * \a deepCopy parameter. But the underlying \b mesh is always **shallow copied**.
160 * \param [in] td - the type of time discretization of the created field, one of
161 * (\ref MEDCoupling::NO_TIME "NO_TIME",
162 * \ref MEDCoupling::ONE_TIME "ONE_TIME",
163 * \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME",
164 * \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
165 * \param [in] deepCopy - if \c true, the copy of the underlying data arrays is
166 * deep, else all data arrays of \a this field are shared by the new field.
167 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
168 * caller is to delete this field using decrRef() as it is no more needed.
170 * \if ENABLE_EXAMPLES
171 * \ref cpp_mcfielddouble_buildNewTimeReprFromThis "Here is a C++ example."<br>
172 * \ref py_mcfielddouble_buildNewTimeReprFromThis "Here is a Python example."
176 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const
178 MEDCouplingTimeDiscretization *tdo=timeDiscr()->buildNewTimeReprFromThis(td,deepCopy);
179 MCAuto<MEDCouplingFieldDiscretization> disc;
182 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),tdo,disc.retn()));
183 ret->setMesh(getMesh());
184 ret->setName(getName());
185 ret->setDescription(getDescription());
190 * This method converts a field on nodes (\a this) to a cell field (returned field). The convertion is a \b non \b conservative remapping !
191 * This method is useful only for users that need a fast convertion from node to cell spatial discretization. The algorithm applied is simply to attach
192 * to each cell the average of values on nodes constituting this cell.
194 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
195 * 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.
196 * \throw If \a this spatial discretization is empty or not ON_NODES.
197 * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkConsistencyLight).
199 * \warning This method is a \b non \b conservative method of remapping from node spatial discretization to cell spatial discretization.
200 * If a conservative method of interpolation is required MEDCoupling::MEDCouplingRemapper class should be used instead with "P1P0" method.
202 MEDCouplingFieldDouble *MEDCouplingFieldDouble::nodeToCellDiscretization() const
204 checkConsistencyLight();
205 TypeOfField tf(getTypeOfField());
207 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::nodeToCellDiscretization : this field is expected to be on ON_NODES !");
208 MCAuto<MEDCouplingFieldDouble> ret(clone(false));
209 MCAuto<MEDCouplingFieldDiscretizationP0> nsp(new MEDCouplingFieldDiscretizationP0);
210 ret->setDiscretization(nsp);
211 const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkConsistencyLight call
212 int nbCells(m->getNumberOfCells());
213 std::vector<DataArrayDouble *> arrs(getArrays());
214 std::size_t sz(arrs.size());
215 std::vector< MCAuto<DataArrayDouble> > outArrsSafe(sz); std::vector<DataArrayDouble *> outArrs(sz);
216 for(std::size_t j=0;j<sz;j++)
218 int nbCompo(arrs[j]->getNumberOfComponents());
219 outArrsSafe[j]=DataArrayDouble::New(); outArrsSafe[j]->alloc(nbCells,nbCompo);
220 outArrsSafe[j]->copyStringInfoFrom(*arrs[j]);
221 outArrs[j]=outArrsSafe[j];
222 double *pt(outArrsSafe[j]->getPointer());
223 const double *srcPt(arrs[j]->begin());
224 for(int i=0;i<nbCells;i++,pt+=nbCompo)
226 std::vector<int> nodeIds;
227 m->getNodeIdsOfCell(i,nodeIds);
228 std::fill(pt,pt+nbCompo,0.);
229 std::size_t nbNodesInCell(nodeIds.size());
230 for(std::size_t k=0;k<nbNodesInCell;k++)
231 std::transform(srcPt+nodeIds[k]*nbCompo,srcPt+(nodeIds[k]+1)*nbCompo,pt,pt,std::plus<double>());
233 std::transform(pt,pt+nbCompo,pt,std::bind2nd(std::multiplies<double>(),1./((double)nbNodesInCell)));
236 std::ostringstream oss; oss << "MEDCouplingFieldDouble::nodeToCellDiscretization : Cell id #" << i << " has been detected to have no nodes !";
237 throw INTERP_KERNEL::Exception(oss.str());
241 ret->setArrays(outArrs);
246 * This method converts a field on cell (\a this) to a node field (returned field). The convertion is a \b non \b conservative remapping !
247 * This method is useful only for users that need a fast convertion from cell to node spatial discretization. The algorithm applied is simply to attach
248 * 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.).
250 * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The
251 * 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.
252 * \throw If \a this spatial discretization is empty or not ON_CELLS.
253 * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkConsistencyLight).
255 * \warning This method is a \b non \b conservative method of remapping from cell spatial discretization to node spatial discretization.
256 * If a conservative method of interpolation is required MEDCoupling::MEDCouplingRemapper class should be used instead with "P0P1" method.
258 MEDCouplingFieldDouble *MEDCouplingFieldDouble::cellToNodeDiscretization() const
260 checkConsistencyLight();
261 TypeOfField tf(getTypeOfField());
263 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::cellToNodeDiscretization : this field is expected to be on ON_CELLS !");
264 MCAuto<MEDCouplingFieldDouble> ret(clone(false));
265 MCAuto<MEDCouplingFieldDiscretizationP1> nsp(new MEDCouplingFieldDiscretizationP1);
266 ret->setDiscretization(nsp);
267 const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkConsistencyLight call
268 MCAuto<DataArrayInt> rn(DataArrayInt::New()),rni(DataArrayInt::New());
269 m->getReverseNodalConnectivity(rn,rni);
270 MCAuto<DataArrayInt> rni2(rni->deltaShiftIndex());
271 MCAuto<DataArrayDouble> rni3(rni2->convertToDblArr()); rni2=0;
272 std::vector<DataArrayDouble *> arrs(getArrays());
273 std::size_t sz(arrs.size());
274 std::vector< MCAuto<DataArrayDouble> > outArrsSafe(sz); std::vector<DataArrayDouble *> outArrs(sz);
275 for(std::size_t j=0;j<sz;j++)
277 MCAuto<DataArrayDouble> tmp(arrs[j]->selectByTupleIdSafe(rn->begin(),rn->end()));
278 outArrsSafe[j]=(tmp->accumulatePerChunck(rni->begin(),rni->end())); tmp=0;
279 outArrsSafe[j]->divideEqual(rni3);
280 outArrsSafe[j]->copyStringInfoFrom(*arrs[j]);
281 outArrs[j]=outArrsSafe[j];
283 ret->setArrays(outArrs);
288 * Returns a string describing \a this field. The string includes info on
291 * - \ref MEDCouplingSpatialDisc "spatial discretization",
292 * - \ref MEDCouplingTemporalDisc "time discretization",
295 * - contents of data arrays.
297 * \return std::string - the string describing \a this field.
299 std::string MEDCouplingFieldDouble::advancedRepr() const
301 std::ostringstream ret;
302 ret << "FieldDouble with name : \"" << getName() << "\"\n";
303 ret << "Description of field is : \"" << getDescription() << "\"\n";
305 { ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; }
307 { ret << "FieldDouble has no space discretization set !\n"; }
309 { ret << "FieldDouble time discretization is : " << timeDiscr()->getStringRepr() << "\n"; }
311 { ret << "FieldDouble has no time discretization set !\n"; }
313 ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
315 ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr();
317 ret << "Mesh support information : No mesh set !\n";
318 std::vector<DataArrayDouble *> arrays;
319 timeDiscr()->getArrays(arrays);
321 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++)
323 ret << "Array #" << arrayId << " :\n__________\n";
325 (*iter)->reprWithoutNameStream(ret);
327 ret << "Array empty !";
333 std::string MEDCouplingFieldDouble::writeVTK(const std::string& fileName, bool isBinary) const
335 std::vector<const MEDCouplingFieldDouble *> fs(1,this);
336 return MEDCouplingFieldDouble::WriteVTK(fileName,fs,isBinary);
340 * This method states if \a this and 'other' are compatibles each other before performing any treatment.
341 * This method is good for methods like : mergeFields.
342 * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields.
344 bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const
346 if(!MEDCouplingField::areCompatibleForMerge(other))
348 const MEDCouplingFieldDouble *otherC(dynamic_cast<const MEDCouplingFieldDouble *>(other));
351 if(!timeDiscr()->areCompatible(otherC->timeDiscr()))
357 * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible,
358 * except that \a this and other can have different number of components.
360 bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const
362 if(!MEDCouplingField::areStrictlyCompatible(other))
364 if(!timeDiscr()->areCompatibleForMeld(other->timeDiscr()))
370 * Permutes values of \a this field according to a given permutation array for cells
371 * renumbering. The underlying mesh is deeply copied and its cells are also permuted.
372 * The number of cells remains the same; for that the permutation array \a old2NewBg
373 * should not contain equal ids.
374 * ** Warning, this method modifies the mesh aggreagated by \a this (by performing a deep copy ) **.
376 * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
377 * to be equal to \a this->getMesh()->getNumberOfCells().
378 * \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation
379 * array, so that its maximal cell id to correspond to (be less than) the number
380 * of cells in mesh. This new array is then used for the renumbering. If \a
381 * check == \c false, \a old2NewBg is used as is, that is less secure as validity
382 * of ids in \a old2NewBg is not checked.
383 * \throw If the mesh is not set.
384 * \throw If the spatial discretization of \a this field is NULL.
385 * \throw If \a check == \c true and \a old2NewBg contains equal ids.
386 * \throw If mesh nature does not allow renumbering (e.g. structured mesh).
388 * \if ENABLE_EXAMPLES
389 * \ref cpp_mcfielddouble_renumberCells "Here is a C++ example".<br>
390 * \ref py_mcfielddouble_renumberCells "Here is a Python example".
393 void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check)
395 renumberCellsWithoutMesh(old2NewBg,check);
396 MCAuto<MEDCouplingMesh> m=_mesh->deepCopy();
397 m->renumberCells(old2NewBg,check);
403 * Permutes values of \a this field according to a given permutation array for cells
404 * renumbering. The underlying mesh is \b not permuted.
405 * The number of cells remains the same; for that the permutation array \a old2NewBg
406 * should not contain equal ids.
407 * This method performs a part of job of renumberCells(). The reasonable use of this
408 * method is only for multi-field instances lying on the same mesh to avoid a
409 * systematic duplication and renumbering of _mesh attribute.
410 * \warning Use this method with a lot of care!
411 * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
412 * to be equal to \a this->getMesh()->getNumberOfCells().
413 * \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation
414 * array, so that its maximal cell id to correspond to (be less than) the number
415 * of cells in mesh. This new array is then used for the renumbering. If \a
416 * check == \c false, \a old2NewBg is used as is, that is less secure as validity
417 * of ids in \a old2NewBg is not checked.
418 * \throw If the mesh is not set.
419 * \throw If the spatial discretization of \a this field is NULL.
420 * \throw If \a check == \c true and \a old2NewBg contains equal ids.
421 * \throw If mesh nature does not allow renumbering (e.g. structured mesh).
423 void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check)
426 throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !");
428 throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !");
430 _type->renumberCells(old2NewBg,check);
431 std::vector<DataArrayDouble *> arrays;
432 timeDiscr()->getArrays(arrays);
433 std::vector<DataArray *> arrays2(arrays.size()); std::copy(arrays.begin(),arrays.end(),arrays2.begin());
434 _type->renumberArraysForCell(_mesh,arrays2,old2NewBg,check);
440 * Permutes values of \a this field according to a given permutation array for node
441 * renumbering. The underlying mesh is deeply copied and its nodes are also permuted.
442 * The number of nodes can change, contrary to renumberCells().
443 * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
444 * to be equal to \a this->getMesh()->getNumberOfNodes().
445 * \param [in] eps - a precision used to compare field values at merged nodes. If
446 * the values differ more than \a eps, an exception is thrown.
447 * \throw If the mesh is not set.
448 * \throw If the spatial discretization of \a this field is NULL.
449 * \throw If \a check == \c true and \a old2NewBg contains equal ids.
450 * \throw If mesh nature does not allow renumbering (e.g. structured mesh).
451 * \throw If values at merged nodes deffer more than \a eps.
453 * \if ENABLE_EXAMPLES
454 * \ref cpp_mcfielddouble_renumberNodes "Here is a C++ example".<br>
455 * \ref py_mcfielddouble_renumberNodes "Here is a Python example".
458 void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps)
460 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
462 throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !");
463 int nbOfNodes=meshC->getNumberOfNodes();
464 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
465 int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1;
466 renumberNodesWithoutMesh(old2NewBg,newNbOfNodes,eps);
467 meshC2->renumberNodes(old2NewBg,newNbOfNodes);
472 * Permutes values of \a this field according to a given permutation array for nodes
473 * renumbering. The underlying mesh is \b not permuted.
474 * The number of nodes can change, contrary to renumberCells().
475 * A given epsilon specifies a threshold of error in case of two nodes are merged but
476 * the difference of values on these nodes are higher than \a eps.
477 * This method performs a part of job of renumberNodes(), excluding node renumbering
478 * in mesh. The reasonable use of this
479 * method is only for multi-field instances lying on the same mesh to avoid a
480 * systematic duplication and renumbering of _mesh attribute.
481 * \warning Use this method with a lot of care!
482 * \warning In case of an exception thrown, the contents of the data array can be
483 * partially modified until the exception occurs.
484 * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is
485 * to be equal to \a this->getMesh()->getNumberOfNodes().
486 * \param [in] newNbOfNodes - a number of nodes in the mesh after renumbering.
487 * \param [in] eps - a precision used to compare field values at merged nodes. If
488 * the values differ more than \a eps, an exception is thrown.
489 * \throw If the mesh is not set.
490 * \throw If the spatial discretization of \a this field is NULL.
491 * \throw If values at merged nodes deffer more than \a eps.
493 void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps)
496 throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !");
497 std::vector<DataArrayDouble *> arrays;
498 timeDiscr()->getArrays(arrays);
499 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
501 _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter);
505 * Returns all tuple ids of \a this scalar field that fit the range [\a vmin,
506 * \a vmax]. This method calls DataArrayDouble::findIdsInRange().
507 * \param [in] vmin - a lower boundary of the range. Tuples with values less than \a
508 * vmin are not included in the result array.
509 * \param [in] vmax - an upper boundary of the range. Tuples with values more than \a
510 * vmax are not included in the result array.
511 * \return DataArrayInt * - a new instance of DataArrayInt holding ids of selected
512 * tuples. The caller is to delete this array using decrRef() as it is no
514 * \throw If the data array is not set.
515 * \throw If \a this->getNumberOfComponents() != 1.
517 DataArrayInt *MEDCouplingFieldDouble::findIdsInRange(double vmin, double vmax) const
520 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::findIdsInRange : no default array set !");
521 return getArray()->findIdsInRange(vmin,vmax);
525 * Builds a newly created field, that the caller will have the responsability to deal with (decrRef()).
526 * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done.
527 * This method returns a restriction of \a this so that only tuples with ids specified in \a part will be contained in the returned field.
528 * Parameter \a part specifies **cell ids whatever the spatial discretization of this** (
529 * \ref MEDCoupling::ON_CELLS "ON_CELLS",
530 * \ref MEDCoupling::ON_NODES "ON_NODES",
531 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT",
532 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE",
533 * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR").
535 * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a part contains following cell ids [3,7,6].
536 * Then the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.<br>
537 * Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh().<br>
538 * Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh().<br>
539 * Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh().
541 * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a part contains following cellIds [3,7,6].
542 * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field
543 * will contain 6 tuples and \a this field will lie on this restricted mesh.
545 * \param [in] part - an array of cell ids to include to the result field.
546 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The caller is to delete this field using decrRef() as it is no more needed.
548 * \if ENABLE_EXAMPLES
549 * \ref cpp_mcfielddouble_subpart1 "Here is a C++ example".<br>
550 * \ref py_mcfielddouble_subpart1 "Here is a Python example".
552 * \sa MEDCouplingFieldDouble::buildSubPartRange
555 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const
558 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !");
559 return buildSubPart(part->begin(),part->end());
563 * Builds a newly created field, that the caller will have the responsability to deal with.
564 * \n This method makes the assumption that \a this field is correctly defined when this method is called (\a this->checkConsistencyLight() returns without any exception thrown), **no check of this will be done**.
565 * \n This method returns a restriction of \a this so that only tuple ids specified in [ \a partBg , \a partEnd ) will be contained in the returned field.
566 * \n Parameter [\a partBg, \a partEnd ) specifies **cell ids whatever the spatial discretization** of \a this (
567 * \ref MEDCoupling::ON_CELLS "ON_CELLS",
568 * \ref MEDCoupling::ON_NODES "ON_NODES",
569 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT",
570 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE",
571 * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR").
573 * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a partBg contains the following cell ids [3,7,6].
574 * Then the returned field will lie on mesh having 3 cells and will contain 3 tuples.
575 *- Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh().
576 *- Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh().
577 *- Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh().
579 * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a partBg contains following cellIds [3,7,6].
580 * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field
581 * will contain 6 tuples and \a this field will lie on this restricted mesh.
583 * \param [in] partBg - start (included) of input range of cell ids to select [ \a partBg, \a partEnd )
584 * \param [in] partEnd - end (not included) of input range of cell ids to select [ \a partBg, \a partEnd )
585 * \return a newly allocated field the caller should deal with.
587 * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \a this->getMesh().
589 * \if ENABLE_EXAMPLES
590 * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."<br>
591 * \ref py_mcfielddouble_subpart1 "Here a Python example."
593 * \sa MEDCoupling::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange
595 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const
598 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !");
599 DataArrayInt *arrSelect;
600 MCAuto<MEDCouplingMesh> m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect);
601 MCAuto<DataArrayInt> arrSelect2(arrSelect);
602 MCAuto<MEDCouplingFieldDouble> ret(clone(false));//quick shallow copy.
603 const MEDCouplingFieldDiscretization *disc=getDiscretization();
605 ret->setDiscretization(MCAuto<MEDCouplingFieldDiscretization>(disc->clonePart(partBg,partEnd)));
607 std::vector<DataArrayDouble *> arrays;
608 timeDiscr()->getArrays(arrays);
609 std::vector<DataArrayDouble *> arrs;
610 std::vector< MCAuto<DataArrayDouble> > arrsSafe;
611 const int *arrSelBg=arrSelect->begin();
612 const int *arrSelEnd=arrSelect->end();
613 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
615 DataArrayDouble *arr=0;
617 arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd);
618 arrs.push_back(arr); arrsSafe.push_back(arr);
620 ret->timeDiscr()->setArrays(arrs,0);
625 * This method is equivalent to MEDCouplingFieldDouble::buildSubPart, the only difference is that the input range of cell ids is
626 * given using a range given \a begin, \a end and \a step to optimize the part computation.
628 * \sa MEDCouplingFieldDouble::buildSubPart
630 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPartRange(int begin, int end, int step) const
633 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !");
634 DataArrayInt *arrSelect;
635 int beginOut,endOut,stepOut;
636 MCAuto<MEDCouplingMesh> m(_type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,arrSelect));
637 MCAuto<DataArrayInt> arrSelect2(arrSelect);
638 MCAuto<MEDCouplingFieldDouble> ret(clone(false));//quick shallow copy.
639 const MEDCouplingFieldDiscretization *disc=getDiscretization();
641 ret->setDiscretization(MCAuto<MEDCouplingFieldDiscretization>(disc->clonePartRange(begin,end,step)));
643 std::vector<DataArrayDouble *> arrays;
644 timeDiscr()->getArrays(arrays);
645 std::vector<DataArrayDouble *> arrs;
646 std::vector< MCAuto<DataArrayDouble> > arrsSafe;
647 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
649 DataArrayDouble *arr=0;
654 const int *arrSelBg=arrSelect->begin();
655 const int *arrSelEnd=arrSelect->end();
656 arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd);
659 arr=(*iter)->selectByTupleIdSafeSlice(beginOut,endOut,stepOut);
661 arrs.push_back(arr); arrsSafe.push_back(arr);
663 ret->timeDiscr()->setArrays(arrs,0);
667 MEDCouplingFieldInt *MEDCouplingFieldDouble::convertToIntField() const
669 MCAuto<MEDCouplingFieldTemplate> tmp(MEDCouplingFieldTemplate::New(*this));
671 double t0(getTime(t1,t2));
672 MCAuto<MEDCouplingFieldInt> ret(MEDCouplingFieldInt::New(*tmp,getTimeDiscretization()));
673 ret->setTime(t0,t1,t2);
676 MCAuto<DataArrayInt> arr(getArray()->convertToIntArr());
682 MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(type,MEDCouplingTimeDiscretization::New(td))
687 * ** WARINING : This method do not deeply copy neither mesh nor spatial discretization. Only a shallow copy (reference) is done for mesh and spatial discretization ! **
689 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingFieldT<double>(ft,MEDCouplingTimeDiscretization::New(td),false)
693 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingFieldT<double>(other,deepCopy)
697 MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingFieldT<double>(type,n,td)
702 * Accumulate values of a given component of \a this field.
703 * \param [in] compId - the index of the component of interest.
704 * \return double - a sum value of *compId*-th component.
705 * \throw If the data array is not set.
706 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
709 double MEDCouplingFieldDouble::accumulate(int compId) const
712 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
713 return getArray()->accumulate(compId);
717 * Accumulates values of each component of \a this array.
718 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
719 * by the caller, that is filled by this method with sum value for each
721 * \throw If the data array is not set.
723 void MEDCouplingFieldDouble::accumulate(double *res) const
726 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
727 getArray()->accumulate(res);
731 * Returns the maximal value within \a this scalar field. Values of all arrays stored
732 * in \a this->_time_discr are checked.
733 * \return double - the maximal value among all values of \a this field.
734 * \throw If \a this->getNumberOfComponents() != 1
735 * \throw If the data array is not set.
736 * \throw If there is an empty data array in \a this field.
738 double MEDCouplingFieldDouble::getMaxValue() const
740 std::vector<DataArrayDouble *> arrays;
741 timeDiscr()->getArrays(arrays);
742 double ret(-std::numeric_limits<double>::max());
743 bool isExistingArr=false;
744 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
750 ret=std::max(ret,(*iter)->getMaxValue(loc));
754 throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !");
759 * Returns the maximal value and all its locations within \a this scalar field.
760 * Only the first of available data arrays is checked.
761 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
762 * tuples holding the maximal value. The caller is to delete it using
763 * decrRef() as it is no more needed.
764 * \return double - the maximal value among all values of the first array of \a this filed.
765 * \throw If \a this->getNumberOfComponents() != 1.
766 * \throw If there is an empty data array in \a this field.
768 double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const
770 std::vector<DataArrayDouble *> arrays;
771 timeDiscr()->getArrays(arrays);
772 double ret(-std::numeric_limits<double>::max());
773 bool isExistingArr=false;
775 MCAuto<DataArrayInt> ret1;
776 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
782 ret=std::max(ret,(*iter)->getMaxValue2(tmp));
783 MCAuto<DataArrayInt> tmpSafe(tmp);
784 if(!((const DataArrayInt *)ret1))
789 throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !");
790 tupleIds=ret1.retn();
795 * Returns the minimal value within \a this scalar field. Values of all arrays stored
796 * in \a this->_time_discr are checked.
797 * \return double - the minimal value among all values of \a this field.
798 * \throw If \a this->getNumberOfComponents() != 1
799 * \throw If the data array is not set.
800 * \throw If there is an empty data array in \a this field.
802 double MEDCouplingFieldDouble::getMinValue() const
804 std::vector<DataArrayDouble *> arrays;
805 timeDiscr()->getArrays(arrays);
806 double ret(std::numeric_limits<double>::max());
807 bool isExistingArr=false;
808 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
814 ret=std::min(ret,(*iter)->getMinValue(loc));
818 throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !");
823 * Returns the minimal value and all its locations within \a this scalar field.
824 * Only the first of available data arrays is checked.
825 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
826 * tuples holding the minimal value. The caller is to delete it using
827 * decrRef() as it is no more needed.
828 * \return double - the minimal value among all values of the first array of \a this filed.
829 * \throw If \a this->getNumberOfComponents() != 1.
830 * \throw If there is an empty data array in \a this field.
832 double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const
834 std::vector<DataArrayDouble *> arrays;
835 timeDiscr()->getArrays(arrays);
836 double ret(-std::numeric_limits<double>::max());
837 bool isExistingArr=false;
839 MCAuto<DataArrayInt> ret1;
840 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
846 ret=std::max(ret,(*iter)->getMinValue2(tmp));
847 MCAuto<DataArrayInt> tmpSafe(tmp);
848 if(!((const DataArrayInt *)ret1))
853 throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !");
854 tupleIds=ret1.retn();
859 * Returns the average value of \a this scalar field.
860 * \return double - the average value over all values of the data array.
861 * \throw If \a this->getNumberOfComponents() != 1
862 * \throw If the data array is not set or it is empty.
864 double MEDCouplingFieldDouble::getAverageValue() const
867 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !");
868 return getArray()->getAverageValue();
872 * This method returns the euclidean norm of \a this field.
874 * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]}
876 * \throw If the data array is not set.
878 double MEDCouplingFieldDouble::norm2() const
881 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !");
882 return getArray()->norm2();
886 * This method returns the max norm of \a this field.
888 * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
890 * \throw If the data array is not set.
892 double MEDCouplingFieldDouble::normMax() const
895 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
896 return getArray()->normMax();
900 * Computes the weighted average of values of each component of \a this field, the weights being the
901 * values returned by buildMeasureField().
902 * \param [out] res - pointer to an array of result sum values, of size at least \a
903 * this->getNumberOfComponents(), that is to be allocated by the caller.
904 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by
905 * buildMeasureField(). It makes this method slower. If you are sure that all
906 * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs ==
907 * \c false to speed up the method.
908 * \throw If the mesh is not set.
909 * \throw If the data array is not set.
911 void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const
914 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
915 MCAuto<MEDCouplingFieldDouble> w=buildMeasureField(isWAbs);
916 double deno=w->getArray()->accumulate(0);
917 MCAuto<DataArrayDouble> arr=getArray()->deepCopy();
918 arr->multiplyEqual(w->getArray());
919 arr->accumulate(res);
920 int nCompo = getArray()->getNumberOfComponents();
921 std::transform(res,res+nCompo,res,std::bind2nd(std::multiplies<double>(),1./deno));
925 * Computes the weighted average of values of a given component of \a this field, the weights being the
926 * values returned by buildMeasureField().
927 * \param [in] compId - an index of the component of interest.
928 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by
929 * buildMeasureField(). It makes this method slower. If you are sure that all
930 * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs ==
931 * \c false to speed up the method.
932 * \throw If the mesh is not set.
933 * \throw If the data array is not set.
934 * \throw If \a compId is not valid.
935 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
937 double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const
939 int nbComps=getArray()->getNumberOfComponents();
940 if(compId<0 || compId>=nbComps)
942 std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
943 throw INTERP_KERNEL::Exception(oss.str());
945 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
946 getWeightedAverageValue(res,isWAbs);
951 * Returns the \c normL1 of values of a given component of \a this field:
953 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
955 * \param [in] compId - an index of the component of interest.
956 * \throw If the mesh is not set.
957 * \throw If the spatial discretization of \a this field is NULL.
958 * \throw If \a compId is not valid.
959 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
961 double MEDCouplingFieldDouble::normL1(int compId) const
964 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1 !");
966 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
967 int nbComps=getArray()->getNumberOfComponents();
968 if(compId<0 || compId>=nbComps)
970 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
971 throw INTERP_KERNEL::Exception(oss.str());
973 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
974 _type->normL1(_mesh,getArray(),res);
979 * Returns the \c normL1 of values of each component of \a this field:
981 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
983 * \param [out] res - pointer to an array of result values, of size at least \a
984 * this->getNumberOfComponents(), that is to be allocated by the caller.
985 * \throw If the mesh is not set.
986 * \throw If the spatial discretization of \a this field is NULL.
988 void MEDCouplingFieldDouble::normL1(double *res) const
991 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
993 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !");
994 _type->normL1(_mesh,getArray(),res);
998 * Returns the \c normL2 of values of a given component of \a this field:
1000 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
1002 * \param [in] compId - an index of the component of interest.
1003 * \throw If the mesh is not set.
1004 * \throw If the spatial discretization of \a this field is NULL.
1005 * \throw If \a compId is not valid.
1006 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
1008 double MEDCouplingFieldDouble::normL2(int compId) const
1011 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
1013 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
1014 int nbComps=getArray()->getNumberOfComponents();
1015 if(compId<0 || compId>=nbComps)
1017 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
1018 throw INTERP_KERNEL::Exception(oss.str());
1020 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
1021 _type->normL2(_mesh,getArray(),res);
1026 * Returns the \c normL2 of values of each component of \a this field:
1028 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
1030 * \param [out] res - pointer to an array of result values, of size at least \a
1031 * this->getNumberOfComponents(), that is to be allocated by the caller.
1032 * \throw If the mesh is not set.
1033 * \throw If the spatial discretization of \a this field is NULL.
1035 void MEDCouplingFieldDouble::normL2(double *res) const
1038 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
1040 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !");
1041 _type->normL2(_mesh,getArray(),res);
1045 * Computes a sum of values of a given component of \a this field multiplied by
1046 * values returned by buildMeasureField().
1047 * This method is useful to check the conservativity of interpolation method.
1048 * \param [in] compId - an index of the component of interest.
1049 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by
1050 * buildMeasureField() that makes this method slower. If a user is sure that all
1051 * cells of the underlying mesh have correct orientation, he can put \a isWAbs ==
1052 * \c false that speeds up this method.
1053 * \throw If the mesh is not set.
1054 * \throw If the data array is not set.
1055 * \throw If \a compId is not valid.
1056 A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ).
1058 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const
1061 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
1063 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral !");
1064 int nbComps=getArray()->getNumberOfComponents();
1065 if(compId<0 || compId>=nbComps)
1067 std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
1068 throw INTERP_KERNEL::Exception(oss.str());
1070 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
1071 _type->integral(_mesh,getArray(),isWAbs,res);
1076 * Computes a sum of values of each component of \a this field multiplied by
1077 * values returned by buildMeasureField().
1078 * This method is useful to check the conservativity of interpolation method.
1079 * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by
1080 * buildMeasureField() that makes this method slower. If a user is sure that all
1081 * cells of the underlying mesh have correct orientation, he can put \a isWAbs ==
1082 * \c false that speeds up this method.
1083 * \param [out] res - pointer to an array of result sum values, of size at least \a
1084 * this->getNumberOfComponents(), that is to be allocated by the caller.
1085 * \throw If the mesh is not set.
1086 * \throw If the data array is not set.
1087 * \throw If the spatial discretization of \a this field is NULL.
1089 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const
1092 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
1094 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral2 !");
1095 _type->integral(_mesh,getArray(),isWAbs,res);
1099 * Returns a value at a given cell of a structured mesh. The cell is specified by its
1101 * \param [in] i - a index of node coordinates array along X axis. The cell is
1102 * located between the i-th and ( i + 1 )-th nodes along X axis.
1103 * \param [in] j - a index of node coordinates array along Y axis. The cell is
1104 * located between the j-th and ( j + 1 )-th nodes along Y axis.
1105 * \param [in] k - a index of node coordinates array along Z axis. The cell is
1106 * located between the k-th and ( k + 1 )-th nodes along Z axis.
1107 * \param [out] res - pointer to an array returning a feild value, of size at least
1108 * \a this->getNumberOfComponents(), that is to be allocated by the caller.
1109 * \throw If the spatial discretization of \a this field is NULL.
1110 * \throw If the mesh is not set.
1111 * \throw If the mesh is not a structured one.
1113 * \if ENABLE_EXAMPLES
1114 * \ref cpp_mcfielddouble_getValueOnPos "Here is a C++ example".<br>
1115 * \ref py_mcfielddouble_getValueOnPos "Here is a Python example".
1118 void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const
1120 const DataArrayDouble *arr=timeDiscr()->getArray();
1122 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
1124 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
1125 _type->getValueOnPos(arr,_mesh,i,j,k,res);
1129 * Returns a value of \a this at a given point using spatial discretization.
1130 * \param [in] spaceLoc - the point of interest.
1131 * \param [out] res - pointer to an array returning a feild value, of size at least
1132 * \a this->getNumberOfComponents(), that is to be allocated by the caller.
1133 * \throw If the spatial discretization of \a this field is NULL.
1134 * \throw If the mesh is not set.
1135 * \throw If \a spaceLoc is out of the spatial discretization.
1137 * \if ENABLE_EXAMPLES
1138 * \ref cpp_mcfielddouble_getValueOn "Here is a C++ example".<br>
1139 * \ref py_mcfielddouble_getValueOn "Here is a Python example".
1142 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const
1144 const DataArrayDouble *arr=timeDiscr()->getArray();
1146 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
1148 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !");
1149 _type->getValueOn(arr,_mesh,spaceLoc,res);
1153 * Returns values of \a this at given points using spatial discretization.
1154 * \param [in] spaceLoc - coordinates of points of interest in full-interlace
1155 * mode. This array is to be of size ( \a nbOfPoints * \a this->getNumberOfComponents() ).
1156 * \param [in] nbOfPoints - number of points of interest.
1157 * \return DataArrayDouble * - a new instance of DataArrayDouble holding field
1158 * values relating to the input points. This array is of size \a nbOfPoints
1159 * tuples per \a this->getNumberOfComponents() components. The caller is to
1160 * delete this array using decrRef() as it is no more needed.
1161 * \throw If the spatial discretization of \a this field is NULL.
1162 * \throw If the mesh is not set.
1163 * \throw If any point in \a spaceLoc is out of the spatial discretization.
1165 * \if ENABLE_EXAMPLES
1166 * \ref cpp_mcfielddouble_getValueOnMulti "Here is a C++ example".<br>
1167 * \ref py_mcfielddouble_getValueOnMulti "Here is a Python example".
1170 DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const
1172 const DataArrayDouble *arr=timeDiscr()->getArray();
1174 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
1176 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnMulti !");
1177 return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
1181 * Returns a value of \a this field at a given point at a given time using spatial discretization.
1182 * If the time is not covered by \a this->_time_discr, an exception is thrown.
1183 * \param [in] spaceLoc - the point of interest.
1184 * \param [in] time - the time of interest.
1185 * \param [out] res - pointer to an array returning a feild value, of size at least
1186 * \a this->getNumberOfComponents(), that is to be allocated by the caller.
1187 * \throw If the spatial discretization of \a this field is NULL.
1188 * \throw If the mesh is not set.
1189 * \throw If \a spaceLoc is out of the spatial discretization.
1190 * \throw If \a time is not covered by \a this->_time_discr.
1192 * \if ENABLE_EXAMPLES
1193 * \ref cpp_mcfielddouble_getValueOn_time "Here is a C++ example".<br>
1194 * \ref py_mcfielddouble_getValueOn_time "Here is a Python example".
1197 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const
1199 std::vector< const DataArrayDouble *> arrs=timeDiscr()->getArraysForTime(time);
1201 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
1203 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOn !");
1204 std::vector<double> res2;
1205 for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
1207 int sz=(int)res2.size();
1208 res2.resize(sz+(*iter)->getNumberOfComponents());
1209 _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]);
1211 timeDiscr()->getValueForTime(time,res2,res);
1215 * Apply a linear function to a given component of \a this field, so that
1216 * a component value <em>(x)</em> becomes \f$ a * x + b \f$.
1217 * \param [in] a - the first coefficient of the function.
1218 * \param [in] b - the second coefficient of the function.
1219 * \param [in] compoId - the index of component to modify.
1220 * \throw If the data array(s) is(are) not set.
1222 void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
1224 timeDiscr()->applyLin(a,b,compoId);
1228 * Apply a linear function to all components of \a this field, so that
1229 * values <em>(x)</em> becomes \f$ a * x + b \f$.
1230 * \param [in] a - the first coefficient of the function.
1231 * \param [in] b - the second coefficient of the function.
1232 * \throw If the data array(s) is(are) not set.
1234 void MEDCouplingFieldDouble::applyLin(double a, double b)
1236 timeDiscr()->applyLin(a,b);
1240 * This method sets \a this to a uniform scalar field with one component.
1241 * All tuples will have the same value 'value'.
1242 * An exception is thrown if no underlying mesh is defined.
1244 MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value)
1247 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
1249 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform operator = !");
1250 int nbOfTuple=_type->getNumberOfTuples(_mesh);
1251 timeDiscr()->setOrCreateUniformValueOnAllComponents(nbOfTuple,value);
1256 * Creates data array(s) of \a this field by using a C function for value generation.
1257 * \param [in] nbOfComp - the number of components for \a this field to have.
1258 * \param [in] func - the function used to compute values of \a this field.
1259 * This function is to compute a field value basing on coordinates of value
1261 * \throw If the mesh is not set.
1262 * \throw If \a func returns \c false.
1263 * \throw If the spatial discretization of \a this field is NULL.
1265 * \if ENABLE_EXAMPLES
1266 * \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example".
1269 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func)
1272 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1274 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
1275 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1276 timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
1280 * Creates data array(s) of \a this field by using a function for value generation.<br>
1281 * The function is applied to coordinates of value location points. For example, if
1282 * \a this field is on cells, the function is applied to cell barycenters.
1283 * For more info on supported expressions that can be used in the function, see \ref
1284 * MEDCouplingArrayApplyFuncExpr. <br>
1285 * The function can include arbitrary named variables
1286 * (e.g. "x","y" or "va44") to refer to components of point coordinates. Names of
1287 * variables are sorted in \b alphabetical \b order to associate a variable name with a
1288 * component. For example, in the expression "2*x+z", "x" stands for the component #0
1289 * and "z" stands for the component #1 (\b not #2)!<br>
1290 * In a general case, a value resulting from the function evaluation is assigned to all
1291 * components of a field value. But there is a possibility to have its own expression for
1292 * each component within one function. For this purpose, there are predefined variable
1293 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1294 * the component #0 etc). A factor of such a variable is added to the
1295 * corresponding component only.<br>
1296 * For example, \a nbOfComp == 4, coordinates of a 3D point are (1.,3.,7.), then
1297 * - "2*x + z" produces (5.,5.,5.,5.)
1298 * - "2*x + 0*y + z" produces (9.,9.,9.,9.)
1299 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1300 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1302 * \param [in] nbOfComp - the number of components for \a this field to have.
1303 * \param [in] func - the function used to compute values of \a this field.
1304 * This function is used to compute a field value basing on coordinates of value
1305 * location point. For example, if \a this field is on cells, the function
1306 * is applied to cell barycenters.
1307 * \throw If the mesh is not set.
1308 * \throw If the spatial discretization of \a this field is NULL.
1309 * \throw If computing \a func fails.
1311 * \if ENABLE_EXAMPLES
1312 * \ref cpp_mcfielddouble_fillFromAnalytic "Here is a C++ example".<br>
1313 * \ref py_mcfielddouble_fillFromAnalytic "Here is a Python example".
1316 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func)
1319 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1321 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !");
1322 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1323 timeDiscr()->fillFromAnalytic(loc,nbOfComp,func);
1327 * Creates data array(s) of \a this field by using a function for value generation.<br>
1328 * The function is applied to coordinates of value location points. For example, if
1329 * \a this field is on cells, the function is applied to cell barycenters.<br>
1330 * This method differs from
1331 * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()"
1332 * by the way how variable
1333 * names, used in the function, are associated with components of coordinates of field
1334 * location points; here, a variable name corresponding to a component is retrieved from
1335 * a corresponding node coordinates array (where it is set via
1336 * DataArrayDouble::setInfoOnComponent()).<br>
1337 * For more info on supported expressions that can be used in the function, see \ref
1338 * MEDCouplingArrayApplyFuncExpr. <br>
1339 * In a general case, a value resulting from the function evaluation is assigned to all
1340 * components of a field value. But there is a possibility to have its own expression for
1341 * each component within one function. For this purpose, there are predefined variable
1342 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1343 * the component #0 etc). A factor of such a variable is added to the
1344 * corresponding component only.<br>
1345 * For example, \a nbOfComp == 4, names of spatial components are "x", "y" and "z",
1346 * coordinates of a 3D point are (1.,3.,7.), then
1347 * - "2*x + z" produces (9.,9.,9.,9.)
1348 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1349 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1351 * \param [in] nbOfComp - the number of components for \a this field to have.
1352 * \param [in] func - the function used to compute values of \a this field.
1353 * This function is used to compute a field value basing on coordinates of value
1354 * location point. For example, if \a this field is on cells, the function
1355 * is applied to cell barycenters.
1356 * \throw If the mesh is not set.
1357 * \throw If the spatial discretization of \a this field is NULL.
1358 * \throw If computing \a func fails.
1360 * \if ENABLE_EXAMPLES
1361 * \ref cpp_mcfielddouble_fillFromAnalytic2 "Here is a C++ example".<br>
1362 * \ref py_mcfielddouble_fillFromAnalytic2 "Here is a Python example".
1365 void MEDCouplingFieldDouble::fillFromAnalyticCompo(int nbOfComp, const std::string& func)
1368 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
1370 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticCompo !");
1371 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1372 timeDiscr()->fillFromAnalyticCompo(loc,nbOfComp,func);
1376 * Creates data array(s) of \a this field by using a function for value generation.<br>
1377 * The function is applied to coordinates of value location points. For example, if
1378 * \a this field is on cells, the function is applied to cell barycenters.<br>
1379 * This method differs from
1380 * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()"
1381 * by the way how variable
1382 * names, used in the function, are associated with components of coordinates of field
1383 * location points; 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 * spatial components are given in \a varsOrder: ["x", "y","z"], coordinates of a
1395 * 3D point 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 used to compute a field value basing on coordinates of value
1403 * location point. For example, if \a this field is on cells, the function
1404 * is applied to cell barycenters.
1405 * \throw If the mesh is not set.
1406 * \throw If the spatial discretization of \a this field is NULL.
1407 * \throw If computing \a func fails.
1409 * \if ENABLE_EXAMPLES
1410 * \ref cpp_mcfielddouble_fillFromAnalytic3 "Here is a C++ example".<br>
1411 * \ref py_mcfielddouble_fillFromAnalytic3 "Here is a Python example".
1414 void MEDCouplingFieldDouble::fillFromAnalyticNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1417 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !");
1419 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticNamedCompo !");
1420 MCAuto<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1421 timeDiscr()->fillFromAnalyticNamedCompo(loc,nbOfComp,varsOrder,func);
1425 * Modifies values of \a this field by applying a C function to each tuple of all
1427 * \param [in] nbOfComp - the number of components for \a this field to have.
1428 * \param [in] func - the function used to compute values of \a this field.
1429 * This function is to compute a field value basing on a current field value.
1430 * \throw If \a func returns \c false.
1432 * \if ENABLE_EXAMPLES
1433 * \ref cpp_mcfielddouble_applyFunc_c_func "Here is a C++ example".
1436 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
1438 timeDiscr()->applyFunc(nbOfComp,func);
1442 * Fill \a this field with a given value.<br>
1443 * This method is a specialization of other overloaded methods. When \a nbOfComp == 1
1444 * this method is equivalent to MEDCoupling::MEDCouplingFieldDouble::operator=().
1445 * \param [in] nbOfComp - the number of components for \a this field to have.
1446 * \param [in] val - the value to assign to every atomic value of \a this field.
1447 * \throw If the spatial discretization of \a this field is NULL.
1448 * \throw If the mesh is not set.
1450 * \if ENABLE_EXAMPLES
1451 * \ref cpp_mcfielddouble_applyFunc_val "Here is a C++ example".<br>
1452 * \ref py_mcfielddouble_applyFunc_val "Here is a Python example".
1455 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
1458 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
1460 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform applyFunc !");
1461 int nbOfTuple=_type->getNumberOfTuples(_mesh);
1462 timeDiscr()->setUniformValue(nbOfTuple,nbOfComp,val);
1466 * Modifies values of \a this field by applying a function to each tuple of all
1468 * For more info on supported expressions that can be used in the function, see \ref
1469 * MEDCouplingArrayApplyFuncExpr. <br>
1470 * The function can include arbitrary named variables
1471 * (e.g. "x","y" or "va44") to refer to components of a field value. Names of
1472 * variables are sorted in \b alphabetical \b order to associate a variable name with a
1473 * component. For example, in the expression "2*x+z", "x" stands for the component #0
1474 * and "z" stands for the component #1 (\b not #2)!<br>
1475 * In a general case, a value resulting from the function evaluation is assigned to all
1476 * components of a field value. But there is a possibility to have its own expression for
1477 * each component within one function. For this purpose, there are predefined variable
1478 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1479 * the component #0 etc). A factor of such a variable is added to the
1480 * corresponding component only.<br>
1481 * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then
1482 * - "2*x + z" produces (5.,5.,5.,5.)
1483 * - "2*x + 0*y + z" produces (9.,9.,9.,9.)
1484 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1485 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1487 * \param [in] nbOfComp - the number of components for \a this field to have.
1488 * \param [in] func - the function used to compute values of \a this field.
1489 * This function is to compute a field value basing on a current field value.
1490 * \throw If computing \a func fails.
1492 * \if ENABLE_EXAMPLES
1493 * \ref cpp_mcfielddouble_applyFunc "Here is a C++ example".<br>
1494 * \ref py_mcfielddouble_applyFunc "Here is a Python example".
1497 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func)
1499 timeDiscr()->applyFunc(nbOfComp,func);
1504 * Modifies values of \a this field by applying a function to each tuple of all
1506 * For more info on supported expressions that can be used in the function, see \ref
1507 * MEDCouplingArrayApplyFuncExpr. <br>
1508 * This method differs from
1509 * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()"
1510 * by the way how variable
1511 * names, used in the function, are associated with components of field values;
1512 * here, a variable name corresponding to a component is retrieved from
1513 * component information of an array (where it is set via
1514 * DataArrayDouble::setInfoOnComponent()).<br>
1515 * In a general case, a value resulting from the function evaluation is assigned to all
1516 * components of a field value. But there is a possibility to have its own expression for
1517 * each component within one function. For this purpose, there are predefined variable
1518 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1519 * the component #0 etc). A factor of such a variable is added to the
1520 * corresponding component only.<br>
1521 * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then
1522 * - "2*x + z" produces (5.,5.,5.,5.)
1523 * - "2*x + 0*y + z" produces (9.,9.,9.,9.)
1524 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.)
1525 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.)
1527 * \param [in] nbOfComp - the number of components for \a this field to have.
1528 * \param [in] func - the function used to compute values of \a this field.
1529 * This function is to compute a new field value basing on a current field value.
1530 * \throw If computing \a func fails.
1532 * \if ENABLE_EXAMPLES
1533 * \ref cpp_mcfielddouble_applyFunc2 "Here is a C++ example".<br>
1534 * \ref py_mcfielddouble_applyFunc2 "Here is a Python example".
1537 void MEDCouplingFieldDouble::applyFuncCompo(int nbOfComp, const std::string& func)
1539 timeDiscr()->applyFuncCompo(nbOfComp,func);
1543 * Modifies values of \a this field by applying a function to each tuple of all
1545 * This method differs from
1546 * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()"
1547 * by the way how variable
1548 * names, used in the function, are associated with components of field values;
1549 * here, a component index of a variable is defined by a
1550 * rank of the variable within the input array \a varsOrder.<br>
1551 * For more info on supported expressions that can be used in the function, see \ref
1552 * MEDCouplingArrayApplyFuncExpr.
1553 * In a general case, a value resulting from the function evaluation is assigned to all
1554 * components of a field value. But there is a possibility to have its own expression for
1555 * each component within one function. For this purpose, there are predefined variable
1556 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1557 * the component #0 etc). A factor of such a variable is added to the
1558 * corresponding component only.<br>
1559 * For example, \a nbOfComp == 4, names of
1560 * components are given in \a varsOrder: ["x", "y","z"], components of a
1561 * 3D vector are (1.,3.,7.), then
1562 * - "2*x + z" produces (9.,9.,9.,9.)
1563 * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.)
1564 * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.)
1566 * \param [in] nbOfComp - the number of components for \a this field to have.
1567 * \param [in] func - the function used to compute values of \a this field.
1568 * This function is to compute a new field value basing on a current field value.
1569 * \throw If computing \a func fails.
1571 * \if ENABLE_EXAMPLES
1572 * \ref cpp_mcfielddouble_applyFunc3 "Here is a C++ example".<br>
1573 * \ref py_mcfielddouble_applyFunc3 "Here is a Python example".
1576 void MEDCouplingFieldDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func)
1578 timeDiscr()->applyFuncNamedCompo(nbOfComp,varsOrder,func);
1582 * Modifies values of \a this field by applying a function to each atomic value of all
1583 * data arrays. The function computes a new single value basing on an old single value.
1584 * For more info on supported expressions that can be used in the function, see \ref
1585 * MEDCouplingArrayApplyFuncExpr. <br>
1586 * The function can include **only one** arbitrary named variable
1587 * (e.g. "x","y" or "va44") to refer to a field atomic value. <br>
1588 * In a general case, a value resulting from the function evaluation is assigned to
1589 * a single field value. But there is a possibility to have its own expression for
1590 * each component within one function. For this purpose, there are predefined variable
1591 * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to
1592 * the component #0 etc). A factor of such a variable is added to the
1593 * corresponding component only.<br>
1594 * For example, components of a field value are (1.,3.,7.), then
1595 * - "2*x - 1" produces (1.,5.,13.)
1596 * - "2*x*IVec + (x+3)*KVec" produces (2.,0.,10.)
1597 * - "2*x*IVec + (x+3)*KVec + 1" produces (3.,1.,11.)
1599 * \param [in] func - the function used to compute values of \a this field.
1600 * This function is to compute a field value basing on a current field value.
1601 * \throw If computing \a func fails.
1603 * \if ENABLE_EXAMPLES
1604 * \ref cpp_mcfielddouble_applyFunc_same_nb_comp "Here is a C++ example".<br>
1605 * \ref py_mcfielddouble_applyFunc_same_nb_comp "Here is a Python example".
1608 void MEDCouplingFieldDouble::applyFunc(const std::string& func)
1610 timeDiscr()->applyFunc(func);
1614 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1615 * The field will contain exactly the same number of components after the call.
1616 * Use is not warranted for the moment !
1618 void MEDCouplingFieldDouble::applyFuncFast32(const std::string& func)
1620 timeDiscr()->applyFuncFast32(func);
1624 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1625 * The field will contain exactly the same number of components after the call.
1626 * Use is not warranted for the moment !
1628 void MEDCouplingFieldDouble::applyFuncFast64(const std::string& func)
1630 timeDiscr()->applyFuncFast64(func);
1634 * Returns number of components in the data array. For more info on the data arrays,
1636 * \return int - the number of components in the data array.
1637 * \throw If the data array is not set.
1639 std::size_t MEDCouplingFieldDouble::getNumberOfComponents() const
1642 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
1643 return getArray()->getNumberOfComponents();
1647 * Use MEDCouplingField::getNumberOfTuplesExpected instead of this method. This method will be removed soon, because it is
1648 * confusing compared to getNumberOfComponents() and getNumberOfValues() behaviour.
1650 * Returns number of tuples in \a this field, that depends on
1651 * - the number of entities in the underlying mesh
1652 * - \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field (e.g. number
1653 * of Gauss points if \a this->getTypeOfField() ==
1654 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT").
1656 * The returned value does \b not \b depend on the number of tuples in the data array
1657 * (which has to be equal to the returned value), \b contrary to
1658 * getNumberOfComponents() and getNumberOfValues() that retrieve information from the
1659 * data array (Sorry, it is confusing !).
1660 * So \b this \b method \b behaves \b exactly \b as MEDCouplingField::getNumberOfTuplesExpected \b method.
1662 * \warning No checkConsistencyLight() is done here.
1663 * For more info on the data arrays, see \ref arrays.
1664 * \return int - the number of tuples.
1665 * \throw If the mesh is not set.
1666 * \throw If the spatial discretization of \a this field is NULL.
1667 * \throw If the spatial discretization is not fully defined.
1668 * \sa MEDCouplingField::getNumberOfTuplesExpected
1670 std::size_t MEDCouplingFieldDouble::getNumberOfTuples() const
1673 throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
1675 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getNumberOfTuples !");
1676 return _type->getNumberOfTuples(_mesh);
1680 * Returns number of atomic double values in the data array of \a this field.
1681 * For more info on the data arrays, see \ref arrays.
1682 * \return int - (number of tuples) * (number of components) of the
1684 * \throw If the data array is not set.
1686 std::size_t MEDCouplingFieldDouble::getNumberOfValues() const
1689 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
1690 return getArray()->getNbOfElems();
1694 * Sets own modification time by the most recently modified element of data (the mesh,
1695 * the data array etc). For more info, see \ref MEDCouplingTimeLabelPage.
1697 void MEDCouplingFieldDouble::updateTime() const
1699 MEDCouplingField::updateTime();
1700 updateTimeWith(*timeDiscr());
1703 std::size_t MEDCouplingFieldDouble::getHeapMemorySizeWithoutChildren() const
1705 return MEDCouplingField::getHeapMemorySizeWithoutChildren();
1708 std::vector<const BigMemoryObject *> MEDCouplingFieldDouble::getDirectChildrenWithNull() const
1710 std::vector<const BigMemoryObject *> ret(MEDCouplingField::getDirectChildrenWithNull());
1713 std::vector<const BigMemoryObject *> ret2(timeDiscr()->getDirectChildrenWithNull());
1714 ret.insert(ret.end(),ret2.begin(),ret2.end());
1720 * Returns a value of \a this field of type either
1721 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or
1722 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE".
1723 * \param [in] cellId - an id of cell of interest.
1724 * \param [in] nodeIdInCell - a node index within the cell.
1725 * \param [in] compoId - an index of component.
1726 * \return double - the field value corresponding to the specified parameters.
1727 * \throw If the data array is not set.
1728 * \throw If the mesh is not set.
1729 * \throw If the spatial discretization of \a this field is NULL.
1730 * \throw If \a this field if of type other than
1731 * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or
1732 * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE".
1734 double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
1737 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getIJK !");
1738 return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
1742 * Sets the data array.
1743 * \param [in] array - the data array holding values of \a this field. It's size
1744 * should correspond to the mesh and
1745 * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1746 * (see getNumberOfTuples()), but this size is not checked here.
1748 //void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
1751 * Sets the data array holding values corresponding to an end of a time interval
1752 * for which \a this field is defined.
1753 * \param [in] array - the data array holding values of \a this field. It's size
1754 * should correspond to the mesh and
1755 * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1756 * (see getNumberOfTuples()), but this size is not checked here.
1758 //void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
1761 * Sets all data arrays needed to define the field values.
1762 * \param [in] arrs - a vector of DataArrayDouble's holding values of \a this
1763 * field. Size of each array should correspond to the mesh and
1764 * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field
1765 * (see getNumberOfTuples()), but this size is not checked here.
1766 * \throw If number of arrays in \a arrs does not correspond to type of
1767 * \ref MEDCouplingTemporalDisc "temporal discretization" of \a this field.
1769 //void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs)
1771 void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
1774 timeDiscr()->getTinySerializationStrInformation(tinyInfo);
1775 tinyInfo.push_back(_name);
1776 tinyInfo.push_back(_desc);
1777 tinyInfo.push_back(getTimeUnit());
1781 * This method retrieves some critical values to resize and prepare remote instance.
1782 * The first two elements returned in tinyInfo correspond to the parameters to give in constructor.
1783 * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1785 void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
1788 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationIntInformation !");
1790 tinyInfo.push_back((int)_type->getEnum());
1791 tinyInfo.push_back((int)timeDiscr()->getEnum());
1792 tinyInfo.push_back((int)_nature);
1793 timeDiscr()->getTinySerializationIntInformation(tinyInfo);
1794 std::vector<int> tinyInfo2;
1795 _type->getTinySerializationIntInformation(tinyInfo2);
1796 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1797 tinyInfo.push_back((int)tinyInfo2.size());
1801 * This method retrieves some critical values to resize and prepare remote instance.
1802 * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1804 void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
1807 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationDbleInformation !");
1809 timeDiscr()->getTinySerializationDbleInformation(tinyInfo);
1810 std::vector<double> tinyInfo2;
1811 _type->getTinySerializationDbleInformation(tinyInfo2);
1812 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1813 tinyInfo.push_back((int)tinyInfo2.size());//very bad, lack of time to improve it
1817 * This method has to be called to the new instance filled by CORBA, MPI, File...
1818 * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied.
1819 * @param dataInt out parameter. If not null the pointer is already owned by \a this after the call of this method. In this case no decrRef must be applied.
1820 * @param arrays out parameter is a vector resized to the right size. The pointers in the vector is already owned by \a this after the call of this method.
1821 * No decrRef must be applied to every instances in returned vector.
1822 * \sa checkForUnserialization
1824 void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays)
1827 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !");
1829 std::vector<int> tinyInfoITmp(tinyInfoI);
1830 int sz=tinyInfoITmp.back();
1831 tinyInfoITmp.pop_back();
1832 std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz);
1833 std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end());
1834 timeDiscr()->resizeForUnserialization(tinyInfoI2,arrays);
1835 std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end());
1836 _type->resizeForUnserialization(tinyInfoITmp3,dataInt);
1840 * This method is extremely close to resizeForUnserialization except that here the arrays in \a dataInt and in \a arrays are attached in \a this
1841 * after having checked that size is correct. This method is used in python pickeling context to avoid copy of data.
1842 * \sa resizeForUnserialization
1844 void MEDCouplingFieldDouble::checkForUnserialization(const std::vector<int>& tinyInfoI, const DataArrayInt *dataInt, const std::vector<DataArrayDouble *>& arrays)
1847 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !");
1848 std::vector<int> tinyInfoITmp(tinyInfoI);
1849 int sz=tinyInfoITmp.back();
1850 tinyInfoITmp.pop_back();
1851 std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz);
1852 std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end());
1853 timeDiscr()->checkForUnserialization(tinyInfoI2,arrays);
1854 std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end());
1855 _type->checkForUnserialization(tinyInfoITmp3,dataInt);
1858 void MEDCouplingFieldDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS)
1861 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform finishUnserialization !");
1862 std::vector<int> tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end());
1864 std::vector<double> tmp(tinyInfoD);
1865 int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it
1867 std::vector<double> tmp1(tmp.begin(),tmp.end()-sz);
1868 std::vector<double> tmp2(tmp.end()-sz,tmp.end());
1870 timeDiscr()->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS);
1871 _nature=(NatureOfField)tinyInfoI[2];
1872 _type->finishUnserialization(tmp2);
1873 int nbOfElemS=(int)tinyInfoS.size();
1874 _name=tinyInfoS[nbOfElemS-3];
1875 _desc=tinyInfoS[nbOfElemS-2];
1876 setTimeUnit(tinyInfoS[nbOfElemS-1]);
1880 * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller.
1881 * The values returned must be consulted only in readonly mode.
1883 void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) const
1886 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform serialize !");
1887 timeDiscr()->getArrays(arrays);
1888 _type->getSerializationIntArray(dataInt);
1892 * Tries to set an \a other mesh as the support of \a this field. An attempt fails, if
1893 * a current and the \a other meshes are different with use of specified equality
1894 * criteria, and then an exception is thrown.
1895 * \param [in] other - the mesh to use as the field support if this mesh can be
1896 * considered equal to the current mesh.
1897 * \param [in] levOfCheck - defines equality criteria used for mesh comparison. For
1898 * it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which
1899 * is used for mesh comparison.
1900 * \param [in] precOnMesh - a precision used to compare nodes of the two meshes.
1901 * It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith().
1902 * \param [in] eps - a precision used at node renumbering (if needed) to compare field
1903 * values at merged nodes. If the values differ more than \a eps, an
1904 * exception is thrown.
1905 * \throw If the mesh is not set.
1906 * \throw If \a other == NULL.
1907 * \throw If any of the meshes is not well defined.
1908 * \throw If the two meshes do not match.
1909 * \throw If field values at merged nodes (if any) deffer more than \a eps.
1911 * \if ENABLE_EXAMPLES
1912 * \ref cpp_mcfielddouble_changeUnderlyingMesh "Here is a C++ example".<br>
1913 * \ref py_mcfielddouble_changeUnderlyingMesh "Here is a Python example".
1916 void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps)
1918 if(_mesh==0 || other==0)
1919 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
1920 DataArrayInt *cellCor=0,*nodeCor=0;
1921 other->checkGeoEquivalWith(_mesh,levOfCheck,precOnMesh,cellCor,nodeCor);
1922 MCAuto<DataArrayInt> cellCor2(cellCor),nodeCor2(nodeCor);
1924 renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
1926 renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps);
1931 * Subtracts another field from \a this one in case when the two fields have different
1932 * supporting meshes. The subtraction is performed provided that the tho meshes can be
1933 * considered equal with use of specified equality criteria, else an exception is thrown.
1934 * If the meshes match, the mesh of \a f is set to \a this field (\a this is permuted if
1935 * necessary) and field values are subtracted. No interpolation is done here, only an
1936 * analysis of two underlying mesh is done to see if the meshes are geometrically
1938 * The job of this method consists in calling
1939 * \a this->changeUnderlyingMesh() with \a f->getMesh() as the first parameter, and then
1940 * \a this -= \a f.<br>
1941 * This method requires that \a f and \a this are coherent (checkConsistencyLight()) and that \a f
1942 * and \a this are coherent for a merge.<br>
1943 * "DM" in the method name stands for "different meshes".
1944 * \param [in] f - the field to subtract from this.
1945 * \param [in] levOfCheck - defines equality criteria used for mesh comparison. For
1946 * it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which
1947 * is used for mesh comparison.
1948 * \param [in] precOnMesh - a precision used to compare nodes of the two meshes.
1949 * It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith().
1950 * \param [in] eps - a precision used at node renumbering (if needed) to compare field
1951 * values at merged nodes. If the values differ more than \a eps, an
1952 * exception is thrown.
1953 * \throw If \a f == NULL.
1954 * \throw If any of the meshes is not set or is not well defined.
1955 * \throw If the two meshes do not match.
1956 * \throw If the two fields are not coherent for merge.
1957 * \throw If field values at merged nodes (if any) deffer more than \a eps.
1959 * \if ENABLE_EXAMPLES
1960 * \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".<br>
1961 * \ref py_mcfielddouble_substractInPlaceDM "Here is a Python example".
1963 * \sa changeUnderlyingMesh().
1965 void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps)
1967 checkConsistencyLight();
1969 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : input field is NULL !");
1970 f->checkConsistencyLight();
1971 if(!areCompatibleForMerge(f))
1972 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : Fields are not compatible ; unable to apply mergeFields on them !");
1973 changeUnderlyingMesh(f->getMesh(),levOfCheck,precOnMesh,eps);
1978 * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the
1979 * underlying mesh is replaced by a new mesh instance where the coincident nodes are merged.
1980 * \param [in] eps - a precision used to compare nodes of the two meshes.
1981 * \param [in] epsOnVals - a precision used to compare field
1982 * values at merged nodes. If the values differ more than \a epsOnVals, an
1983 * exception is thrown.
1984 * \return bool - \c true if some nodes have been merged and hence \a this field lies
1986 * \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
1987 * \throw If the mesh is not well defined.
1988 * \throw If the spatial discretization of \a this field is NULL.
1989 * \throw If the data array is not set.
1990 * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
1992 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals)
1994 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1996 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1998 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes !");
1999 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
2002 MCAuto<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2);
2003 if(!ret)//no nodes have been merged.
2005 std::vector<DataArrayDouble *> arrays;
2006 timeDiscr()->getArrays(arrays);
2007 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
2009 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
2015 * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the
2016 * underlying mesh is replaced by a new mesh instance where the coincident nodes are
2018 * In contrast to mergeNodes(), location of merged nodes is changed to be at their barycenter.
2019 * \param [in] eps - a precision used to compare nodes of the two meshes.
2020 * \param [in] epsOnVals - a precision used to compare field
2021 * values at merged nodes. If the values differ more than \a epsOnVals, an
2022 * exception is thrown.
2023 * \return bool - \c true if some nodes have been merged and hence \a this field lies
2025 * \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
2026 * \throw If the mesh is not well defined.
2027 * \throw If the spatial discretization of \a this field is NULL.
2028 * \throw If the data array is not set.
2029 * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
2031 bool MEDCouplingFieldDouble::mergeNodesCenter(double eps, double epsOnVals)
2033 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
2035 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
2037 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodesCenter !");
2038 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
2041 MCAuto<DataArrayInt> arr=meshC2->mergeNodesCenter(eps,ret,ret2);
2042 if(!ret)//no nodes have been merged.
2044 std::vector<DataArrayDouble *> arrays;
2045 timeDiscr()->getArrays(arrays);
2046 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
2048 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
2054 * Removes from the underlying mesh nodes not used in any cell. If some nodes are
2055 * removed, the underlying mesh is replaced by a new mesh instance where the unused
2056 * nodes are removed.<br>
2057 * \param [in] epsOnVals - a precision used to compare field
2058 * values at merged nodes. If the values differ more than \a epsOnVals, an
2059 * exception is thrown.
2060 * \return bool - \c true if some nodes have been removed and hence \a this field lies
2062 * \throw If the mesh is of type not inheriting from MEDCouplingPointSet.
2063 * \throw If the mesh is not well defined.
2064 * \throw If the spatial discretization of \a this field is NULL.
2065 * \throw If the data array is not set.
2066 * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals.
2068 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals)
2070 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
2072 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
2074 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipCoords !");
2075 MCAuto<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCopy());
2076 int oldNbOfNodes=meshC2->getNumberOfNodes();
2077 MCAuto<DataArrayInt> arr=meshC2->zipCoordsTraducer();
2078 if(meshC2->getNumberOfNodes()!=oldNbOfNodes)
2080 std::vector<DataArrayDouble *> arrays;
2081 timeDiscr()->getArrays(arrays);
2082 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
2084 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
2092 * Removes duplicates of cells from the understanding mesh. If some cells are
2093 * removed, the underlying mesh is replaced by a new mesh instance where the cells
2094 * duplicates are removed.<br>
2095 * \param [in] compType - specifies a cell comparison technique. Meaning of its
2096 * valid values [0,1,2] is explained in the description of
2097 * MEDCouplingPointSet::zipConnectivityTraducer() which is called by this method.
2098 * \param [in] epsOnVals - a precision used to compare field
2099 * values at merged cells. If the values differ more than \a epsOnVals, an
2100 * exception is thrown.
2101 * \return bool - \c true if some cells have been removed and hence \a this field lies
2103 * \throw If the mesh is not an instance of MEDCouplingUMesh.
2104 * \throw If the mesh is not well defined.
2105 * \throw If the spatial discretization of \a this field is NULL.
2106 * \throw If the data array is not set.
2107 * \throw If field values at merged cells (if any) deffer more than \a epsOnVals.
2109 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals)
2111 const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
2113 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipConnectivity : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
2115 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipConnectivity !");
2116 MCAuto<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCopy());
2117 int oldNbOfCells=meshC2->getNumberOfCells();
2118 MCAuto<DataArrayInt> arr=meshC2->zipConnectivityTraducer(compType);
2119 if(meshC2->getNumberOfCells()!=oldNbOfCells)
2121 std::vector<DataArrayDouble *> arrays;
2122 timeDiscr()->getArrays(arrays);
2123 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
2125 _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter);
2133 * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists.
2134 * For the moment, this method is implemented for fields on cells.
2136 * \return a newly allocated field double containing the result that the user should deallocate.
2138 MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const
2140 const MEDCouplingMesh *mesh=getMesh();
2142 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !");
2143 if(getTypeOfField()!=ON_CELLS)
2144 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !");
2145 const MCAuto<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
2146 MCAuto<MEDCouplingFieldDouble> ret(clone(false));
2147 ret->setMesh(umesh);
2148 DataArrayInt *cellIds=0;
2149 MCAuto<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds);
2150 MCAuto<DataArrayInt> cellIds2=cellIds;
2151 ret->setMesh(mesh2);
2152 MCAuto<DataArrayInt> tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end());
2153 std::vector<DataArrayDouble *> arrays;
2154 timeDiscr()->getArrays(arrays);
2156 std::vector<DataArrayDouble *> newArr(arrays.size());
2157 std::vector< MCAuto<DataArrayDouble> > newArr2(arrays.size());
2158 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++)
2162 newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
2163 newArr[i]=newArr2[i];
2166 ret->setArrays(newArr);
2171 * Divides every cell of the underlying mesh into simplices (triangles in 2D and
2172 * tetrahedra in 3D). If some cells are divided, the underlying mesh is replaced by a new
2173 * mesh instance containing the simplices.<br>
2174 * \param [in] policy - specifies a pattern used for splitting. For its description, see
2175 * MEDCouplingUMesh::simplexize().
2176 * \return bool - \c true if some cells have been divided and hence \a this field lies
2178 * \throw If \a policy has an invalid value. For valid values, see the description of
2179 * MEDCouplingUMesh::simplexize().
2180 * \throw If MEDCouplingMesh::simplexize() is not applicable to the underlying mesh.
2181 * \throw If the mesh is not well defined.
2182 * \throw If the spatial discretization of \a this field is NULL.
2183 * \throw If the data array is not set.
2185 bool MEDCouplingFieldDouble::simplexize(int policy)
2188 throw INTERP_KERNEL::Exception("No underlying mesh on this field to perform simplexize !");
2190 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform simplexize !");
2191 int oldNbOfCells=_mesh->getNumberOfCells();
2192 MCAuto<MEDCouplingMesh> meshC2(_mesh->deepCopy());
2193 MCAuto<DataArrayInt> arr=meshC2->simplexize(policy);
2194 int newNbOfCells=meshC2->getNumberOfCells();
2195 if(oldNbOfCells==newNbOfCells)
2197 std::vector<DataArrayDouble *> arrays;
2198 timeDiscr()->getArrays(arrays);
2199 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
2201 _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter);
2207 * 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.
2208 * Each Gauss points in \a this is replaced by a polygon or polyhedron cell with associated region following Voronoi algorithm.
2210 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoize(double eps) const
2212 checkConsistencyLight();
2213 const MEDCouplingMesh *mesh(getMesh());
2214 INTERP_KERNEL::AutoCppPtr<Voronizer> vor;
2215 int meshDim(mesh->getMeshDimension()),spaceDim(mesh->getSpaceDimension());
2216 if(meshDim==2 && (spaceDim==2 || spaceDim==3))
2217 vor=new Voronizer2D;
2218 else if(meshDim==3 && spaceDim==3)
2219 vor=new Voronizer3D;
2221 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize : only 2D, 3D surf, and 3D are supported for the moment !");
2222 return voronoizeGen(vor,eps);
2226 * 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.
2227 * Finaly \a this is also expected to be consistent.
2228 * In these conditions this method returns a newly created field (to be dealed by the caller).
2229 * The returned field will also 3 compo vector field be on nodes lying on the same mesh than \a this.
2231 * 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.
2232 * \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.
2234 * \sa DataArrayDouble::fromCartToCylGiven
2236 MEDCouplingFieldDouble *MEDCouplingFieldDouble::computeVectorFieldCyl(const double center[3], const double vect[3]) const
2238 checkConsistencyLight();
2239 const DataArrayDouble *coo(getMesh()->getDirectAccessOfCoordsArrIfInStructure());
2240 MEDCouplingTimeDiscretization *td(timeDiscr()->computeVectorFieldCyl(coo,center,vect));
2241 td->copyTinyAttrFrom(*timeDiscr());
2242 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2243 ret->setMesh(getMesh());
2244 ret->setName(getName());
2249 * Creates a new MEDCouplingFieldDouble filled with the doubly contracted product of
2250 * every tensor of \a this 6-componental field.
2251 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2252 * each tuple is calculated from the tuple <em>(t)</em> of \a this field as
2253 * follows: \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2254 * This new field lies on the same mesh as \a this one. The caller is to delete
2255 * this field using decrRef() as it is no more needed.
2256 * \throw If \a this->getNumberOfComponents() != 6.
2257 * \throw If the spatial discretization of \a this field is NULL.
2259 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const
2262 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform doublyContractedProduct !");
2263 MEDCouplingTimeDiscretization *td(timeDiscr()->doublyContractedProduct());
2264 td->copyTinyAttrFrom(*timeDiscr());
2265 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2266 ret->setName("DoublyContractedProduct");
2267 ret->setMesh(getMesh());
2272 * Creates a new MEDCouplingFieldDouble filled with the determinant of a square
2273 * matrix defined by every tuple of \a this field, having either 4, 6 or 9 components.
2274 * The case of 6 components corresponds to that of the upper triangular matrix.
2275 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose
2276 * each tuple is the determinant of matrix of the corresponding tuple of \a this
2277 * field. This new field lies on the same mesh as \a this one. The caller is to
2278 * delete this field using decrRef() as it is no more needed.
2279 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2280 * \throw If the spatial discretization of \a this field is NULL.
2282 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const
2285 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform determinant !");
2286 MEDCouplingTimeDiscretization *td(timeDiscr()->determinant());
2287 td->copyTinyAttrFrom(*timeDiscr());
2288 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2289 ret->setName("Determinant");
2290 ret->setMesh(getMesh());
2296 * Creates a new MEDCouplingFieldDouble with 3 components filled with 3 eigenvalues of
2297 * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2298 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2299 * having 3 components, whose each tuple contains the eigenvalues of the matrix of
2300 * corresponding tuple of \a this field. This new field lies on the same mesh as
2301 * \a this one. The caller is to delete this field using decrRef() as it is no
2303 * \throw If \a this->getNumberOfComponents() != 6.
2304 * \throw If the spatial discretization of \a this field is NULL.
2306 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const
2309 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenValues !");
2310 MEDCouplingTimeDiscretization *td(timeDiscr()->eigenValues());
2311 td->copyTinyAttrFrom(*timeDiscr());
2312 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2313 ret->setName("EigenValues");
2314 ret->setMesh(getMesh());
2319 * Creates a new MEDCouplingFieldDouble with 9 components filled with 3 eigenvectors of
2320 * an upper triangular matrix defined by every tuple of \a this 6-componental field.
2321 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2322 * having 9 components, whose each tuple contains the eigenvectors of the matrix of
2323 * corresponding tuple of \a this field. This new field lies on the same mesh as
2324 * \a this one. The caller is to delete this field using decrRef() as it is no
2326 * \throw If \a this->getNumberOfComponents() != 6.
2327 * \throw If the spatial discretization of \a this field is NULL.
2329 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const
2332 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenVectors !");
2333 MEDCouplingTimeDiscretization *td(timeDiscr()->eigenVectors());
2334 td->copyTinyAttrFrom(*timeDiscr());
2335 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2336 ret->setName("EigenVectors");
2337 ret->setMesh(getMesh());
2342 * Creates a new MEDCouplingFieldDouble filled with the inverse matrix of
2343 * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2344 * components. The case of 6 components corresponds to that of the upper triangular
2346 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2347 * having the same number of components as \a this one, whose each tuple
2348 * contains the inverse matrix of the matrix of corresponding tuple of \a this
2349 * field. This new field lies on the same mesh as \a this one. The caller is to
2350 * delete this field using decrRef() as it is no more needed.
2351 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2352 * \throw If the spatial discretization of \a this field is NULL.
2354 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const
2357 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform inverse !");
2358 MEDCouplingTimeDiscretization *td(timeDiscr()->inverse());
2359 td->copyTinyAttrFrom(*timeDiscr());
2360 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2361 ret->setName("Inversion");
2362 ret->setMesh(getMesh());
2367 * Creates a new MEDCouplingFieldDouble filled with the trace of
2368 * a matrix defined by every tuple of \a this field having either 4, 6 or 9
2369 * components. The case of 6 components corresponds to that of the upper triangular
2371 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2372 * having 1 component, whose each tuple is the trace of the matrix of
2373 * corresponding tuple of \a this field.
2374 * This new field lies on the same mesh as \a this one. The caller is to
2375 * delete this field using decrRef() as it is no more needed.
2376 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2377 * \throw If the spatial discretization of \a this field is NULL.
2379 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const
2382 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform trace !");
2383 MEDCouplingTimeDiscretization *td(timeDiscr()->trace());
2384 td->copyTinyAttrFrom(*timeDiscr());
2385 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2386 ret->setName("Trace");
2387 ret->setMesh(getMesh());
2392 * Creates a new MEDCouplingFieldDouble filled with the stress deviator tensor of
2393 * a stress tensor defined by every tuple of \a this 6-componental field.
2394 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2395 * having same number of components and tuples as \a this field,
2396 * whose each tuple contains the stress deviator tensor of the stress tensor of
2397 * corresponding tuple of \a this field. This new field lies on the same mesh as
2398 * \a this one. The caller is to delete this field using decrRef() as it is no
2400 * \throw If \a this->getNumberOfComponents() != 6.
2401 * \throw If the spatial discretization of \a this field is NULL.
2403 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const
2406 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform deviator !");
2407 MEDCouplingTimeDiscretization *td(timeDiscr()->deviator());
2408 td->copyTinyAttrFrom(*timeDiscr());
2409 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2410 ret->setName("Deviator");
2411 ret->setMesh(getMesh());
2416 * Creates a new MEDCouplingFieldDouble filled with the magnitude of
2417 * every vector of \a this field.
2418 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble,
2419 * having one component, whose each tuple is the magnitude of the vector
2420 * of corresponding tuple of \a this field. This new field lies on the
2421 * same mesh as \a this one. The caller is to
2422 * delete this field using decrRef() as it is no more needed.
2423 * \throw If the spatial discretization of \a this field is NULL.
2425 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const
2428 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform magnitude !");
2429 MEDCouplingTimeDiscretization *td(timeDiscr()->magnitude());
2430 td->copyTinyAttrFrom(*timeDiscr());
2431 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2432 ret->setName("Magnitude");
2433 ret->setMesh(getMesh());
2438 * Creates a new scalar MEDCouplingFieldDouble filled with the maximal value among
2439 * values of every tuple of \a this field.
2440 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2441 * This new field lies on the same mesh as \a this one. The caller is to
2442 * delete this field using decrRef() as it is no more needed.
2443 * \throw If the spatial discretization of \a this field is NULL.
2445 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const
2448 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform maxPerTuple !");
2449 MEDCouplingTimeDiscretization *td(timeDiscr()->maxPerTuple());
2450 td->copyTinyAttrFrom(*timeDiscr());
2451 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2452 std::ostringstream oss;
2453 oss << "Max_" << getName();
2454 ret->setName(oss.str());
2455 ret->setMesh(getMesh());
2460 * Changes number of components in \a this field. If \a newNbOfComp is less
2461 * than \a this->getNumberOfComponents() then each tuple
2462 * is truncated to have \a newNbOfComp components, keeping first components. If \a
2463 * newNbOfComp is more than \a this->getNumberOfComponents() then
2464 * each tuple is populated with \a dftValue to have \a newNbOfComp components.
2465 * \param [in] newNbOfComp - number of components for the new field to have.
2466 * \param [in] dftValue - value assigned to new values added to \a this field.
2467 * \throw If \a this is not allocated.
2469 void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue)
2471 timeDiscr()->changeNbOfComponents(newNbOfComp,dftValue);
2475 * Creates a new MEDCouplingFieldDouble composed of selected components of \a this field.
2476 * The new MEDCouplingFieldDouble has the same number of tuples but includes components
2477 * specified by \a compoIds parameter. So that getNbOfElems() of the result field
2478 * can be either less, same or more than \a this->getNumberOfValues().
2479 * \param [in] compoIds - sequence of zero based indices of components to include
2480 * into the new field.
2481 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble that the caller
2482 * is to delete using decrRef() as it is no more needed.
2483 * \throw If a component index (\a i) is not valid:
2484 * \a i < 0 || \a i >= \a this->getNumberOfComponents().
2486 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
2489 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform keepSelectedComponents !");
2490 MEDCouplingTimeDiscretization *td(timeDiscr()->keepSelectedComponents(compoIds));
2491 td->copyTinyAttrFrom(*timeDiscr());
2492 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2493 ret->setName(getName());
2494 ret->setMesh(getMesh());
2500 * Copy all components in a specified order from another field.
2501 * The number of tuples in \a this and the other field can be different.
2502 * \param [in] f - the field to copy data from.
2503 * \param [in] compoIds - sequence of zero based indices of components, data of which is
2505 * \throw If the two fields have different number of data arrays.
2506 * \throw If a data array is set in one of fields and is not set in the other.
2507 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2508 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2510 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds)
2512 timeDiscr()->setSelectedComponents(f->timeDiscr(),compoIds);
2516 * Sorts value within every tuple of \a this field.
2517 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2518 * in descending order.
2519 * \throw If a data array is not allocated.
2521 void MEDCouplingFieldDouble::sortPerTuple(bool asc)
2523 timeDiscr()->sortPerTuple(asc);
2527 * Creates a new MEDCouplingFieldDouble by concatenating two given fields.
2529 * the first field precede values of the second field within the result field.
2530 * \param [in] f1 - the first field.
2531 * \param [in] f2 - the second field.
2532 * \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2533 * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef()
2534 * as it is no more needed.
2535 * \throw If the fields are not compatible for the merge.
2536 * \throw If the spatial discretization of \a f1 is NULL.
2537 * \throw If the time discretization of \a f1 is NULL.
2539 * \if ENABLE_EXAMPLES
2540 * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2541 * \ref py_mcfielddouble_MergeFields "Here is a Python example".
2544 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2546 if(!f1->areCompatibleForMerge(f2))
2547 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
2548 const MEDCouplingMesh *m1(f1->getMesh()),*m2(f2->getMesh());
2549 if(!f1->timeDiscr())
2550 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no time discr of f1 !");
2552 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no spatial discr of f1 !");
2553 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->aggregate(f2->timeDiscr()));
2554 td->copyTinyAttrFrom(*f1->timeDiscr());
2555 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2556 ret->setName(f1->getName());
2557 ret->setDescription(f1->getDescription());
2560 MCAuto<MEDCouplingMesh> m=m1->mergeMyselfWith(m2);
2567 * Creates a new MEDCouplingFieldDouble by concatenating all given fields.
2568 * Values of the *i*-th field precede values of the (*i*+1)-th field within the result.
2569 * If there is only one field in \a a, a deepCopy() (except time information of mesh and
2570 * field) of the field is returned.
2571 * Generally speaking the first field in \a a is used to assign tiny attributes of the
2573 * \param [in] a - a vector of fields (MEDCouplingFieldDouble) to concatenate.
2574 * \return MEDCouplingFieldDouble * - the result field. It is a new instance of
2575 * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef()
2576 * as it is no more needed.
2577 * \throw If \a a is empty.
2578 * \throw If the fields are not compatible for the merge.
2580 * \if ENABLE_EXAMPLES
2581 * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br>
2582 * \ref py_mcfielddouble_MergeFields "Here is a Python example".
2585 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a)
2588 throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !");
2589 std::vector< MCAuto<MEDCouplingUMesh> > ms(a.size());
2590 std::vector< const MEDCouplingUMesh *> ms2(a.size());
2591 std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
2592 std::vector<const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
2593 const MEDCouplingFieldDouble *ref=(*it++);
2595 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of NULL instance in first place of input vector !");
2596 for(;it!=a.end();it++)
2597 if(!ref->areCompatibleForMerge(*it))
2598 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2599 for(int i=0;i<(int)a.size();i++)
2602 { ms[i]=a[i]->getMesh()->buildUnstructured(); ms2[i]=ms[i]; }
2604 { ms[i]=0; ms2[i]=0; }
2605 tds[i]=a[i]->timeDiscr();
2607 MEDCouplingTimeDiscretization *td(tds[0]->aggregate(tds));
2608 td->copyTinyAttrFrom(*(a[0]->timeDiscr()));
2609 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()));
2610 ret->setName(a[0]->getName());
2611 ret->setDescription(a[0]->getDescription());
2614 MCAuto<MEDCouplingUMesh> m(MEDCouplingUMesh::MergeUMeshes(ms2));
2615 m->copyTinyInfoFrom(ms2[0]);
2622 * Creates a new MEDCouplingFieldDouble by concatenating components of two given fields.
2623 * The number of components in the result field is a sum of the number of components of
2624 * given fields. The number of tuples in the result field is same as that of each of given
2626 * Number of tuples in the given fields must be the same.
2627 * \param [in] f1 - a field to include in the result field.
2628 * \param [in] f2 - another field to include in the result field.
2629 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2630 * The caller is to delete this result field using decrRef() as it is no more
2632 * \throw If the fields are not compatible for a meld (areCompatibleForMeld()).
2633 * \throw If any of data arrays is not allocated.
2634 * \throw If \a f1->getNumberOfTuples() != \a f2->getNumberOfTuples()
2636 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2639 throw INTERP_KERNEL::Exception("MeldFields : null input pointer !");
2640 if(!f1->areCompatibleForMeld(f2))
2641 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
2642 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->meld(f2->timeDiscr()));
2643 td->copyTinyAttrFrom(*f1->timeDiscr());
2644 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2645 ret->setMesh(f1->getMesh());
2650 * Returns a new MEDCouplingFieldDouble containing a dot product of two given fields,
2651 * so that the i-th tuple of the result field is a sum of products of j-th components of
2652 * i-th tuples of given fields (\f$ f_i = \sum_{j=1}^n f1_j * f2_j \f$).
2653 * Number of tuples and components in the given fields must be the same.
2654 * \param [in] f1 - a given field.
2655 * \param [in] f2 - another given field.
2656 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2657 * The caller is to delete this result field using decrRef() as it is no more
2659 * \throw If either \a f1 or \a f2 is NULL.
2660 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2661 * differ not only in values.
2663 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2666 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !");
2667 if(!f1->areStrictlyCompatibleForMulDiv(f2))
2668 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them! Check support mesh, and spatial and time discretisation.");
2669 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->dot(f2->timeDiscr()));
2670 td->copyTinyAttrFrom(*f1->timeDiscr());
2671 MEDCouplingFieldDouble *ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2672 ret->setMesh(f1->getMesh());
2677 * Returns a new MEDCouplingFieldDouble containing a cross product of two given fields,
2679 * the i-th tuple of the result field is a 3D vector which is a cross
2680 * product of two vectors defined by the i-th tuples of given fields.
2681 * Number of tuples in the given fields must be the same.
2682 * Number of components in the given fields must be 3.
2683 * \param [in] f1 - a given field.
2684 * \param [in] f2 - another given field.
2685 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2686 * The caller is to delete this result field using decrRef() as it is no more
2688 * \throw If either \a f1 or \a f2 is NULL.
2689 * \throw If \a f1->getNumberOfComponents() != 3
2690 * \throw If \a f2->getNumberOfComponents() != 3
2691 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2692 * differ not only in values.
2694 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2697 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !");
2698 if(!f1->areStrictlyCompatibleForMulDiv(f2))
2699 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation.");
2700 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->crossProduct(f2->timeDiscr()));
2701 td->copyTinyAttrFrom(*f1->timeDiscr());
2702 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2703 ret->setMesh(f1->getMesh());
2708 * Returns a new MEDCouplingFieldDouble containing maximal values of two given fields.
2709 * Number of tuples and components in the given fields must be the same.
2710 * \param [in] f1 - a field to compare values with another one.
2711 * \param [in] f2 - another field to compare values with the first one.
2712 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2713 * The caller is to delete this result field using decrRef() as it is no more
2715 * \throw If either \a f1 or \a f2 is NULL.
2716 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2717 * differ not only in values.
2719 * \if ENABLE_EXAMPLES
2720 * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2721 * \ref py_mcfielddouble_MaxFields "Here is a Python example".
2724 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2727 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MaxFields : input field is NULL !");
2728 if(!f1->areStrictlyCompatible(f2))
2729 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MaxFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2730 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->max(f2->timeDiscr()));
2731 td->copyTinyAttrFrom(*f1->timeDiscr());
2732 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2733 ret->setMesh(f1->getMesh());
2738 * Returns a new MEDCouplingFieldDouble containing minimal values of two given fields.
2739 * Number of tuples and components in the given fields must be the same.
2740 * \param [in] f1 - a field to compare values with another one.
2741 * \param [in] f2 - another field to compare values with the first one.
2742 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2743 * The caller is to delete this result field using decrRef() as it is no more
2745 * \throw If either \a f1 or \a f2 is NULL.
2746 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2747 * differ not only in values.
2749 * \if ENABLE_EXAMPLES
2750 * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br>
2751 * \ref py_mcfielddouble_MaxFields "Here is a Python example".
2754 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2757 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MinFields : input field is NULL !");
2758 if(!f1->areStrictlyCompatible(f2))
2759 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MinFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2760 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->min(f2->timeDiscr()));
2761 td->copyTinyAttrFrom(*f1->timeDiscr());
2762 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2763 ret->setMesh(f1->getMesh());
2768 * Returns a copy of \a this field in which sign of all values is reversed.
2769 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble
2770 * containing the same number of tuples and components as \a this field.
2771 * The caller is to delete this result field using decrRef() as it is no more
2773 * \throw If the spatial discretization of \a this field is NULL.
2774 * \throw If a data array is not allocated.
2776 MEDCouplingFieldDouble *MEDCouplingFieldDouble::negate() const
2779 throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform negate !");
2780 MEDCouplingTimeDiscretization *td(timeDiscr()->negate());
2781 td->copyTinyAttrFrom(*timeDiscr());
2782 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone()));
2783 ret->setMesh(getMesh());
2788 * Returns a new MEDCouplingFieldDouble containing sum values of corresponding values of
2789 * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] + _f2_ [ i, j ] ).
2790 * Number of tuples and components in the given fields must be the same.
2791 * \param [in] f1 - a field to sum up.
2792 * \param [in] f2 - another field to sum up.
2793 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2794 * The caller is to delete this result field using decrRef() as it is no more
2796 * \throw If either \a f1 or \a f2 is NULL.
2797 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2798 * differ not only in values.
2800 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2803 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::AddFields : input field is NULL !");
2804 if(!f1->areStrictlyCompatible(f2))
2805 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply AddFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2806 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->add(f2->timeDiscr()));
2807 td->copyTinyAttrFrom(*f1->timeDiscr());
2808 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2809 ret->setMesh(f1->getMesh());
2814 * Adds values of another MEDCouplingFieldDouble to values of \a this one
2815 * ( _this_ [ i, j ] += _other_ [ i, j ] ) using DataArrayDouble::addEqual().
2816 * The two fields must have same number of tuples, components and same underlying mesh.
2817 * \param [in] other - the field to add to \a this one.
2818 * \return const MEDCouplingFieldDouble & - a reference to \a this field.
2819 * \throw If \a other is NULL.
2820 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2821 * differ not only in values.
2823 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other)
2825 if(!areStrictlyCompatible(&other))
2826 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply += on them! Check support mesh, field nature, and spatial and time discretisation.");
2827 timeDiscr()->addEqual(other.timeDiscr());
2832 * Returns a new MEDCouplingFieldDouble containing subtraction of corresponding values of
2833 * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] - _f2_ [ i, j ] ).
2834 * Number of tuples and components in the given fields must be the same.
2835 * \param [in] f1 - a field to subtract from.
2836 * \param [in] f2 - a field to subtract.
2837 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
2838 * The caller is to delete this result field using decrRef() as it is no more
2840 * \throw If either \a f1 or \a f2 is NULL.
2841 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2842 * differ not only in values.
2844 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2847 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::SubstractFields : input field is NULL !");
2848 if(!f1->areStrictlyCompatible(f2))
2849 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply SubstractFields on them! Check support mesh, field nature, and spatial and time discretisation.");
2850 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->substract(f2->timeDiscr()));
2851 td->copyTinyAttrFrom(*f1->timeDiscr());
2852 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()));
2853 ret->setMesh(f1->getMesh());
2858 * Subtract values of another MEDCouplingFieldDouble from values of \a this one
2859 * ( _this_ [ i, j ] -= _other_ [ i, j ] ) using DataArrayDouble::substractEqual().
2860 * The two fields must have same number of tuples, components and same underlying mesh.
2861 * \param [in] other - the field to subtract from \a this one.
2862 * \return const MEDCouplingFieldDouble & - a reference to \a this field.
2863 * \throw If \a other is NULL.
2864 * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they
2865 * differ not only in values.
2867 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other)
2869 if(!areStrictlyCompatible(&other))
2870 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply -= on them! Check support mesh, field nature, and spatial and time discretisation.");
2871 timeDiscr()->substractEqual(other.timeDiscr());
2876 * Returns a new MEDCouplingFieldDouble containing product values of
2877 * two given fields. There are 2 valid cases.
2878 * 1. The fields have same number of tuples and components. Then each value of
2879 * the result field (_f_) is a product of the corresponding values of _f1_ and
2880 * _f2_, i.e. _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, j ].
2881 * 2. The fields have same number of tuples and one field, say _f2_, has one
2883 * _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, 0 ].
2885 * The two fields must have same number of tuples and same underlying mesh.
2886 * \param [in] f1 - a factor field.
2887 * \param [in] f2 - another factor field.
2888 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2889 * The caller is to delete this result field using decrRef() as it is no more
2891 * \throw If either \a f1 or \a f2 is NULL.
2892 * \throw If the fields are not compatible for multiplication (areCompatibleForMul()),
2893 * i.e. they differ not only in values and possibly number of components.
2895 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2898 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MultiplyFields : input field is NULL !");
2899 if(!f1->areCompatibleForMul(f2))
2900 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MultiplyFields on them! Check support mesh, and spatial and time discretisation.");
2901 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->multiply(f2->timeDiscr()));
2902 td->copyTinyAttrFrom(*f1->timeDiscr());
2903 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2904 ret->setMesh(f1->getMesh());
2909 * Multiply values of another MEDCouplingFieldDouble to values of \a this one
2910 * using DataArrayDouble::multiplyEqual().
2911 * The two fields must have same number of tuples and same underlying mesh.
2912 * There are 2 valid cases.
2913 * 1. The fields have same number of components. Then each value of
2914 * \a other is multiplied to the corresponding value of \a this field, i.e.
2915 * _this_ [ i, j ] *= _other_ [ i, j ].
2916 * 2. The _other_ field has one component. Then
2917 * _this_ [ i, j ] *= _other_ [ i, 0 ].
2919 * The two fields must have same number of tuples and same underlying mesh.
2920 * \param [in] other - an field to multiply to \a this one.
2921 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2922 * The caller is to delete this result field using decrRef() as it is no more
2924 * \throw If \a other is NULL.
2925 * \throw If the fields are not strictly compatible for multiplication
2926 * (areCompatibleForMul()),
2927 * i.e. they differ not only in values and possibly in number of components.
2929 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other)
2931 if(!areCompatibleForMul(&other))
2932 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply *= on them! Check support mesh, and spatial and time discretisation.");
2933 timeDiscr()->multiplyEqual(other.timeDiscr());
2939 * Returns a new MEDCouplingFieldDouble containing division of two given fields.
2940 * There are 2 valid cases.
2941 * 1. The fields have same number of tuples and components. Then each value of
2942 * the result field (_f_) is a division of the corresponding values of \a f1 and
2943 * \a f2, i.e. _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, j ].
2944 * 2. The fields have same number of tuples and _f2_ has one component. Then
2945 * _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, 0 ].
2947 * \param [in] f1 - a numerator field.
2948 * \param [in] f2 - a denominator field.
2949 * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
2950 * The caller is to delete this result field using decrRef() as it is no more
2952 * \throw If either \a f1 or \a f2 is NULL.
2953 * \throw If the fields are not compatible for division (areCompatibleForDiv()),
2954 * i.e. they differ not only in values and possibly in number of components.
2956 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
2959 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DivideFields : input field is NULL !");
2960 if(!f1->areCompatibleForDiv(f2))
2961 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DivideFields on them! Check support mesh, and spatial and time discretisation.");
2962 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->divide(f2->timeDiscr()));
2963 td->copyTinyAttrFrom(*f1->timeDiscr());
2964 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
2965 ret->setMesh(f1->getMesh());
2970 * Divide values of \a this field by values of another MEDCouplingFieldDouble
2971 * using DataArrayDouble::divideEqual().
2972 * The two fields must have same number of tuples and same underlying mesh.
2973 * There are 2 valid cases.
2974 * 1. The fields have same number of components. Then each value of
2975 * \a this field is divided by the corresponding value of \a other one, i.e.
2976 * _this_ [ i, j ] /= _other_ [ i, j ].
2977 * 2. The \a other field has one component. Then
2978 * _this_ [ i, j ] /= _other_ [ i, 0 ].
2980 * \warning No check of division by zero is performed!
2981 * \param [in] other - an field to divide \a this one by.
2982 * \throw If \a other is NULL.
2983 * \throw If the fields are not compatible for division (areCompatibleForDiv()),
2984 * i.e. they differ not only in values and possibly in number of components.
2986 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other)
2988 if(!areCompatibleForDiv(&other))
2989 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply /= on them! Check support mesh, and spatial and time discretisation.");
2990 timeDiscr()->divideEqual(other.timeDiscr());
2996 * Directly called by MEDCouplingFieldDouble::operator^.
2998 * \sa MEDCouplingFieldDouble::operator^
3000 MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
3003 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::PowFields : input field is NULL !");
3004 if(!f1->areCompatibleForMul(f2))
3005 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply PowFields on them! Check support mesh, and spatial and time discretisation.");
3006 MEDCouplingTimeDiscretization *td(f1->timeDiscr()->pow(f2->timeDiscr()));
3007 td->copyTinyAttrFrom(*f1->timeDiscr());
3008 MCAuto<MEDCouplingFieldDouble> ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()));
3009 ret->setMesh(f1->getMesh());
3014 * Directly call MEDCouplingFieldDouble::PowFields static method.
3016 * \sa MEDCouplingFieldDouble::PowFields
3018 MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const
3020 return PowFields(this,&other);
3023 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other)
3025 if(!areCompatibleForDiv(&other))
3026 throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply ^= on them! Check support mesh, and spatial and time discretisation.");
3027 timeDiscr()->powEqual(other.timeDiscr());
3033 * Writes the field series \a fs and the mesh the fields lie on in the VTK file \a fileName.
3034 * If \a fs is empty no file is written.
3035 * The result file is valid provided that no exception is thrown.
3036 * \warning All the fields must be named and lie on the same non NULL mesh.
3037 * \param [in] fileName - the name of a VTK file to write in.
3038 * \param [in] fs - the fields to write.
3039 * \param [in] isBinary - specifies the VTK format of the written file. By default true (Binary mode)
3040 * \throw If \a fs[ 0 ] == NULL.
3041 * \throw If the fields lie not on the same mesh.
3042 * \throw If the mesh is not set.
3043 * \throw If any of the fields has no name.
3045 * \if ENABLE_EXAMPLES
3046 * \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".<br>
3047 * \ref py_mcfielddouble_WriteVTK "Here is a Python example".
3050 std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector<const MEDCouplingFieldDouble *>& fs, bool isBinary)
3053 return std::string();
3054 std::size_t nfs=fs.size();
3056 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field is NULL !");
3057 const MEDCouplingMesh *m=fs[0]->getMesh();
3059 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field lies on NULL mesh !");
3060 for(std::size_t i=1;i<nfs;i++)
3061 if(fs[i]->getMesh()!=m)
3062 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.");
3064 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !");
3065 std::string ret(m->getVTKFileNameOf(fileName));
3066 MCAuto<DataArrayByte> byteArr;
3068 { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); }
3069 std::ostringstream coss,noss;
3070 for(std::size_t i=0;i<nfs;i++)
3072 const MEDCouplingFieldDouble *cur=fs[i];
3073 std::string name(cur->getName());
3076 std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
3077 throw INTERP_KERNEL::Exception(oss.str());
3079 TypeOfField typ=cur->getTypeOfField();
3081 cur->getArray()->writeVTK(coss,8,cur->getName(),byteArr);
3082 else if(typ==ON_NODES)
3083 cur->getArray()->writeVTK(noss,8,cur->getName(),byteArr);
3085 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : only node and cell fields supported for the moment !");
3087 m->writeVTKAdvanced(ret,coss.str(),noss.str(),byteArr);
3091 MCAuto<MEDCouplingFieldDouble> MEDCouplingFieldDouble::voronoizeGen(const Voronizer *vor, double eps) const
3093 checkConsistencyLight();
3095 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoizeGen : null pointer !");
3096 const MEDCouplingMesh *inpMesh(getMesh());
3097 int nbCells(inpMesh->getNumberOfCells());
3098 const MEDCouplingFieldDiscretization *disc(getDiscretization());
3099 const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
3101 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : Not a ON_GAUSS_PT field");
3102 int nbLocs(disc2->getNbOfGaussLocalization());
3103 std::vector< MCAuto<MEDCouplingUMesh> > cells(nbCells);
3104 for(int i=0;i<nbLocs;i++)
3106 const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(i));
3107 if(gl.getDimension()!=vor->getDimension())
3108 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : not a 2D one !");
3109 MCAuto<MEDCouplingUMesh> mesh(gl.buildRefCell());
3110 const std::vector<double>& coo(gl.getGaussCoords());
3111 MCAuto<DataArrayDouble> coo2(DataArrayDouble::NewFromStdVector(coo));
3112 coo2->rearrange(vor->getDimension());
3114 MCAuto<MEDCouplingUMesh> coo3(MEDCouplingUMesh::Build0DMeshFromCoords(coo2));
3116 MCAuto<MEDCouplingUMesh> vorCellsForCurDisc(vor->doIt(mesh,coo2,eps));
3117 std::vector<int> ids;
3118 MCAuto<DataArrayDouble> ptsInReal;
3119 disc2->getCellIdsHavingGaussLocalization(i,ids);
3121 MCAuto<MEDCouplingUMesh> tmp4(inpMesh->buildUnstructured());
3122 MCAuto<MEDCouplingUMesh> subMesh(tmp4->buildPartOfMySelf(&ids[0],&ids[0]+ids.size()));
3123 ptsInReal=gl.localizePtsInRefCooForEachCell(vorCellsForCurDisc->getCoords(),subMesh);
3125 int nbPtsPerCell(vorCellsForCurDisc->getNumberOfNodes());
3126 for(std::size_t i=0;i<ids.size();i++)
3128 MCAuto<MEDCouplingUMesh> elt(vorCellsForCurDisc->clone(false));
3129 MCAuto<DataArrayDouble> coo(ptsInReal->selectByTupleIdSafeSlice(i*nbPtsPerCell,(i+1)*nbPtsPerCell,1));
3130 elt->setCoords(coo);
3134 std::vector< const MEDCouplingUMesh * > cellsPtr(VecAutoToVecOfCstPt(cells));
3135 MCAuto<MEDCouplingUMesh> outMesh(MEDCouplingUMesh::MergeUMeshes(cellsPtr));
3136 MCAuto<MEDCouplingFieldDouble> onCells(MEDCouplingFieldDouble::New(ON_CELLS));
3137 onCells->setMesh(outMesh);
3139 MCAuto<DataArrayDouble> arr(getArray()->deepCopy());
3140 onCells->setArray(arr);
3142 onCells->setTimeUnit(getTimeUnit());
3145 double a(getTime(b,c));
3146 onCells->setTime(a,b,c);
3148 onCells->setName(getName());
3152 MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr()
3154 MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
3157 MEDCouplingTimeDiscretization *retc(dynamic_cast<MEDCouplingTimeDiscretization *>(ret));
3159 throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");
3163 const MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr() const
3165 const MEDCouplingTimeDiscretizationTemplate<double> *ret(_time_discr);
3168 const MEDCouplingTimeDiscretization *retc(dynamic_cast<const MEDCouplingTimeDiscretization *>(ret));
3170 throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !");