1 // Copyright (C) 2007-2012 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.
54 * \param [in] ft \ref MEDCouplingFieldTemplatesPage "field template" defining its spatial discretization and supporting mesh.
55 * \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")
57 * \return a newly allocated field the caller should deal with.
59 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td)
61 return new MEDCouplingFieldDouble(ft,td);
65 * Sets time \a unit of \a this field.
67 * \param [in] unit \a unit (string) in which time is measured.
69 void MEDCouplingFieldDouble::setTimeUnit(const char *unit)
71 _time_discr->setTimeUnit(unit);
75 * Returns a time unit of \a this field.
77 * \return a string describing units in which time is measured.
79 const char *MEDCouplingFieldDouble::getTimeUnit() const
81 return _time_discr->getTimeUnit();
85 * This method if possible the time information (time unit, time iteration, time unit and time value) with its support
86 * that is to say its mesh.
88 * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is
91 void MEDCouplingFieldDouble::synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception)
93 _time_discr->synchronizeTimeWith(_mesh);
97 * This method performs a copy of \a this **without any copy of the underlying mesh** ( see warning section of this method).
98 * The copy of arrays is deep if \b recDeepCpy equals to true, no copy of arrays is done if \b recDeepCpy equals to false.
100 * \c clone(false) is rather dedicated for advanced users that want to limit the amount of memory.
102 * It allows the user to perform methods
103 * MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields with \a this and the returned field.
105 * \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.
106 * If the user wants to duplicated deeply the underlying mesh he should call MEDCouplingFieldDouble::cloneWithMesh method or MEDCouplingFieldDouble::deepCpy instead.
108 * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied or only attached to the returned field.
109 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
110 * \sa ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
112 MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
114 return new MEDCouplingFieldDouble(*this,recDeepCpy);
118 * This method behaves exactly like MEDCouplingFieldDouble::clone method **except that here the underlying mesh is systematically **
119 * (whatever the value of the input parameter \a recDeepCpy) **deeply duplicated**.
121 * The result of \c cloneWithMesh(true) is exactly the same than calling \ref MEDCouplingFieldDouble::deepCpy "deepCpy".
123 * So the resulting field of this call cannot be called with \a this with the following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ...
124 * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
126 * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied or only attached to the returned field.
127 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
128 * \sa ParaMEDMEM::MEDCouplingFieldDouble::clone(bool recDeepCpy) const
130 MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
132 MEDCouplingFieldDouble *ret=clone(recDeepCpy);
135 MEDCouplingMesh *mCpy=_mesh->deepCpy();
143 * This method performs a deepCpy of \a this (**mesh included**)!
144 * So the resulting field of this call cannot be called with \a this with following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ...
145 * To avoid deep copying the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
146 * This method is exactly equivalent to MEDCouplingFieldDouble::cloneWithMesh called with parameter true.
148 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
149 * \sa ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
151 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const
153 return cloneWithMesh(true);
159 * \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").
160 * \param [in] deepCopy specifies if underlying arrays in \a this should be copied or only attached to the returned field.
161 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
163 * \ref cpp_mcfielddouble_buildnewtimereprfromthis "Here a C++ example."
165 * \ref py_mcfielddouble_buildnewtimereprfromthis "Here a Python example."
166 * \sa ParaMEDMEM::MEDCouplingFieldDouble::clone(bool recDeepCpy) const
168 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const
170 MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(td,deepCopy);
171 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),tdo,_type->clone());
172 ret->setMesh(getMesh());
173 ret->setName(getName());
174 ret->setDescription(getDescription());
179 * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason).
181 void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingField *other) throw(INTERP_KERNEL::Exception)
183 MEDCouplingField::copyTinyStringsFrom(other);
184 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
187 _time_discr->copyTinyStringsFrom(*otherC->_time_discr);
192 * Copy only times, order, iteration from other. The underlying mesh is not impacted by this method.
193 * Arrays are not impacted too.
195 void MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
199 _time_discr->copyTinyAttrFrom(*other->_time_discr);
204 void MEDCouplingFieldDouble::copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
206 copyTinyStringsFrom(other);
207 copyTinyAttrFrom(other);
210 std::string MEDCouplingFieldDouble::simpleRepr() const
212 std::ostringstream ret;
213 ret << "FieldDouble with name : \"" << getName() << "\"\n";
214 ret << "Description of field is : \"" << getDescription() << "\"\n";
215 ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
216 ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
217 ret << "FieldDouble nature of field is : " << MEDCouplingNatureOfField::getRepr(_nature) << "\n";
220 int nbOfCompo=getArray()->getNumberOfComponents();
221 ret << "FieldDouble default array has " << nbOfCompo << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
222 ret << "FieldDouble default array has following info on components : ";
223 for(int i=0;i<nbOfCompo;i++)
224 ret << "\"" << getArray()->getInfoOnComponent(i) << "\" ";
228 ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr();
230 ret << "Mesh support information : No mesh set !\n";
234 std::string MEDCouplingFieldDouble::advancedRepr() const
236 std::ostringstream ret;
237 ret << "FieldDouble with name : \"" << getName() << "\"\n";
238 ret << "Description of field is : \"" << getDescription() << "\"\n";
239 ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
240 ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
242 ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
244 ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr();
246 ret << "Mesh support information : No mesh set !\n";
247 std::vector<DataArrayDouble *> arrays;
248 _time_discr->getArrays(arrays);
250 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++)
252 ret << "Array #" << arrayId << " :\n__________\n";
254 (*iter)->reprWithoutNameStream(ret);
256 ret << "Array empty !";
262 void MEDCouplingFieldDouble::writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception)
264 std::vector<const MEDCouplingFieldDouble *> fs(1,this);
265 MEDCouplingFieldDouble::WriteVTK(fileName,fs);
268 bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception)
271 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::isEqualIfNotWhy : other instance is NULL !");
272 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
275 reason="field given in input is not castable in MEDCouplingFieldDouble !";
278 if(!MEDCouplingField::isEqualIfNotWhy(other,meshPrec,valsPrec,reason))
280 if(!_time_discr->isEqualIfNotWhy(otherC->_time_discr,valsPrec,reason))
282 reason.insert(0,"In FieldDouble time discretizations differ :");
288 bool MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const
290 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
293 if(!MEDCouplingField::isEqualWithoutConsideringStr(other,meshPrec,valsPrec))
295 if(!_time_discr->isEqualWithoutConsideringStr(otherC->_time_discr,valsPrec))
301 * This method states if \a this and 'other' are compatibles each other before performing any treatment.
302 * This method is good for methods like : mergeFields.
303 * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields.
305 bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const
307 if(!MEDCouplingField::areCompatibleForMerge(other))
309 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
312 if(!_time_discr->areCompatible(otherC->_time_discr))
318 * This method is more strict than MEDCouplingField::areCompatibleForMerge method.
319 * This method is used for operation on fields to operate a first check before attempting operation.
321 bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const
324 if(!MEDCouplingField::areStrictlyCompatible(other))
326 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
329 if(!_time_discr->areStrictlyCompatible(otherC->_time_discr,tmp))
335 * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
336 * number of components between \a this and 'other' can be different here (for operator*).
338 bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const
340 if(!MEDCouplingField::areStrictlyCompatible(other))
342 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
345 if(!_time_discr->areStrictlyCompatibleForMul(otherC->_time_discr))
351 * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
352 * number of components between \a this and 'other' can be different here (for operator/).
354 bool MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const
356 if(!MEDCouplingField::areStrictlyCompatible(other))
358 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
361 if(!_time_discr->areStrictlyCompatibleForDiv(otherC->_time_discr))
367 * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible,
368 * except that \a this and other can have different number of components.
370 bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const
372 if(!MEDCouplingField::areStrictlyCompatible(other))
374 if(!_time_discr->areCompatibleForMeld(other->_time_discr))
380 * This method performs a clone of mesh and a renumbering of underlying cells of it. The number of cells remains the same.
381 * The values of field are impacted in consequence to have the same geometrical field.
383 void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
385 renumberCellsWithoutMesh(old2NewBg,check);
386 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_mesh->deepCpy();
387 m->renumberCells(old2NewBg,check);
393 * \b WARNING : use this method with lot of care !
394 * This method performs half job of MEDCouplingFieldDouble::renumberCells. That is to say no permutation of cells is done on underlying mesh.
395 * 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
396 * avoid a systematic duplication and renumbering of _mesh attribute.
398 void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
401 throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !");
403 _type->renumberCells(old2NewBg,check);
404 std::vector<DataArrayDouble *> arrays;
405 _time_discr->getArrays(arrays);
406 _type->renumberArraysForCell(_mesh,arrays,old2NewBg,check);
412 * 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.
413 * The values of field are impacted in consequence to have the same geometrical field.
415 void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception)
417 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
419 throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !");
420 int nbOfNodes=meshC->getNumberOfNodes();
421 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
422 int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1;
423 renumberNodesWithoutMesh(old2NewBg,newNbOfNodes);
424 meshC2->renumberNodes(old2NewBg,newNbOfNodes);
429 * \b WARNING : use this method with lot of care !
430 * This method performs half job of MEDCouplingFieldDouble::renumberNodes. That is to say no permutation of cells is done on underlying mesh.
431 * That is to say, the field content is changed by this method.
433 void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps) throw(INTERP_KERNEL::Exception)
435 std::vector<DataArrayDouble *> arrays;
436 _time_discr->getArrays(arrays);
437 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
439 _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter);
443 * This method makes the assumption that the default array is set. If not an exception will be thrown.
444 * This method is usable only if the default array has exactly one component. If not an exception will be thrown too.
445 * This method returns all tuples ids that fit the range [vmin,vmax].
446 * The caller has the responsability of the returned DataArrayInt.
448 DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
451 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getIdsInRange : no default array set !");
452 return getArray()->getIdsInRange(vmin,vmax);
456 * Builds a newly created field, that the caller will have the responsability to deal with (decrRef).
457 * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done.
458 * This method returns a restriction of \a this so that only tuples id specified in 'part' will be contained in returned field.
459 * 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)
461 * If \a this is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6].
462 * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
463 * 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()'
464 * 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()'
465 * 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()'
467 * 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].
468 * \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,
469 * will contain 6 tuples and this field will lie on this restricted mesh.
471 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception)
474 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !");
475 const int *start=part->getConstPointer();
476 const int *end=start+part->getNbOfElems();
477 return buildSubPart(start,end);
481 * Builds a newly created field, that the caller will have the responsability to deal with.
482 * \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**.
483 * \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.
484 * \n Parameter [\a partBg, \a partEnd ) specifies \b cell \b ids \b whatever \b the \b spatial \b discretization of \a this
485 * (\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")
487 * If \a this is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6].
488 * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
490 *- 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()
491 *- 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()
492 *- 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()
494 * 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.
495 * \n If part contains following cellIds [3,7,6].
496 * \n If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, the returned field,
497 * will contain 6 tuples (and same number of components \c this->getArray()->getNumberOfComponents() ) and this field will lie on this restricted mesh.
499 * \param [in] partBg start (included) of input range cell ids to select [ \a partBg, \a partEnd )
500 * \param [in] partEnd end (not included) of input range cell ids to select [ \a partBg, \a partEnd )
501 * \return a newly allocated field the caller should deal with.
503 * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \c this->getMesh()
505 * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."
507 * \ref py_mcfielddouble_subpart1 "Here a Python example."
508 * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const
510 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception)
512 DataArrayInt *arrSelect;
513 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect);
514 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrSelect2(arrSelect);
515 MEDCouplingFieldDouble *ret=clone(false);//quick shallow copy.
516 const MEDCouplingFieldDiscretization *disc=getDiscretization();
518 ret->setDiscretization(disc->clonePart(partBg,partEnd));
520 std::vector<DataArrayDouble *> arrays;
521 _time_discr->getArrays(arrays);
522 std::vector<DataArrayDouble *> arrs;
523 const int *arrSelBg=arrSelect->begin();
524 const int *arrSelEnd=arrSelect->end();
525 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
527 DataArrayDouble *arr=0;
529 arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd);
532 ret->_time_discr->setArrays(arrs,0);
533 for(std::vector<DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
539 TypeOfTimeDiscretization MEDCouplingFieldDouble::getTimeDiscretization() const
541 return _time_discr->getEnum();
544 MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingField(type),
545 _time_discr(MEDCouplingTimeDiscretization::New(td))
549 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingField(ft),
550 _time_discr(MEDCouplingTimeDiscretization::New(td))
554 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other,deepCopy),
555 _time_discr(other._time_discr->performCpy(deepCopy))
559 MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingField(type,n),_time_discr(td)
563 MEDCouplingFieldDouble::~MEDCouplingFieldDouble()
568 void MEDCouplingFieldDouble::checkCoherency() const throw(INTERP_KERNEL::Exception)
571 throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !");
572 _time_discr->checkCoherency();
573 _type->checkCoherencyBetween(_mesh,getArray());
577 * Returns the accumulation (the sum) of comId_th component of each tuples of \b default and \b only \b default array.
579 double MEDCouplingFieldDouble::accumulate(int compId) const
582 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
583 return getArray()->accumulate(compId);
587 * Returns the accumulation (the sum) of all tuples of \b default and \b only default array.
588 * The res is expected to be of size getNumberOfComponents().
590 void MEDCouplingFieldDouble::accumulate(double *res) const
593 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
594 getArray()->accumulate(res);
598 * 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.
599 * To getMaxValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'.
600 * If no arrays exists, an exception will be thrown.
602 double MEDCouplingFieldDouble::getMaxValue() const throw(INTERP_KERNEL::Exception)
604 std::vector<DataArrayDouble *> arrays;
605 _time_discr->getArrays(arrays);
606 double ret=-std::numeric_limits<double>::max();
607 bool isExistingArr=false;
608 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
614 ret=std::max(ret,(*iter)->getMaxValue(loc));
618 throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !");
623 * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMaxValue method because the returned
624 * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility
625 * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array.
626 * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used
627 * to compute tupleIds.
629 double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
631 std::vector<DataArrayDouble *> arrays;
632 _time_discr->getArrays(arrays);
633 double ret=-std::numeric_limits<double>::max();
634 bool isExistingArr=false;
636 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
642 ret=std::max(ret,(*iter)->getMaxValue2(tmp));
650 throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !");
655 * 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.
656 * To getMinValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'.
657 * If no arrays exists, an exception will be thrown.
659 double MEDCouplingFieldDouble::getMinValue() const throw(INTERP_KERNEL::Exception)
661 std::vector<DataArrayDouble *> arrays;
662 _time_discr->getArrays(arrays);
663 double ret=std::numeric_limits<double>::max();
664 bool isExistingArr=false;
665 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
671 ret=std::min(ret,(*iter)->getMinValue(loc));
675 throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !");
680 * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMinValue method because the returned
681 * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility
682 * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array.
683 * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used
684 * to compute tupleIds.
686 double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
688 std::vector<DataArrayDouble *> arrays;
689 _time_discr->getArrays(arrays);
690 double ret=-std::numeric_limits<double>::max();
691 bool isExistingArr=false;
693 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
699 ret=std::max(ret,(*iter)->getMinValue2(tmp));
707 throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !");
712 * 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.
713 * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
714 * If default array does not exist, an exception will be thrown.
716 double MEDCouplingFieldDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
719 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !");
720 return getArray()->getAverageValue();
724 * This method returns the euclidean norm of \a this.
726 * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]}
728 * If default array does not exist, an exception will be thrown.
730 double MEDCouplingFieldDouble::norm2() const throw(INTERP_KERNEL::Exception)
733 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !");
734 return getArray()->norm2();
738 * This method returns the max norm of \a this.
740 * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
742 * If default array does not exist, an exception will be thrown.
744 double MEDCouplingFieldDouble::normMax() const throw(INTERP_KERNEL::Exception)
747 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
748 return getArray()->normMax();
752 * This method returns the average value in \a this weighted by ParaMEDMEM::MEDCouplingField::buildMeasureField.
753 * \a this is expected to be a field with exactly \b one component. If not an exception will be thrown.
754 * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
755 * If default array does not exist, an exception will be thrown.
757 * \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.
758 * \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
759 * are all well oriented this parameter can be set to false to be 'faster'. By default this parameter is true.
761 void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const throw(INTERP_KERNEL::Exception)
764 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
765 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> w=buildMeasureField(isWAbs);
766 double deno=w->getArray()->accumulate(0);
767 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=getArray()->deepCpy();
768 arr->multiplyEqual(w->getArray());
769 std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind2nd(std::multiplies<double>(),1./deno));
770 arr->accumulate(res);
774 * This method returns the average value in \a this weighted by ParaMEDMEM::MEDCouplingField::buildMeasureField.
775 * \a this is expected to be a field with exactly \b one component. If not an exception will be thrown.
776 * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
777 * If default array does not exist, an exception will be thrown.
779 * \param [in] compId The component id that should be in [0, \c this->getNumberOfComponents() ). If not an INTERP_KERNEL::Exception will be thrown.
780 * \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
781 * 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).
783 double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception)
785 int nbComps=getArray()->getNumberOfComponents();
786 if(compId<0 || compId>=nbComps)
788 std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
789 throw INTERP_KERNEL::Exception(oss.str().c_str());
791 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
792 getWeightedAverageValue(res,isWAbs);
797 * Returns the normL1 of current field on compId component :
799 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
801 * If compId>=nbOfComponent an exception is thrown.
803 double MEDCouplingFieldDouble::normL1(int compId) const throw(INTERP_KERNEL::Exception)
806 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
807 int nbComps=getArray()->getNumberOfComponents();
808 if(compId<0 || compId>=nbComps)
810 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
811 throw INTERP_KERNEL::Exception(oss.str().c_str());
813 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
814 _type->normL1(_mesh,getArray(),res);
819 * Returns the normL1 of current field on each components :
821 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
823 * The res is expected to be of size getNumberOfComponents().
825 void MEDCouplingFieldDouble::normL1(double *res) const throw(INTERP_KERNEL::Exception)
828 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
829 _type->normL1(_mesh,getArray(),res);
833 * Returns the normL2 of current field on compId component :
835 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
837 * If compId>=nbOfComponent an exception is thrown.
839 double MEDCouplingFieldDouble::normL2(int compId) const throw(INTERP_KERNEL::Exception)
842 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
843 int nbComps=getArray()->getNumberOfComponents();
844 if(compId<0 || compId>=nbComps)
846 std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
847 throw INTERP_KERNEL::Exception(oss.str().c_str());
849 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
850 _type->normL2(_mesh,getArray(),res);
855 * Returns the normL2 of current field on each components :
857 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
859 * The res is expected to be of size getNumberOfComponents().
861 void MEDCouplingFieldDouble::normL2(double *res) const throw(INTERP_KERNEL::Exception)
864 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
865 _type->normL2(_mesh,getArray(),res);
869 * Returns the accumulation (the sum) of comId_th component of each tuples weigthed by the field
870 * returns by getWeightingField relative of the _type of field of default array.
871 * This method is useful to check the conservativity of interpolation method.
873 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception)
876 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
877 int nbComps=getArray()->getNumberOfComponents();
878 if(compId<0 || compId>=nbComps)
880 std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
881 throw INTERP_KERNEL::Exception(oss.str().c_str());
883 INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
884 _type->integral(_mesh,getArray(),isWAbs,res);
889 * Returns the accumulation (the sum) of each tuples weigthed by the field
890 * returns by getWeightingField relative of the _type of field of default array.
891 * This method is useful to check the conservativity of interpolation method.
893 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception)
896 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
897 _type->integral(_mesh,getArray(),isWAbs,res);
901 * This method is reserved for field lying on structured mesh spatial support. It returns the value of cell localized by (i,j,k)
902 * If spatial support is not structured mesh an exception will be thrown.
903 * @param res out array expected to be equal to size getNumberOfComponents()
905 void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const throw(INTERP_KERNEL::Exception)
907 const DataArrayDouble *arr=_time_discr->getArray();
909 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
910 _type->getValueOnPos(arr,_mesh,i,j,k,res);
914 * Returns value of \a this on default time of point 'spaceLoc' using spatial discretization.
915 * If 'point' is outside the spatial discretization of this an exception will be thrown.
917 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const throw(INTERP_KERNEL::Exception)
919 const DataArrayDouble *arr=_time_discr->getArray();
921 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
922 _type->getValueOn(arr,_mesh,spaceLoc,res);
926 * Returns a newly allocated array with 'nbOfPoints' tuples and nb of components equal to 'this->getNumberOfComponents()'.
928 DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const throw(INTERP_KERNEL::Exception)
930 const DataArrayDouble *arr=_time_discr->getArray();
932 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
933 return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
937 * Returns value of \a this on time 'time' of point 'spaceLoc' using spatial discretization.
938 * If 'time' is not covered by this->_time_discr an exception will be thrown.
939 * If 'point' is outside the spatial discretization of this an exception will be thrown.
941 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const throw(INTERP_KERNEL::Exception)
943 std::vector< const DataArrayDouble *> arrs=_time_discr->getArraysForTime(time);
945 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
946 std::vector<double> res2;
947 for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
949 int sz=(int)res2.size();
950 res2.resize(sz+(*iter)->getNumberOfComponents());
951 _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]);
953 _time_discr->getValueForTime(time,res2,res);
957 * Applies a*x+b on 'compoId'th component of each cell.
959 void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
961 _time_discr->applyLin(a,b,compoId);
965 * This method sets \a this to a uniform scalar field with one component.
966 * All tuples will have the same value 'value'.
967 * An exception is thrown if no underlying mesh is defined.
969 MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) throw(INTERP_KERNEL::Exception)
972 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
973 int nbOfTuple=_type->getNumberOfTuples(_mesh);
974 _time_discr->setUniformValue(nbOfTuple,1,value);
979 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic.
980 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
981 * The main difference is that the field as been started to be constructed here.
982 * An exception is thrown if no underlying mesh is set before the call of this method.
984 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception)
987 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
988 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
989 _time_discr->fillFromAnalytic(loc,nbOfComp,func);
993 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic.
994 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
995 * The main difference is that the field as been started to be constructed here.
996 * An exception is thrown if no underlying mesh is set before the call of this method.
998 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
1001 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
1002 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1003 _time_discr->fillFromAnalytic(loc,nbOfComp,func);
1007 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic2.
1008 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
1009 * The main difference is that the field as been started to be constructed here.
1010 * An exception is throw if no underlying mesh is set before the call of this method.
1012 void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
1015 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !");
1016 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1017 _time_discr->fillFromAnalytic2(loc,nbOfComp,func);
1021 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic3.
1022 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
1023 * The main difference is that the field as been started to be constructed here.
1024 * An exception is thrown if no underlying mesh is set before the call of this method.
1026 void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) throw(INTERP_KERNEL::Exception)
1029 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !");
1030 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1031 _time_discr->fillFromAnalytic3(loc,nbOfComp,varsOrder,func);
1035 * Applyies the function specified by pointer 'func' on each tuples on all arrays contained in _time_discr.
1036 * If '*func' returns false during one evaluation an exception will be thrown.
1038 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
1040 _time_discr->applyFunc(nbOfComp,func);
1044 * This method is a specialization of other overloaded methods. When 'nbOfComp' equals 1 this method is equivalent to
1045 * ParaMEDMEM::MEDCouplingFieldDouble::operator=.
1047 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
1050 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
1051 int nbOfTuple=_type->getNumberOfTuples(_mesh);
1052 _time_discr->setUniformValue(nbOfTuple,nbOfComp,val);
1056 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1057 * If '*func' fails in evaluation during one evaluation an exception will be thrown.
1058 * The field will contain 'nbOfComp' components after the call.
1060 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
1062 _time_discr->applyFunc(nbOfComp,func);
1066 * This method is equivalent to MEDCouplingFieldDouble::applyFunc, except that here components info are used to determine variables position in 'func'.
1067 * If there is vars detected in 'func' that is not in an info on components an exception will be thrown.
1069 void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
1071 _time_discr->applyFunc2(nbOfComp,func);
1075 * This method is equivalent to MEDCouplingFieldDouble::applyFunc, except that here 'varsOrder' is used to determine variables position in 'func'.
1076 * If there is vars detected in 'func' that is not in 'varsOrder' an exception will be thrown.
1078 void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) throw(INTERP_KERNEL::Exception)
1080 _time_discr->applyFunc3(nbOfComp,varsOrder,func);
1084 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1085 * If '*func' fails in evaluation during one evaluation an exception will be thrown.
1086 * The field will contain exactly the same number of components after the call.
1088 void MEDCouplingFieldDouble::applyFunc(const char *func) throw(INTERP_KERNEL::Exception)
1090 _time_discr->applyFunc(func);
1094 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1095 * The field will contain exactly the same number of components after the call.
1096 * Use is not warranted for the moment !
1098 void MEDCouplingFieldDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
1100 _time_discr->applyFuncFast32(func);
1104 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1105 * The field will contain exactly the same number of components after the call.
1106 * Use is not warranted for the moment !
1108 void MEDCouplingFieldDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
1110 _time_discr->applyFuncFast64(func);
1114 * This method makes the assumption that the default array has been set before.
1115 * If not an exception will be sent.
1116 * If default array set, the number of components will be sent.
1118 int MEDCouplingFieldDouble::getNumberOfComponents() const throw(INTERP_KERNEL::Exception)
1121 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
1122 return getArray()->getNumberOfComponents();
1126 * This method makes the assumption that _mesh has be set before the call of this method and description of gauss
1127 * localizations in case of Gauss field. If not an exception will sent.
1128 * \b Contrary to MEDCouplingFieldDouble::getNumberOfComponents and MEDCouplingFieldDouble::getNumberOfValues is
1129 * \b not aware of the presence of the default array.
1130 * \b WARNING \b no coherency check is done here. MEDCouplingFieldDouble::checkCoherency method should be called to check that !
1132 int MEDCouplingFieldDouble::getNumberOfTuples() const throw(INTERP_KERNEL::Exception)
1135 throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
1136 return _type->getNumberOfTuples(_mesh);
1140 * This method makes the assumption that the default array has been set before.
1141 * If not an exception will be sent.
1142 * If default array set, the number of values present in the default array will be sent.
1144 int MEDCouplingFieldDouble::getNumberOfValues() const throw(INTERP_KERNEL::Exception)
1147 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
1148 return getArray()->getNbOfElems();
1151 void MEDCouplingFieldDouble::updateTime() const
1153 MEDCouplingField::updateTime();
1154 updateTimeWith(*_time_discr);
1157 std::size_t MEDCouplingFieldDouble::getHeapMemorySize() const
1161 ret+=_time_discr->getHeapMemorySize();
1162 return MEDCouplingField::getHeapMemorySize()+ret;
1165 void MEDCouplingFieldDouble::setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception)
1167 MEDCouplingField::setNature(nat);
1168 _type->checkCompatibilityWithNature(nat);
1172 * This method synchronizes time information (time, iteration, order, time unit) regarding the information in \c this->_mesh.
1173 * \throw If no mesh is set in this. Or if \a this is not compatible with time setting (typically NO_TIME)
1175 void MEDCouplingFieldDouble::synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception)
1178 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::synchronizeTimeWithMesh : no mesh set in this !");
1180 double val=_mesh->getTime(it,ordr);
1181 std::string timeUnit(_mesh->getTimeUnit());
1182 setTime(val,it,ordr);
1183 setTimeUnit(timeUnit.c_str());
1186 double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
1188 return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
1191 void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
1193 _time_discr->setArray(array,this);
1196 void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
1198 _time_discr->setEndArray(array,this);
1201 void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs) throw(INTERP_KERNEL::Exception)
1203 _time_discr->setArrays(arrs,this);
1206 void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
1209 _time_discr->getTinySerializationStrInformation(tinyInfo);
1210 tinyInfo.push_back(_name);
1211 tinyInfo.push_back(_desc);
1212 tinyInfo.push_back(getTimeUnit());
1216 * This method retrieves some critical values to resize and prepare remote instance.
1217 * The first two elements returned in tinyInfo correspond to the parameters to give in constructor.
1218 * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1220 void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
1223 tinyInfo.push_back((int)_type->getEnum());
1224 tinyInfo.push_back((int)_time_discr->getEnum());
1225 tinyInfo.push_back((int)_nature);
1226 _time_discr->getTinySerializationIntInformation(tinyInfo);
1227 std::vector<int> tinyInfo2;
1228 _type->getTinySerializationIntInformation(tinyInfo2);
1229 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1230 tinyInfo.push_back((int)tinyInfo2.size());
1234 * This method retrieves some critical values to resize and prepare remote instance.
1235 * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1237 void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
1240 _time_discr->getTinySerializationDbleInformation(tinyInfo);
1241 std::vector<double> tinyInfo2;
1242 _type->getTinySerializationDbleInformation(tinyInfo2);
1243 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1244 tinyInfo.push_back((int)tinyInfo2.size());//very bad, lack of time to improve it
1248 * This method has to be called to the new instance filled by CORBA, MPI, File...
1249 * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied.
1250 * @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.
1251 * @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.
1252 * No decrRef must be applied to every instances in returned vector.
1254 void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays)
1257 std::vector<int> tinyInfoITmp(tinyInfoI);
1258 int sz=tinyInfoITmp.back();
1259 tinyInfoITmp.pop_back();
1260 std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz);
1261 std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end());
1262 _time_discr->resizeForUnserialization(tinyInfoI2,arrays);
1263 std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end());
1264 _type->resizeForUnserialization(tinyInfoITmp3,dataInt);
1267 void MEDCouplingFieldDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS)
1269 std::vector<int> tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end());
1271 std::vector<double> tmp(tinyInfoD);
1272 int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it
1274 std::vector<double> tmp1(tmp.begin(),tmp.end()-sz);
1275 std::vector<double> tmp2(tmp.end()-sz,tmp.end());
1277 _time_discr->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS);
1278 _nature=(NatureOfField)tinyInfoI[2];
1279 _type->finishUnserialization(tmp2);
1280 int nbOfElemS=(int)tinyInfoS.size();
1281 _name=tinyInfoS[nbOfElemS-3];
1282 _desc=tinyInfoS[nbOfElemS-2];
1283 setTimeUnit(tinyInfoS[nbOfElemS-1].c_str());
1287 * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller.
1288 * The values returned must be consulted only in readonly mode.
1290 void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) const
1292 _time_discr->getArrays(arrays);
1293 _type->getSerializationIntArray(dataInt);
1297 * This method tries to to change the mesh support of \a this following the parameter 'levOfCheck' and 'prec'.
1298 * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method. This method is used to perform the job.
1299 * If this->_mesh is not defined or other an exeption will be throw.
1301 void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception)
1303 if(_mesh==0 || other==0)
1304 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
1305 DataArrayInt *cellCor=0,*nodeCor=0;
1306 other->checkGeoEquivalWith(_mesh,levOfCheck,prec,cellCor,nodeCor);
1307 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2(cellCor),nodeCor2(nodeCor);
1309 renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
1311 renumberNodesWithoutMesh(nodeCor->getConstPointer(),_mesh->getNumberOfNodes());
1312 setMesh(const_cast<MEDCouplingMesh *>(other));
1316 * 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.
1317 * 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.
1318 * This method requires that 'f' and \a this are coherent (check coherency) and that 'f' and \a this would be coherent for a merge.
1319 * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method.
1321 void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception)
1324 f->checkCoherency();
1325 if(!areCompatibleForMerge(f))
1326 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::diffWith : Fields are not compatible ; unable to apply mergeFields on them !");
1327 changeUnderlyingMesh(f->getMesh(),levOfCheck,prec);
1332 * Merge nodes of underlying mesh. In case of some node will be merged the underlying mesh instance will change.
1333 * The first 'eps' stands for geometric approximation. The second 'epsOnVals' is for epsilon on values in case of node merging.
1334 * If 2 nodes distant from less than 'eps' and with value different with more than 'epsOnVals' an exception will be thrown.
1336 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals) throw(INTERP_KERNEL::Exception)
1338 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1340 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1341 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1344 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2);
1345 if(!ret)//no nodes have been merged.
1347 std::vector<DataArrayDouble *> arrays;
1348 _time_discr->getArrays(arrays);
1349 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1351 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1357 * Merge nodes with (barycenter computation) of underlying mesh. In case of some node will be merged the underlying mesh instance will change.
1358 * The first 'eps' stands for geometric approximation. The second 'epsOnVals' is for epsilon on values in case of node merging.
1359 * If 2 nodes distant from less than 'eps' and with value different with more than 'epsOnVals' an exception will be thrown.
1361 bool MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals) throw(INTERP_KERNEL::Exception)
1363 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1365 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1366 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1369 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes2(eps,ret,ret2);
1370 if(!ret)//no nodes have been merged.
1372 std::vector<DataArrayDouble *> arrays;
1373 _time_discr->getArrays(arrays);
1374 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1376 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1382 * This method applyies ParaMEDMEM::MEDCouplingPointSet::zipCoords method on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingPointSet.
1383 * If some nodes have disappeared true is returned.
1384 * 'epsOnVals' stands for epsilon in case of merge of cells. This value is used as tolerance in case the corresponding values differ.
1386 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals) throw(INTERP_KERNEL::Exception)
1388 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1390 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1391 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1392 int oldNbOfNodes=meshC2->getNumberOfNodes();
1393 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipCoordsTraducer();
1394 if(meshC2->getNumberOfNodes()!=oldNbOfNodes)
1396 std::vector<DataArrayDouble *> arrays;
1397 _time_discr->getArrays(arrays);
1398 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1400 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1408 * This method applyies ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingUMesh.
1409 * The semantic of 'compType' is given in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer method.
1410 * 'epsOnVals' stands for epsilon in case of merge of cells. This value is used as tolerance in case the corresponding values differ.
1412 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals) throw(INTERP_KERNEL::Exception)
1414 const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
1416 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1417 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCpy());
1418 int oldNbOfCells=meshC2->getNumberOfCells();
1419 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipConnectivityTraducer(compType);
1420 if(meshC2->getNumberOfCells()!=oldNbOfCells)
1422 std::vector<DataArrayDouble *> arrays;
1423 _time_discr->getArrays(arrays);
1424 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1426 _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter);
1434 * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists.
1435 * For the moment, this method is implemented for fields on cells.
1437 * \return a newly allocated field double containing the result that the user should deallocate.
1439 MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const throw(INTERP_KERNEL::Exception)
1441 const MEDCouplingMesh *mesh=getMesh();
1443 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !");
1444 if(getTypeOfField()!=ON_CELLS)
1445 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !");
1446 const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1447 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=clone(false);
1448 ret->setMesh(umesh);
1449 DataArrayInt *cellIds=0;
1450 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds);
1451 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds2=cellIds;
1452 ret->setMesh(mesh2);
1453 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end());
1454 std::vector<DataArrayDouble *> arrays;
1455 _time_discr->getArrays(arrays);
1457 std::vector<DataArrayDouble *> newArr(arrays.size());
1458 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > newArr2(arrays.size());
1459 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++)
1463 newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
1464 newArr[i]=newArr2[i];
1467 ret->setArrays(newArr);
1472 * This method applyies ParaMEDMEM::MEDCouplingUMesh::simplexize on 'this->_mesh'.
1473 * The semantic of 'policy' is given in ParaMEDMEM::MEDCouplingUMesh::simplexize method.
1475 bool MEDCouplingFieldDouble::simplexize(int policy) throw(INTERP_KERNEL::Exception)
1477 int oldNbOfCells=_mesh->getNumberOfCells();
1478 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> meshC2(_mesh->deepCpy());
1479 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->simplexize(policy);
1480 int newNbOfCells=meshC2->getNumberOfCells();
1481 if(oldNbOfCells==newNbOfCells)
1483 std::vector<DataArrayDouble *> arrays;
1484 _time_discr->getArrays(arrays);
1485 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1487 _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter);
1492 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
1494 MEDCouplingTimeDiscretization *td=_time_discr->doublyContractedProduct();
1495 td->copyTinyAttrFrom(*_time_discr);
1496 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1497 ret->setName("DoublyContractedProduct");
1498 ret->setMesh(getMesh());
1502 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const throw(INTERP_KERNEL::Exception)
1504 MEDCouplingTimeDiscretization *td=_time_discr->determinant();
1505 td->copyTinyAttrFrom(*_time_discr);
1506 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1507 ret->setName("Determinant");
1508 ret->setMesh(getMesh());
1512 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
1514 MEDCouplingTimeDiscretization *td=_time_discr->eigenValues();
1515 td->copyTinyAttrFrom(*_time_discr);
1516 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1517 ret->setName("EigenValues");
1518 ret->setMesh(getMesh());
1522 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
1524 MEDCouplingTimeDiscretization *td=_time_discr->eigenVectors();
1525 td->copyTinyAttrFrom(*_time_discr);
1526 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1527 ret->setName("EigenVectors");
1528 ret->setMesh(getMesh());
1532 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const throw(INTERP_KERNEL::Exception)
1534 MEDCouplingTimeDiscretization *td=_time_discr->inverse();
1535 td->copyTinyAttrFrom(*_time_discr);
1536 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1537 ret->setName("Inversion");
1538 ret->setMesh(getMesh());
1542 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const throw(INTERP_KERNEL::Exception)
1544 MEDCouplingTimeDiscretization *td=_time_discr->trace();
1545 td->copyTinyAttrFrom(*_time_discr);
1546 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1547 ret->setName("Trace");
1548 ret->setMesh(getMesh());
1552 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const throw(INTERP_KERNEL::Exception)
1554 MEDCouplingTimeDiscretization *td=_time_discr->deviator();
1555 td->copyTinyAttrFrom(*_time_discr);
1556 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1557 ret->setName("Trace");
1558 ret->setMesh(getMesh());
1562 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const throw(INTERP_KERNEL::Exception)
1564 MEDCouplingTimeDiscretization *td=_time_discr->magnitude();
1565 td->copyTinyAttrFrom(*_time_discr);
1566 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1567 ret->setName("Magnitude");
1568 ret->setMesh(getMesh());
1572 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
1574 MEDCouplingTimeDiscretization *td=_time_discr->maxPerTuple();
1575 td->copyTinyAttrFrom(*_time_discr);
1576 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1577 std::ostringstream oss;
1578 oss << "Max_" << getName();
1579 ret->setName(oss.str().c_str());
1580 ret->setMesh(getMesh());
1584 void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception)
1586 _time_discr->changeNbOfComponents(newNbOfComp,dftValue);
1589 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1591 MEDCouplingTimeDiscretization *td=_time_discr->keepSelectedComponents(compoIds);
1592 td->copyTinyAttrFrom(*_time_discr);
1593 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1594 ret->setName(getName());
1595 ret->setMesh(getMesh());
1599 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
1601 _time_discr->setSelectedComponents(f->_time_discr,compoIds);
1604 void MEDCouplingFieldDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
1606 _time_discr->sortPerTuple(asc);
1609 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1611 if(!f1->areCompatibleForMerge(f2))
1612 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !");
1613 const MEDCouplingMesh *m1=f1->getMesh();
1614 const MEDCouplingMesh *m2=f2->getMesh();
1615 MEDCouplingMesh *m=m1->mergeMyselfWith(m2);
1616 MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr);
1617 td->copyTinyAttrFrom(*f1->_time_discr);
1618 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1621 ret->setName(f1->getName());
1622 ret->setDescription(f1->getDescription());
1627 * This method returns a newly created field that is the union of all fields in input array 'a'.
1628 * This method expects that 'a' is non empty. If not an exception will be thrown.
1629 * 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.
1630 * Generally speaking the first instance field in 'a' will be used to assign tiny attributes of returned field.
1632 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a) throw(INTERP_KERNEL::Exception)
1635 throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !");
1636 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms(a.size());
1637 std::vector< const MEDCouplingUMesh *> ms2(a.size());
1638 std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
1639 std::vector<const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
1640 const MEDCouplingFieldDouble *ref=(*it++);
1641 for(;it!=a.end();it++)
1642 if(!ref->areCompatibleForMerge(*it))
1643 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !");
1644 for(int i=0;i<(int)a.size();i++)
1646 if(!a[i]->getMesh())
1647 throw INTERP_KERNEL::Exception("MergeFields : A field as no underlying mesh !");
1648 ms[i]=a[i]->getMesh()->buildUnstructured();
1650 tds[i]=a[i]->_time_discr;
1652 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::MergeUMeshes(ms2);
1653 m->setName(ms2[0]->getName()); m->setDescription(ms2[0]->getDescription());
1654 MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds);
1655 td->copyTinyAttrFrom(*(a[0]->_time_discr));
1656 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone());
1658 ret->setName(a[0]->getName());
1659 ret->setDescription(a[0]->getDescription());
1663 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1665 if(!f1->areCompatibleForMeld(f2))
1666 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MeldFields on them !");
1667 MEDCouplingTimeDiscretization *td=f1->_time_discr->meld(f2->_time_discr);
1668 td->copyTinyAttrFrom(*f1->_time_discr);
1669 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1670 ret->setMesh(f1->getMesh());
1674 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1676 if(!f1->areStrictlyCompatible(f2))
1677 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DotFields on them !");
1678 MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr);
1679 td->copyTinyAttrFrom(*f1->_time_discr);
1680 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1681 ret->setMesh(f1->getMesh());
1685 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1687 if(!f1->areStrictlyCompatible(f2))
1688 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply CrossProductFields on them !");
1689 MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr);
1690 td->copyTinyAttrFrom(*f1->_time_discr);
1691 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1692 ret->setMesh(f1->getMesh());
1696 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1698 if(!f1->areStrictlyCompatible(f2))
1699 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MaxFields on them !");
1700 MEDCouplingTimeDiscretization *td=f1->_time_discr->max(f2->_time_discr);
1701 td->copyTinyAttrFrom(*f1->_time_discr);
1702 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1703 ret->setMesh(f1->getMesh());
1707 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1709 if(!f1->areStrictlyCompatible(f2))
1710 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MinFields on them !");
1711 MEDCouplingTimeDiscretization *td=f1->_time_discr->min(f2->_time_discr);
1712 td->copyTinyAttrFrom(*f1->_time_discr);
1713 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1714 ret->setMesh(f1->getMesh());
1718 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1720 if(!f1->areStrictlyCompatible(f2))
1721 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply AddFields on them !");
1722 MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr);
1723 td->copyTinyAttrFrom(*f1->_time_discr);
1724 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1725 ret->setMesh(f1->getMesh());
1729 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1731 if(!areStrictlyCompatible(&other))
1732 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply += on them !");
1733 _time_discr->addEqual(other._time_discr);
1737 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1739 if(!f1->areStrictlyCompatible(f2))
1740 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply SubstractFields on them !");
1741 MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(f2->_time_discr);
1742 td->copyTinyAttrFrom(*f1->_time_discr);
1743 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1744 ret->setMesh(f1->getMesh());
1748 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1750 if(!areStrictlyCompatible(&other))
1751 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply -= on them !");
1752 _time_discr->substractEqual(other._time_discr);
1756 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1758 if(!f1->areCompatibleForMul(f2))
1759 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MultiplyFields on them !");
1760 MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr);
1761 td->copyTinyAttrFrom(*f1->_time_discr);
1762 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1763 ret->setMesh(f1->getMesh());
1767 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1769 if(!areCompatibleForMul(&other))
1770 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply *= on them !");
1771 _time_discr->multiplyEqual(other._time_discr);
1775 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1777 if(!f1->areCompatibleForDiv(f2))
1778 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DivideFields on them !");
1779 MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(f2->_time_discr);
1780 td->copyTinyAttrFrom(*f1->_time_discr);
1781 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1782 ret->setMesh(f1->getMesh());
1786 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1788 if(!areCompatibleForDiv(&other))
1789 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !");
1790 _time_discr->divideEqual(other._time_discr);
1795 * This method writes the field series 'fs' in the VTK file 'fileName'.
1796 * 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.
1797 * If the single mesh is empty an exception will be thrown.
1798 * Finally there is a field in 'fs' with no name an exception will be thrown too.
1800 void MEDCouplingFieldDouble::WriteVTK(const char *fileName, const std::vector<const MEDCouplingFieldDouble *>& fs) throw(INTERP_KERNEL::Exception)
1804 std::size_t nfs=fs.size();
1805 const MEDCouplingMesh *m=fs[0]->getMesh();
1806 for(std::size_t i=1;i<nfs;i++)
1807 if(fs[i]->getMesh()!=m)
1808 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.");
1810 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !");
1811 std::ostringstream coss,noss;
1812 for(std::size_t i=0;i<nfs;i++)
1814 const MEDCouplingFieldDouble *cur=fs[i];
1815 std::string name(cur->getName());
1818 std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
1819 throw INTERP_KERNEL::Exception(oss.str().c_str());
1821 TypeOfField typ=cur->getTypeOfField();
1823 cur->getArray()->writeVTK(coss,8,cur->getName());
1824 else if(typ==ON_NODES)
1825 cur->getArray()->writeVTK(noss,8,cur->getName());
1827 m->writeVTKAdvanced(fileName,coss.str(),noss.str());