1 // Copyright (C) 2007-2013 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.
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 "MEDCouplingUMesh.hxx"
24 #include "MEDCouplingTimeDiscretization.hxx"
25 #include "MEDCouplingFieldDiscretization.hxx"
26 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
27 #include "MEDCouplingNatureOfField.hxx"
29 #include "InterpKernelAutoPtr.hxx"
36 using namespace ParaMEDMEM;
39 * Creates a new instance of MEDCouplingFieldDouble of given type. The caller is responsable for the returned field.
41 * \param [in] type type of spatial discretization of a created field (\ref ParaMEDMEM::ON_CELLS "ON_CELLS", \ref ParaMEDMEM::ON_NODES "ON_NODES", \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE", \ref ParaMEDMEM::ON_NODES_KR "ON_NODES_KR").
42 * \param [in] td type of time discretization of a created field (\ref ParaMEDMEM::NO_TIME "NO_TIME", \ref ParaMEDMEM::ONE_TIME "ONE_TIME", \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
44 * \return a newly allocated field the caller should deal with.
46 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td)
48 return new MEDCouplingFieldDouble(type,td);
52 * Creates a new instance of MEDCouplingFieldDouble of given type. The caller is responsable for the returned field.
53 * ** WARINING : This method do not deeply copy neither mesh nor spatial discretization. Only a shallow copy (reference) is done for mesh and spatial discretization ! **
55 * \param [in] ft \ref MEDCouplingFieldTemplatesPage "field template" defining its spatial discretization and supporting mesh.
56 * \param [in] td type of time discretization of a created field (\ref ParaMEDMEM::NO_TIME "NO_TIME", \ref ParaMEDMEM::ONE_TIME "ONE_TIME", \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL")
58 * \return a newly allocated field the caller should deal with.
60 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td)
62 return new MEDCouplingFieldDouble(ft,td);
66 * Sets time \a unit of \a this field.
68 * \param [in] unit \a unit (string) in which time is measured.
70 void MEDCouplingFieldDouble::setTimeUnit(const char *unit)
72 _time_discr->setTimeUnit(unit);
76 * Returns a time unit of \a this field.
78 * \return a string describing units in which time is measured.
80 const char *MEDCouplingFieldDouble::getTimeUnit() const
82 return _time_discr->getTimeUnit();
86 * This method if possible the time information (time unit, time iteration, time unit and time value) with its support
87 * that is to say its mesh.
89 * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is
92 void MEDCouplingFieldDouble::synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception)
94 _time_discr->synchronizeTimeWith(_mesh);
98 * This method performs a copy of \a this **without any copy of the underlying mesh** ( see warning section of this method).
99 * The copy of arrays is deep if \b recDeepCpy equals to true, no copy of arrays is done if \b recDeepCpy equals to false.
101 * \c clone(false) is rather dedicated for advanced users that want to limit the amount of memory.
103 * It allows the user to perform methods
104 * MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields with \a this and the returned field.
106 * \warning The \b underlying \b mesh of the returned field is \b always the same (same pointer) than \a this **whatever the value** of \a recDeepCpy parameter.
107 * If the user wants to duplicated deeply the underlying mesh he should call MEDCouplingFieldDouble::cloneWithMesh method or MEDCouplingFieldDouble::deepCpy instead.
109 * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied or only attached to the returned field.
110 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
111 * \sa ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
113 MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
115 return new MEDCouplingFieldDouble(*this,recDeepCpy);
119 * This method behaves exactly like MEDCouplingFieldDouble::clone method **except that here the underlying mesh is systematically **
120 * (whatever the value of the input parameter \a recDeepCpy) **deeply duplicated**.
122 * The result of \c cloneWithMesh(true) is exactly the same than calling \ref MEDCouplingFieldDouble::deepCpy "deepCpy".
124 * So the resulting field of this call cannot be called with \a this with the following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ...
125 * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
127 * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied or only attached to the returned field.
128 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
129 * \sa ParaMEDMEM::MEDCouplingFieldDouble::clone(bool recDeepCpy) const
131 MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
133 MEDCouplingFieldDouble *ret=clone(recDeepCpy);
136 MEDCouplingMesh *mCpy=_mesh->deepCpy();
144 * This method performs a deepCpy of \a this (**mesh included**)!
145 * So the resulting field of this call cannot be called with \a this with following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ...
146 * To avoid deep copying the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
147 * This method is exactly equivalent to MEDCouplingFieldDouble::cloneWithMesh called with parameter true.
149 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
150 * \sa ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
152 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const
154 return cloneWithMesh(true);
160 * \param [in] td type of time discretization of a created field (\ref ParaMEDMEM::NO_TIME "NO_TIME", \ref ParaMEDMEM::ONE_TIME "ONE_TIME", \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL").
161 * \param [in] deepCopy specifies if underlying arrays in \a this should be copied or only attached to the returned field.
162 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
164 * \ref cpp_mcfielddouble_buildnewtimereprfromthis "Here a C++ example."
166 * \ref py_mcfielddouble_buildnewtimereprfromthis "Here a Python example."
167 * \sa ParaMEDMEM::MEDCouplingFieldDouble::clone(bool recDeepCpy) const
169 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const
171 MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(td,deepCopy);
172 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),tdo,_type->clone());
173 ret->setMesh(getMesh());
174 ret->setName(getName());
175 ret->setDescription(getDescription());
180 * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason).
182 void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingField *other) throw(INTERP_KERNEL::Exception)
184 MEDCouplingField::copyTinyStringsFrom(other);
185 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
188 _time_discr->copyTinyStringsFrom(*otherC->_time_discr);
193 * Copy only times, order, iteration from other. The underlying mesh is not impacted by this method.
194 * Arrays are not impacted too.
196 void MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
200 _time_discr->copyTinyAttrFrom(*other->_time_discr);
205 void MEDCouplingFieldDouble::copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
207 copyTinyStringsFrom(other);
208 copyTinyAttrFrom(other);
211 std::string MEDCouplingFieldDouble::simpleRepr() const
213 std::ostringstream ret;
214 ret << "FieldDouble with name : \"" << getName() << "\"\n";
215 ret << "Description of field is : \"" << getDescription() << "\"\n";
216 ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
217 ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
218 ret << "FieldDouble nature of field is : " << MEDCouplingNatureOfField::GetRepr(_nature) << "\n";
221 int nbOfCompo=getArray()->getNumberOfComponents();
222 ret << "FieldDouble default array has " << nbOfCompo << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
223 ret << "FieldDouble default array has following info on components : ";
224 for(int i=0;i<nbOfCompo;i++)
225 ret << "\"" << getArray()->getInfoOnComponent(i) << "\" ";
229 ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr();
231 ret << "Mesh support information : No mesh set !\n";
235 std::string MEDCouplingFieldDouble::advancedRepr() const
237 std::ostringstream ret;
238 ret << "FieldDouble with name : \"" << getName() << "\"\n";
239 ret << "Description of field is : \"" << getDescription() << "\"\n";
240 ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
241 ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
243 ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
245 ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr();
247 ret << "Mesh support information : No mesh set !\n";
248 std::vector<DataArrayDouble *> arrays;
249 _time_discr->getArrays(arrays);
251 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++)
253 ret << "Array #" << arrayId << " :\n__________\n";
255 (*iter)->reprWithoutNameStream(ret);
257 ret << "Array empty !";
263 void MEDCouplingFieldDouble::writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception)
265 std::vector<const MEDCouplingFieldDouble *> fs(1,this);
266 MEDCouplingFieldDouble::WriteVTK(fileName,fs);
269 bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception)
272 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::isEqualIfNotWhy : other instance is NULL !");
273 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
276 reason="field given in input is not castable in MEDCouplingFieldDouble !";
279 if(!MEDCouplingField::isEqualIfNotWhy(other,meshPrec,valsPrec,reason))
281 if(!_time_discr->isEqualIfNotWhy(otherC->_time_discr,valsPrec,reason))
283 reason.insert(0,"In FieldDouble time discretizations differ :");
289 bool MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const
291 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
294 if(!MEDCouplingField::isEqualWithoutConsideringStr(other,meshPrec,valsPrec))
296 if(!_time_discr->isEqualWithoutConsideringStr(otherC->_time_discr,valsPrec))
302 * This method states if \a this and 'other' are compatibles each other before performing any treatment.
303 * This method is good for methods like : mergeFields.
304 * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields.
306 bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const
308 if(!MEDCouplingField::areCompatibleForMerge(other))
310 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
313 if(!_time_discr->areCompatible(otherC->_time_discr))
319 * This method is more strict than MEDCouplingField::areCompatibleForMerge method.
320 * This method is used for operation on fields to operate a first check before attempting operation.
322 bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const
325 if(!MEDCouplingField::areStrictlyCompatible(other))
327 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
330 if(!_time_discr->areStrictlyCompatible(otherC->_time_discr,tmp))
336 * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
337 * number of components between \a this and 'other' can be different here (for operator*).
339 bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const
341 if(!MEDCouplingField::areStrictlyCompatible(other))
343 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
346 if(!_time_discr->areStrictlyCompatibleForMul(otherC->_time_discr))
352 * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
353 * number of components between \a this and 'other' can be different here (for operator/).
355 bool MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const
357 if(!MEDCouplingField::areStrictlyCompatible(other))
359 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
362 if(!_time_discr->areStrictlyCompatibleForDiv(otherC->_time_discr))
368 * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible,
369 * except that \a this and other can have different number of components.
371 bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const
373 if(!MEDCouplingField::areStrictlyCompatible(other))
375 if(!_time_discr->areCompatibleForMeld(other->_time_discr))
381 * This method performs a clone of mesh and a renumbering of underlying cells of it. The number of cells remains the same.
382 * The values of field are impacted in consequence to have the same geometrical field.
384 void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
386 renumberCellsWithoutMesh(old2NewBg,check);
387 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_mesh->deepCpy();
388 m->renumberCells(old2NewBg,check);
394 * \b WARNING : use this method with lot of care !
395 * This method performs half job of MEDCouplingFieldDouble::renumberCells. That is to say no permutation of cells is done on underlying mesh.
396 * That is to say, the field content is changed by this method. The reason of this method is only for multi-field instances lying on the same mesh to
397 * avoid a systematic duplication and renumbering of _mesh attribute.
399 void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
402 throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !");
404 _type->renumberCells(old2NewBg,check);
405 std::vector<DataArrayDouble *> arrays;
406 _time_discr->getArrays(arrays);
407 _type->renumberArraysForCell(_mesh,arrays,old2NewBg,check);
413 * This method performs a clone of mesh and a renumbering of underlying nodes of it. The number of nodes remains not compulsory the same as renumberCells method.
414 * The values of field are impacted in consequence to have the same geometrical field.
416 void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception)
418 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
420 throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !");
421 int nbOfNodes=meshC->getNumberOfNodes();
422 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
423 int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1;
424 renumberNodesWithoutMesh(old2NewBg,newNbOfNodes);
425 meshC2->renumberNodes(old2NewBg,newNbOfNodes);
430 * \b WARNING : use this method with lot of care !
431 * This method performs half job of MEDCouplingFieldDouble::renumberNodes. That is to say no permutation of cells is done on underlying mesh.
432 * That is to say, the field content is changed by this method.
434 void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps) throw(INTERP_KERNEL::Exception)
436 std::vector<DataArrayDouble *> arrays;
437 _time_discr->getArrays(arrays);
438 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
440 _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter);
444 * This method makes the assumption that the default array is set. If not an exception will be thrown.
445 * This method is usable only if the default array has exactly one component. If not an exception will be thrown too.
446 * This method returns all tuples ids that fit the range [vmin,vmax].
447 * The caller has the responsability of the returned DataArrayInt.
449 DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
452 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getIdsInRange : no default array set !");
453 return getArray()->getIdsInRange(vmin,vmax);
457 * Builds a newly created field, that the caller will have the responsability to deal with (decrRef).
458 * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done.
459 * This method returns a restriction of \a this so that only tuples id specified in 'part' will be contained in returned field.
460 * Parameter 'part' specifies \b cell \b ids \b whatever \b the \b spatial \b discretization of \a this (ON_CELLS, ON_NODES, ON_GAUSS_PT, ON_GAUSS_NE)
462 * If \a this is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6].
463 * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
464 * Tuple#0 of return field will refer to the cell#0 of returned mesh. The cell #0 of returned mesh will be equal to the cell#3 of 'this->getMesh()'
465 * Tuple#1 of return field will refer to the cell#1 of returned mesh. The cell #1 of returned mesh will be equal to the cell#7 of 'this->getMesh()'
466 * Tuple#2 of return field will refer to the cell#2 of returned mesh. The cell #2 of returned mesh will be equal to the cell#6 of 'this->getMesh()'
468 * If \a this is field on node lying on a mesh that have 10 cells and 11 nodes for example. If part contains following cellIds [3,7,6].
469 * \a this is currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, the returned field,
470 * will contain 6 tuples and this field will lie on this restricted mesh.
472 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception)
475 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !");
476 const int *start=part->getConstPointer();
477 const int *end=start+part->getNbOfElems();
478 return buildSubPart(start,end);
482 * Builds a newly created field, that the caller will have the responsability to deal with.
483 * \n This method makes the assumption that the field \a this is correctly defined when this method is called (\c this->checkCoherency() returns without any exception thrown), **no check of this will be done**.
484 * \n This method returns a restriction of \a this so that only tuples id specified in [ \a partBg , \a partEnd ) will be contained in returned field.
485 * \n Parameter [\a partBg, \a partEnd ) specifies \b cell \b ids \b whatever \b the \b spatial \b discretization of \a this
486 * (\ref ParaMEDMEM::ON_CELLS "ON_CELLS", \ref ParaMEDMEM::ON_NODES "ON_CELLS", \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE")
488 * If \a this is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6].
489 * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
491 *- Tuple#0 of return field will refer to the cell#0 of returned mesh. The cell #0 of returned mesh will be equal to the cell#3 of \c this->getMesh()
492 *- Tuple#1 of return field will refer to the cell#1 of returned mesh. The cell #1 of returned mesh will be equal to the cell#7 of \c this->getMesh()
493 *- Tuple#2 of return field will refer to the cell#2 of returned mesh. The cell #2 of returned mesh will be equal to the cell#6 of \c this->getMesh()
495 * If \a this is field on node lying on a mesh that have 10 cells and 11 nodes for example. So \a this is currently contains 11 tuples.
496 * \n If part contains following cellIds [3,7,6].
497 * \n If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, the returned field,
498 * will contain 6 tuples (and same number of components \c this->getArray()->getNumberOfComponents() ) and this field will lie on this restricted mesh.
500 * \param [in] partBg start (included) of input range cell ids to select [ \a partBg, \a partEnd )
501 * \param [in] partEnd end (not included) of input range cell ids to select [ \a partBg, \a partEnd )
502 * \return a newly allocated field the caller should deal with.
504 * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \c this->getMesh()
506 * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."
508 * \ref py_mcfielddouble_subpart1 "Here a Python example."
509 * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const
511 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception)
513 DataArrayInt *arrSelect;
514 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect);
515 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrSelect2(arrSelect);
516 MEDCouplingFieldDouble *ret=clone(false);//quick shallow copy.
517 const MEDCouplingFieldDiscretization *disc=getDiscretization();
519 ret->setDiscretization(MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDiscretization>(disc->clonePart(partBg,partEnd)));
521 std::vector<DataArrayDouble *> arrays;
522 _time_discr->getArrays(arrays);
523 std::vector<DataArrayDouble *> arrs;
524 const int *arrSelBg=arrSelect->begin();
525 const int *arrSelEnd=arrSelect->end();
526 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
528 DataArrayDouble *arr=0;
530 arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd);
533 ret->_time_discr->setArrays(arrs,0);
534 for(std::vector<DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
540 TypeOfTimeDiscretization MEDCouplingFieldDouble::getTimeDiscretization() const
542 return _time_discr->getEnum();
545 MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingField(type),
546 _time_discr(MEDCouplingTimeDiscretization::New(td))
551 * ** WARINING : This method do not deeply copy neither mesh nor spatial discretization. Only a shallow copy (reference) is done for mesh and spatial discretization ! **
553 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingField(ft,false),
554 _time_discr(MEDCouplingTimeDiscretization::New(td))
558 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other,deepCopy),
559 _time_discr(other._time_discr->performCpy(deepCopy))
563 MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingField(type,n),_time_discr(td)
567 MEDCouplingFieldDouble::~MEDCouplingFieldDouble()
572 void MEDCouplingFieldDouble::checkCoherency() const throw(INTERP_KERNEL::Exception)
575 throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !");
576 _time_discr->checkCoherency();
577 _type->checkCoherencyBetween(_mesh,getArray());
581 * Returns the accumulation (the sum) of comId_th component of each tuples of \b default and \b only \b default array.
583 double MEDCouplingFieldDouble::accumulate(int compId) const
586 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
587 return getArray()->accumulate(compId);
591 * Returns the accumulation (the sum) of all tuples of \b default and \b only default array.
592 * The res is expected to be of size getNumberOfComponents().
594 void MEDCouplingFieldDouble::accumulate(double *res) const
597 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
598 getArray()->accumulate(res);
602 * This method returns the max value in \a this. \a this is expected to be a field with exactly \b one component. If not an exception will be thrown.
603 * To getMaxValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'.
604 * If no arrays exists, an exception will be thrown.
606 double MEDCouplingFieldDouble::getMaxValue() const throw(INTERP_KERNEL::Exception)
608 std::vector<DataArrayDouble *> arrays;
609 _time_discr->getArrays(arrays);
610 double ret=-std::numeric_limits<double>::max();
611 bool isExistingArr=false;
612 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
618 ret=std::max(ret,(*iter)->getMaxValue(loc));
622 throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !");
627 * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMaxValue method because the returned
628 * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility
629 * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array.
630 * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used
631 * to compute tupleIds.
633 double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
635 std::vector<DataArrayDouble *> arrays;
636 _time_discr->getArrays(arrays);
637 double ret=-std::numeric_limits<double>::max();
638 bool isExistingArr=false;
640 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
646 ret=std::max(ret,(*iter)->getMaxValue2(tmp));
654 throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !");
659 * This method returns the min value in \a this. \a this is expected to be a field with exactly \b one component. If not an exception will be thrown.
660 * To getMinValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'.
661 * If no arrays exists, an exception will be thrown.
663 double MEDCouplingFieldDouble::getMinValue() const throw(INTERP_KERNEL::Exception)
665 std::vector<DataArrayDouble *> arrays;
666 _time_discr->getArrays(arrays);
667 double ret=std::numeric_limits<double>::max();
668 bool isExistingArr=false;
669 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
675 ret=std::min(ret,(*iter)->getMinValue(loc));
679 throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !");
684 * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMinValue method because the returned
685 * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility
686 * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array.
687 * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used
688 * to compute tupleIds.
690 double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
692 std::vector<DataArrayDouble *> arrays;
693 _time_discr->getArrays(arrays);
694 double ret=-std::numeric_limits<double>::max();
695 bool isExistingArr=false;
697 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
703 ret=std::max(ret,(*iter)->getMinValue2(tmp));
711 throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !");
716 * This method returns the average value in \a this. \a this is expected to be a field with exactly \b one component. If not an exception will be thrown.
717 * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
718 * If default array does not exist, an exception will be thrown.
720 double MEDCouplingFieldDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
723 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !");
724 return getArray()->getAverageValue();
728 * This method returns the euclidean norm of \a this.
730 * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]}
732 * If default array does not exist, an exception will be thrown.
734 double MEDCouplingFieldDouble::norm2() const throw(INTERP_KERNEL::Exception)
737 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !");
738 return getArray()->norm2();
742 * This method returns the max norm of \a this.
744 * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
746 * If default array does not exist, an exception will be thrown.
748 double MEDCouplingFieldDouble::normMax() const throw(INTERP_KERNEL::Exception)
751 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
752 return getArray()->normMax();
756 * This method returns the average value in \a this weighted by ParaMEDMEM::MEDCouplingField::buildMeasureField.
757 * \a this is expected to be a field with exactly \b one component. If not an exception will be thrown.
758 * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
759 * If default array does not exist, an exception will be thrown.
761 * \param [out] res the location where the result will be stored. \a res is expected to be a location with \c this->getNumberOfComponents() places available.
762 * \param [in] isWAbs specifies if abs is applied on measure on underlying mesh before performing computation. For a user already sure that all cells of its underlying mesh
763 * are all well oriented this parameter can be set to false to be 'faster'. By default this parameter is true.
765 void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const throw(INTERP_KERNEL::Exception)
768 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
769 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> w=buildMeasureField(isWAbs);
770 double deno=w->getArray()->accumulate(0);
771 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=getArray()->deepCpy();
772 arr->multiplyEqual(w->getArray());
773 std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind2nd(std::multiplies<double>(),1./deno));
774 arr->accumulate(res);
778 * This method returns the average value in \a this weighted by ParaMEDMEM::MEDCouplingField::buildMeasureField.
779 * \a this is expected to be a field with exactly \b one component. If not an exception will be thrown.
780 * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
781 * If default array does not exist, an exception will be thrown.
783 * \param [in] compId The component id that should be in [0, \c this->getNumberOfComponents() ). If not an INTERP_KERNEL::Exception will be thrown.
784 * \param [in] isWAbs specifies if abs is applied on measure on underlying mesh before performing computation. For a user already sure that all cells of its underlying mesh
785 * are all well oriented this parameter can be set to false to be 'faster'. By default this parameter is true in C++ not in python (overloading confusion).
787 double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception)
789 int nbComps=getArray()->getNumberOfComponents();
790 if(compId<0 || compId>=nbComps)
792 std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
793 throw INTERP_KERNEL::Exception(oss.str().c_str());
795 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
796 getWeightedAverageValue(res,isWAbs);
801 * Returns the normL1 of current field on compId component :
803 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
805 * If compId>=nbOfComponent an exception is thrown.
807 double MEDCouplingFieldDouble::normL1(int compId) const throw(INTERP_KERNEL::Exception)
810 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
811 int nbComps=getArray()->getNumberOfComponents();
812 if(compId<0 || compId>=nbComps)
814 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
815 throw INTERP_KERNEL::Exception(oss.str().c_str());
817 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
818 _type->normL1(_mesh,getArray(),res);
823 * Returns the normL1 of current field on each components :
825 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
827 * The res is expected to be of size getNumberOfComponents().
829 void MEDCouplingFieldDouble::normL1(double *res) const throw(INTERP_KERNEL::Exception)
832 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
833 _type->normL1(_mesh,getArray(),res);
837 * Returns the normL2 of current field on compId component :
839 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
841 * If compId>=nbOfComponent an exception is thrown.
843 double MEDCouplingFieldDouble::normL2(int compId) const throw(INTERP_KERNEL::Exception)
846 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
847 int nbComps=getArray()->getNumberOfComponents();
848 if(compId<0 || compId>=nbComps)
850 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
851 throw INTERP_KERNEL::Exception(oss.str().c_str());
853 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
854 _type->normL2(_mesh,getArray(),res);
859 * Returns the normL2 of current field on each components :
861 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
863 * The res is expected to be of size getNumberOfComponents().
865 void MEDCouplingFieldDouble::normL2(double *res) const throw(INTERP_KERNEL::Exception)
868 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
869 _type->normL2(_mesh,getArray(),res);
873 * Returns the accumulation (the sum) of comId_th component of each tuples weigthed by the field
874 * returns by getWeightingField relative of the _type of field of default array.
875 * This method is useful to check the conservativity of interpolation method.
877 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception)
880 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
881 int nbComps=getArray()->getNumberOfComponents();
882 if(compId<0 || compId>=nbComps)
884 std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
885 throw INTERP_KERNEL::Exception(oss.str().c_str());
887 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
888 _type->integral(_mesh,getArray(),isWAbs,res);
893 * Returns the accumulation (the sum) of each tuples weigthed by the field
894 * returns by getWeightingField relative of the _type of field of default array.
895 * This method is useful to check the conservativity of interpolation method.
897 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception)
900 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
901 _type->integral(_mesh,getArray(),isWAbs,res);
905 * This method is reserved for field lying on structured mesh spatial support. It returns the value of cell localized by (i,j,k)
906 * If spatial support is not structured mesh an exception will be thrown.
907 * @param res out array expected to be equal to size getNumberOfComponents()
909 void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const throw(INTERP_KERNEL::Exception)
911 const DataArrayDouble *arr=_time_discr->getArray();
913 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
914 _type->getValueOnPos(arr,_mesh,i,j,k,res);
918 * Returns value of \a this on default time of point 'spaceLoc' using spatial discretization.
919 * If 'point' is outside the spatial discretization of this an exception will be thrown.
921 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const throw(INTERP_KERNEL::Exception)
923 const DataArrayDouble *arr=_time_discr->getArray();
925 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
926 _type->getValueOn(arr,_mesh,spaceLoc,res);
930 * Returns a newly allocated array with 'nbOfPoints' tuples and nb of components equal to 'this->getNumberOfComponents()'.
932 DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const throw(INTERP_KERNEL::Exception)
934 const DataArrayDouble *arr=_time_discr->getArray();
936 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
937 return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
941 * Returns value of \a this on time 'time' of point 'spaceLoc' using spatial discretization.
942 * If 'time' is not covered by this->_time_discr an exception will be thrown.
943 * If 'point' is outside the spatial discretization of this an exception will be thrown.
945 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const throw(INTERP_KERNEL::Exception)
947 std::vector< const DataArrayDouble *> arrs=_time_discr->getArraysForTime(time);
949 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
950 std::vector<double> res2;
951 for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
953 int sz=(int)res2.size();
954 res2.resize(sz+(*iter)->getNumberOfComponents());
955 _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]);
957 _time_discr->getValueForTime(time,res2,res);
961 * Applies a*x+b on 'compoId'th component of each cell.
963 void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
965 _time_discr->applyLin(a,b,compoId);
969 * This method sets \a this to a uniform scalar field with one component.
970 * All tuples will have the same value 'value'.
971 * An exception is thrown if no underlying mesh is defined.
973 MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) throw(INTERP_KERNEL::Exception)
976 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
977 int nbOfTuple=_type->getNumberOfTuples(_mesh);
978 _time_discr->setUniformValue(nbOfTuple,1,value);
983 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic.
984 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
985 * The main difference is that the field as been started to be constructed here.
986 * An exception is thrown if no underlying mesh is set before the call of this method.
988 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception)
991 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
992 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
993 _time_discr->fillFromAnalytic(loc,nbOfComp,func);
997 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic.
998 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
999 * The main difference is that the field as been started to be constructed here.
1000 * An exception is thrown if no underlying mesh is set before the call of this method.
1002 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
1005 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1006 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1007 _time_discr->fillFromAnalytic(loc,nbOfComp,func);
1011 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic2.
1012 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
1013 * The main difference is that the field as been started to be constructed here.
1014 * An exception is throw if no underlying mesh is set before the call of this method.
1016 void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
1019 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !");
1020 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1021 _time_discr->fillFromAnalytic2(loc,nbOfComp,func);
1025 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic3.
1026 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
1027 * The main difference is that the field as been started to be constructed here.
1028 * An exception is thrown if no underlying mesh is set before the call of this method.
1030 void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) throw(INTERP_KERNEL::Exception)
1033 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !");
1034 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1035 _time_discr->fillFromAnalytic3(loc,nbOfComp,varsOrder,func);
1039 * Applyies the function specified by pointer 'func' on each tuples on all arrays contained in _time_discr.
1040 * If '*func' returns false during one evaluation an exception will be thrown.
1042 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
1044 _time_discr->applyFunc(nbOfComp,func);
1048 * This method is a specialization of other overloaded methods. When 'nbOfComp' equals 1 this method is equivalent to
1049 * ParaMEDMEM::MEDCouplingFieldDouble::operator=.
1051 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
1054 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
1055 int nbOfTuple=_type->getNumberOfTuples(_mesh);
1056 _time_discr->setUniformValue(nbOfTuple,nbOfComp,val);
1060 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1061 * If '*func' fails in evaluation during one evaluation an exception will be thrown.
1062 * The field will contain 'nbOfComp' components after the call.
1064 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
1066 _time_discr->applyFunc(nbOfComp,func);
1070 * This method is equivalent to MEDCouplingFieldDouble::applyFunc, except that here components info are used to determine variables position in 'func'.
1071 * If there is vars detected in 'func' that is not in an info on components an exception will be thrown.
1073 void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
1075 _time_discr->applyFunc2(nbOfComp,func);
1079 * This method is equivalent to MEDCouplingFieldDouble::applyFunc, except that here 'varsOrder' is used to determine variables position in 'func'.
1080 * If there is vars detected in 'func' that is not in 'varsOrder' an exception will be thrown.
1082 void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) throw(INTERP_KERNEL::Exception)
1084 _time_discr->applyFunc3(nbOfComp,varsOrder,func);
1088 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1089 * If '*func' fails in evaluation during one evaluation an exception will be thrown.
1090 * The field will contain exactly the same number of components after the call.
1092 void MEDCouplingFieldDouble::applyFunc(const char *func) throw(INTERP_KERNEL::Exception)
1094 _time_discr->applyFunc(func);
1098 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1099 * The field will contain exactly the same number of components after the call.
1100 * Use is not warranted for the moment !
1102 void MEDCouplingFieldDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
1104 _time_discr->applyFuncFast32(func);
1108 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1109 * The field will contain exactly the same number of components after the call.
1110 * Use is not warranted for the moment !
1112 void MEDCouplingFieldDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
1114 _time_discr->applyFuncFast64(func);
1118 * This method makes the assumption that the default array has been set before.
1119 * If not an exception will be sent.
1120 * If default array set, the number of components will be sent.
1122 int MEDCouplingFieldDouble::getNumberOfComponents() const throw(INTERP_KERNEL::Exception)
1125 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
1126 return getArray()->getNumberOfComponents();
1130 * This method makes the assumption that _mesh has be set before the call of this method and description of gauss
1131 * localizations in case of Gauss field. If not an exception will sent.
1132 * \b Contrary to MEDCouplingFieldDouble::getNumberOfComponents and MEDCouplingFieldDouble::getNumberOfValues is
1133 * \b not aware of the presence of the default array.
1134 * \b WARNING \b no coherency check is done here. MEDCouplingFieldDouble::checkCoherency method should be called to check that !
1136 int MEDCouplingFieldDouble::getNumberOfTuples() const throw(INTERP_KERNEL::Exception)
1139 throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
1140 return _type->getNumberOfTuples(_mesh);
1144 * This method makes the assumption that the default array has been set before.
1145 * If not an exception will be sent.
1146 * If default array set, the number of values present in the default array will be sent.
1148 int MEDCouplingFieldDouble::getNumberOfValues() const throw(INTERP_KERNEL::Exception)
1151 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
1152 return getArray()->getNbOfElems();
1155 void MEDCouplingFieldDouble::updateTime() const
1157 MEDCouplingField::updateTime();
1158 updateTimeWith(*_time_discr);
1161 std::size_t MEDCouplingFieldDouble::getHeapMemorySize() const
1165 ret+=_time_discr->getHeapMemorySize();
1166 return MEDCouplingField::getHeapMemorySize()+ret;
1169 void MEDCouplingFieldDouble::setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception)
1171 MEDCouplingField::setNature(nat);
1172 _type->checkCompatibilityWithNature(nat);
1176 * This method synchronizes time information (time, iteration, order, time unit) regarding the information in \c this->_mesh.
1177 * \throw If no mesh is set in this. Or if \a this is not compatible with time setting (typically NO_TIME)
1179 void MEDCouplingFieldDouble::synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception)
1182 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::synchronizeTimeWithMesh : no mesh set in this !");
1184 double val=_mesh->getTime(it,ordr);
1185 std::string timeUnit(_mesh->getTimeUnit());
1186 setTime(val,it,ordr);
1187 setTimeUnit(timeUnit.c_str());
1190 double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
1192 return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
1195 void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
1197 _time_discr->setArray(array,this);
1200 void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
1202 _time_discr->setEndArray(array,this);
1205 void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs) throw(INTERP_KERNEL::Exception)
1207 _time_discr->setArrays(arrs,this);
1210 void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
1213 _time_discr->getTinySerializationStrInformation(tinyInfo);
1214 tinyInfo.push_back(_name);
1215 tinyInfo.push_back(_desc);
1216 tinyInfo.push_back(getTimeUnit());
1220 * This method retrieves some critical values to resize and prepare remote instance.
1221 * The first two elements returned in tinyInfo correspond to the parameters to give in constructor.
1222 * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1224 void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
1227 tinyInfo.push_back((int)_type->getEnum());
1228 tinyInfo.push_back((int)_time_discr->getEnum());
1229 tinyInfo.push_back((int)_nature);
1230 _time_discr->getTinySerializationIntInformation(tinyInfo);
1231 std::vector<int> tinyInfo2;
1232 _type->getTinySerializationIntInformation(tinyInfo2);
1233 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1234 tinyInfo.push_back((int)tinyInfo2.size());
1238 * This method retrieves some critical values to resize and prepare remote instance.
1239 * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1241 void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
1244 _time_discr->getTinySerializationDbleInformation(tinyInfo);
1245 std::vector<double> tinyInfo2;
1246 _type->getTinySerializationDbleInformation(tinyInfo2);
1247 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1248 tinyInfo.push_back((int)tinyInfo2.size());//very bad, lack of time to improve it
1252 * This method has to be called to the new instance filled by CORBA, MPI, File...
1253 * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied.
1254 * @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.
1255 * @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.
1256 * No decrRef must be applied to every instances in returned vector.
1258 void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays)
1261 std::vector<int> tinyInfoITmp(tinyInfoI);
1262 int sz=tinyInfoITmp.back();
1263 tinyInfoITmp.pop_back();
1264 std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz);
1265 std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end());
1266 _time_discr->resizeForUnserialization(tinyInfoI2,arrays);
1267 std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end());
1268 _type->resizeForUnserialization(tinyInfoITmp3,dataInt);
1271 void MEDCouplingFieldDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS)
1273 std::vector<int> tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end());
1275 std::vector<double> tmp(tinyInfoD);
1276 int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it
1278 std::vector<double> tmp1(tmp.begin(),tmp.end()-sz);
1279 std::vector<double> tmp2(tmp.end()-sz,tmp.end());
1281 _time_discr->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS);
1282 _nature=(NatureOfField)tinyInfoI[2];
1283 _type->finishUnserialization(tmp2);
1284 int nbOfElemS=(int)tinyInfoS.size();
1285 _name=tinyInfoS[nbOfElemS-3];
1286 _desc=tinyInfoS[nbOfElemS-2];
1287 setTimeUnit(tinyInfoS[nbOfElemS-1].c_str());
1291 * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller.
1292 * The values returned must be consulted only in readonly mode.
1294 void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) const
1296 _time_discr->getArrays(arrays);
1297 _type->getSerializationIntArray(dataInt);
1301 * This method tries to to change the mesh support of \a this following the parameter 'levOfCheck' and 'prec'.
1302 * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method. This method is used to perform the job.
1303 * If this->_mesh is not defined or other an exeption will be throw.
1305 void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception)
1307 if(_mesh==0 || other==0)
1308 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
1309 DataArrayInt *cellCor=0,*nodeCor=0;
1310 other->checkGeoEquivalWith(_mesh,levOfCheck,prec,cellCor,nodeCor);
1311 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2(cellCor),nodeCor2(nodeCor);
1313 renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
1315 renumberNodesWithoutMesh(nodeCor->getConstPointer(),_mesh->getNumberOfNodes());
1316 setMesh(const_cast<MEDCouplingMesh *>(other));
1320 * This method is an extension of MEDCouplingFieldDouble::operator-=. It allows a user to operate a difference of 2 fields (\a this and 'f') even if they do not share same meshes.
1321 * No interpolation will be done here only an analyze of two underlying mesh will be done to see if the meshes are geometrically equivalent. If yes, the eventual renumbering will be done and operator-= applyed after.
1322 * This method requires that 'f' and \a this are coherent (check coherency) and that 'f' and \a this would be coherent for a merge.
1323 * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method.
1325 void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception)
1328 f->checkCoherency();
1329 if(!areCompatibleForMerge(f))
1330 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::diffWith : Fields are not compatible ; unable to apply mergeFields on them !");
1331 changeUnderlyingMesh(f->getMesh(),levOfCheck,prec);
1336 * Merge nodes of underlying mesh. In case of some node will be merged the underlying mesh instance will change.
1337 * The first 'eps' stands for geometric approximation. The second 'epsOnVals' is for epsilon on values in case of node merging.
1338 * If 2 nodes distant from less than 'eps' and with value different with more than 'epsOnVals' an exception will be thrown.
1340 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals) throw(INTERP_KERNEL::Exception)
1342 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1344 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1345 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1348 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2);
1349 if(!ret)//no nodes have been merged.
1351 std::vector<DataArrayDouble *> arrays;
1352 _time_discr->getArrays(arrays);
1353 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1355 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1361 * Merge nodes with (barycenter computation) of underlying mesh. In case of some node will be merged the underlying mesh instance will change.
1362 * The first 'eps' stands for geometric approximation. The second 'epsOnVals' is for epsilon on values in case of node merging.
1363 * If 2 nodes distant from less than 'eps' and with value different with more than 'epsOnVals' an exception will be thrown.
1365 bool MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals) throw(INTERP_KERNEL::Exception)
1367 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1369 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1370 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1373 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes2(eps,ret,ret2);
1374 if(!ret)//no nodes have been merged.
1376 std::vector<DataArrayDouble *> arrays;
1377 _time_discr->getArrays(arrays);
1378 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1380 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1386 * This method applyies ParaMEDMEM::MEDCouplingPointSet::zipCoords method on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingPointSet.
1387 * If some nodes have disappeared true is returned.
1388 * 'epsOnVals' stands for epsilon in case of merge of cells. This value is used as tolerance in case the corresponding values differ.
1390 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals) throw(INTERP_KERNEL::Exception)
1392 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1394 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1395 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1396 int oldNbOfNodes=meshC2->getNumberOfNodes();
1397 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipCoordsTraducer();
1398 if(meshC2->getNumberOfNodes()!=oldNbOfNodes)
1400 std::vector<DataArrayDouble *> arrays;
1401 _time_discr->getArrays(arrays);
1402 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1404 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1412 * This method applyies ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingUMesh.
1413 * The semantic of 'compType' is given in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer method.
1414 * 'epsOnVals' stands for epsilon in case of merge of cells. This value is used as tolerance in case the corresponding values differ.
1416 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals) throw(INTERP_KERNEL::Exception)
1418 const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
1420 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1421 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCpy());
1422 int oldNbOfCells=meshC2->getNumberOfCells();
1423 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipConnectivityTraducer(compType);
1424 if(meshC2->getNumberOfCells()!=oldNbOfCells)
1426 std::vector<DataArrayDouble *> arrays;
1427 _time_discr->getArrays(arrays);
1428 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1430 _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter);
1438 * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists.
1439 * For the moment, this method is implemented for fields on cells.
1441 * \return a newly allocated field double containing the result that the user should deallocate.
1443 MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const throw(INTERP_KERNEL::Exception)
1445 const MEDCouplingMesh *mesh=getMesh();
1447 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !");
1448 if(getTypeOfField()!=ON_CELLS)
1449 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !");
1450 const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1451 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=clone(false);
1452 ret->setMesh(umesh);
1453 DataArrayInt *cellIds=0;
1454 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds);
1455 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds2=cellIds;
1456 ret->setMesh(mesh2);
1457 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end());
1458 std::vector<DataArrayDouble *> arrays;
1459 _time_discr->getArrays(arrays);
1461 std::vector<DataArrayDouble *> newArr(arrays.size());
1462 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > newArr2(arrays.size());
1463 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++)
1467 newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
1468 newArr[i]=newArr2[i];
1471 ret->setArrays(newArr);
1476 * This method applyies ParaMEDMEM::MEDCouplingUMesh::simplexize on 'this->_mesh'.
1477 * The semantic of 'policy' is given in ParaMEDMEM::MEDCouplingUMesh::simplexize method.
1479 bool MEDCouplingFieldDouble::simplexize(int policy) throw(INTERP_KERNEL::Exception)
1481 int oldNbOfCells=_mesh->getNumberOfCells();
1482 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> meshC2(_mesh->deepCpy());
1483 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->simplexize(policy);
1484 int newNbOfCells=meshC2->getNumberOfCells();
1485 if(oldNbOfCells==newNbOfCells)
1487 std::vector<DataArrayDouble *> arrays;
1488 _time_discr->getArrays(arrays);
1489 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1491 _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter);
1496 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
1498 MEDCouplingTimeDiscretization *td=_time_discr->doublyContractedProduct();
1499 td->copyTinyAttrFrom(*_time_discr);
1500 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1501 ret->setName("DoublyContractedProduct");
1502 ret->setMesh(getMesh());
1506 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const throw(INTERP_KERNEL::Exception)
1508 MEDCouplingTimeDiscretization *td=_time_discr->determinant();
1509 td->copyTinyAttrFrom(*_time_discr);
1510 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1511 ret->setName("Determinant");
1512 ret->setMesh(getMesh());
1516 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
1518 MEDCouplingTimeDiscretization *td=_time_discr->eigenValues();
1519 td->copyTinyAttrFrom(*_time_discr);
1520 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1521 ret->setName("EigenValues");
1522 ret->setMesh(getMesh());
1526 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
1528 MEDCouplingTimeDiscretization *td=_time_discr->eigenVectors();
1529 td->copyTinyAttrFrom(*_time_discr);
1530 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1531 ret->setName("EigenVectors");
1532 ret->setMesh(getMesh());
1536 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const throw(INTERP_KERNEL::Exception)
1538 MEDCouplingTimeDiscretization *td=_time_discr->inverse();
1539 td->copyTinyAttrFrom(*_time_discr);
1540 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1541 ret->setName("Inversion");
1542 ret->setMesh(getMesh());
1546 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const throw(INTERP_KERNEL::Exception)
1548 MEDCouplingTimeDiscretization *td=_time_discr->trace();
1549 td->copyTinyAttrFrom(*_time_discr);
1550 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1551 ret->setName("Trace");
1552 ret->setMesh(getMesh());
1556 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const throw(INTERP_KERNEL::Exception)
1558 MEDCouplingTimeDiscretization *td=_time_discr->deviator();
1559 td->copyTinyAttrFrom(*_time_discr);
1560 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1561 ret->setName("Trace");
1562 ret->setMesh(getMesh());
1566 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const throw(INTERP_KERNEL::Exception)
1568 MEDCouplingTimeDiscretization *td=_time_discr->magnitude();
1569 td->copyTinyAttrFrom(*_time_discr);
1570 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1571 ret->setName("Magnitude");
1572 ret->setMesh(getMesh());
1576 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
1578 MEDCouplingTimeDiscretization *td=_time_discr->maxPerTuple();
1579 td->copyTinyAttrFrom(*_time_discr);
1580 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1581 std::ostringstream oss;
1582 oss << "Max_" << getName();
1583 ret->setName(oss.str().c_str());
1584 ret->setMesh(getMesh());
1588 void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception)
1590 _time_discr->changeNbOfComponents(newNbOfComp,dftValue);
1593 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1595 MEDCouplingTimeDiscretization *td=_time_discr->keepSelectedComponents(compoIds);
1596 td->copyTinyAttrFrom(*_time_discr);
1597 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1598 ret->setName(getName());
1599 ret->setMesh(getMesh());
1603 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
1605 _time_discr->setSelectedComponents(f->_time_discr,compoIds);
1608 void MEDCouplingFieldDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
1610 _time_discr->sortPerTuple(asc);
1613 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1615 if(!f1->areCompatibleForMerge(f2))
1616 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !");
1617 const MEDCouplingMesh *m1=f1->getMesh();
1618 const MEDCouplingMesh *m2=f2->getMesh();
1619 MEDCouplingMesh *m=m1->mergeMyselfWith(m2);
1620 MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr);
1621 td->copyTinyAttrFrom(*f1->_time_discr);
1622 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1625 ret->setName(f1->getName());
1626 ret->setDescription(f1->getDescription());
1631 * This method returns a newly created field that is the union of all fields in input array 'a'.
1632 * This method expects that 'a' is non empty. If not an exception will be thrown.
1633 * If there is only one field in 'a' a deepCopy (except time information of mesh and field) of the unique field instance in 'a' will be returned.
1634 * Generally speaking the first instance field in 'a' will be used to assign tiny attributes of returned field.
1636 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a) throw(INTERP_KERNEL::Exception)
1639 throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !");
1640 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms(a.size());
1641 std::vector< const MEDCouplingUMesh *> ms2(a.size());
1642 std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
1643 std::vector<const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
1644 const MEDCouplingFieldDouble *ref=(*it++);
1645 for(;it!=a.end();it++)
1646 if(!ref->areCompatibleForMerge(*it))
1647 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !");
1648 for(int i=0;i<(int)a.size();i++)
1650 if(!a[i]->getMesh())
1651 throw INTERP_KERNEL::Exception("MergeFields : A field as no underlying mesh !");
1652 ms[i]=a[i]->getMesh()->buildUnstructured();
1654 tds[i]=a[i]->_time_discr;
1656 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::MergeUMeshes(ms2);
1657 m->setName(ms2[0]->getName()); m->setDescription(ms2[0]->getDescription());
1658 MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds);
1659 td->copyTinyAttrFrom(*(a[0]->_time_discr));
1660 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone());
1662 ret->setName(a[0]->getName());
1663 ret->setDescription(a[0]->getDescription());
1667 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1669 if(!f1->areCompatibleForMeld(f2))
1670 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MeldFields on them !");
1671 MEDCouplingTimeDiscretization *td=f1->_time_discr->meld(f2->_time_discr);
1672 td->copyTinyAttrFrom(*f1->_time_discr);
1673 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1674 ret->setMesh(f1->getMesh());
1678 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1680 if(!f1->areStrictlyCompatible(f2))
1681 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DotFields on them !");
1682 MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr);
1683 td->copyTinyAttrFrom(*f1->_time_discr);
1684 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1685 ret->setMesh(f1->getMesh());
1689 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1691 if(!f1->areStrictlyCompatible(f2))
1692 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply CrossProductFields on them !");
1693 MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr);
1694 td->copyTinyAttrFrom(*f1->_time_discr);
1695 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1696 ret->setMesh(f1->getMesh());
1700 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1702 if(!f1->areStrictlyCompatible(f2))
1703 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MaxFields on them !");
1704 MEDCouplingTimeDiscretization *td=f1->_time_discr->max(f2->_time_discr);
1705 td->copyTinyAttrFrom(*f1->_time_discr);
1706 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1707 ret->setMesh(f1->getMesh());
1711 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1713 if(!f1->areStrictlyCompatible(f2))
1714 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MinFields on them !");
1715 MEDCouplingTimeDiscretization *td=f1->_time_discr->min(f2->_time_discr);
1716 td->copyTinyAttrFrom(*f1->_time_discr);
1717 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1718 ret->setMesh(f1->getMesh());
1722 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1724 if(!f1->areStrictlyCompatible(f2))
1725 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply AddFields on them !");
1726 MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr);
1727 td->copyTinyAttrFrom(*f1->_time_discr);
1728 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1729 ret->setMesh(f1->getMesh());
1733 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1735 if(!areStrictlyCompatible(&other))
1736 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply += on them !");
1737 _time_discr->addEqual(other._time_discr);
1741 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1743 if(!f1->areStrictlyCompatible(f2))
1744 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply SubstractFields on them !");
1745 MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(f2->_time_discr);
1746 td->copyTinyAttrFrom(*f1->_time_discr);
1747 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1748 ret->setMesh(f1->getMesh());
1752 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1754 if(!areStrictlyCompatible(&other))
1755 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply -= on them !");
1756 _time_discr->substractEqual(other._time_discr);
1760 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1762 if(!f1->areCompatibleForMul(f2))
1763 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MultiplyFields on them !");
1764 MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr);
1765 td->copyTinyAttrFrom(*f1->_time_discr);
1766 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1767 ret->setMesh(f1->getMesh());
1771 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1773 if(!areCompatibleForMul(&other))
1774 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply *= on them !");
1775 _time_discr->multiplyEqual(other._time_discr);
1779 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1781 if(!f1->areCompatibleForDiv(f2))
1782 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DivideFields on them !");
1783 MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(f2->_time_discr);
1784 td->copyTinyAttrFrom(*f1->_time_discr);
1785 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1786 ret->setMesh(f1->getMesh());
1790 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1792 if(!areCompatibleForDiv(&other))
1793 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !");
1794 _time_discr->divideEqual(other._time_discr);
1799 * This method writes the field series 'fs' in the VTK file 'fileName'.
1800 * If 'fs' is empty no file is written. If fields lies on more than one mesh an exception will be thrown and no file will be written too.
1801 * If the single mesh is empty an exception will be thrown.
1802 * Finally there is a field in 'fs' with no name an exception will be thrown too.
1804 void MEDCouplingFieldDouble::WriteVTK(const char *fileName, const std::vector<const MEDCouplingFieldDouble *>& fs) throw(INTERP_KERNEL::Exception)
1808 std::size_t nfs=fs.size();
1809 const MEDCouplingMesh *m=fs[0]->getMesh();
1810 for(std::size_t i=1;i<nfs;i++)
1811 if(fs[i]->getMesh()!=m)
1812 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.");
1814 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !");
1815 std::ostringstream coss,noss;
1816 for(std::size_t i=0;i<nfs;i++)
1818 const MEDCouplingFieldDouble *cur=fs[i];
1819 std::string name(cur->getName());
1822 std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
1823 throw INTERP_KERNEL::Exception(oss.str().c_str());
1825 TypeOfField typ=cur->getTypeOfField();
1827 cur->getArray()->writeVTK(coss,8,cur->getName());
1828 else if(typ==ON_NODES)
1829 cur->getArray()->writeVTK(noss,8,cur->getName());
1831 m->writeVTKAdvanced(fileName,coss.str(),noss.str());