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"
34 using namespace ParaMEDMEM;
37 * Creates a new instance of MEDCouplingFieldDouble of given type. The caller is responsable for the returned field.
39 * \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").
40 * \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").
42 * \return a newly allocated field the caller should deal with.
44 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td)
46 return new MEDCouplingFieldDouble(type,td);
50 * Creates a new instance of MEDCouplingFieldDouble of given type. The caller is responsable for the returned field.
52 * \param [in] ft \ref MEDCouplingFieldTemplatesPage "field template" defining its spatial discretization and supporting mesh.
53 * \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")
55 * \return a newly allocated field the caller should deal with.
57 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td)
59 return new MEDCouplingFieldDouble(ft,td);
63 * Sets time \a unit of \a this field.
65 * \param [in] unit \a unit (string) in which time is measured.
67 void MEDCouplingFieldDouble::setTimeUnit(const char *unit)
69 _time_discr->setTimeUnit(unit);
73 * Returns a time unit of \a this field.
75 * \return a string describing units in which time is measured.
77 const char *MEDCouplingFieldDouble::getTimeUnit() const
79 return _time_discr->getTimeUnit();
83 * This method if possible the time information (time unit, time iteration, time unit and time value) with its support
84 * that is to say its mesh.
86 * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is
89 void MEDCouplingFieldDouble::synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception)
91 _time_discr->synchronizeTimeWith(_mesh);
95 * This method performs a copy of \a this **without any copy of the underlying mesh** ( see warning section of this method).
96 * The copy of arrays is deep if \b recDeepCpy equals to true, no copy of arrays is done if \b recDeepCpy equals to false.
98 * \c clone(false) is rather dedicated for advanced users that want to limit the amount of memory.
100 * It allows the user to perform methods
101 * MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields with \a this and the returned field.
103 * \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.
104 * If the user wants to duplicated deeply the underlying mesh he should call MEDCouplingFieldDouble::cloneWithMesh method or MEDCouplingFieldDouble::deepCpy instead.
106 * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied or only attached to the returned field.
107 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
108 * \sa ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
110 MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
112 return new MEDCouplingFieldDouble(*this,recDeepCpy);
116 * This method behaves exactly like MEDCouplingFieldDouble::clone method **except that here the underlying mesh is systematically **
117 * (whatever the value of the input parameter \a recDeepCpy) **deeply duplicated**.
119 * The result of \c cloneWithMesh(true) is exactly the same than calling \ref MEDCouplingFieldDouble::deepCpy "deepCpy".
121 * So the resulting field of this call cannot be called with \a this with the following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ...
122 * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
124 * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied or only attached to the returned field.
125 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
126 * \sa ParaMEDMEM::MEDCouplingFieldDouble::clone(bool recDeepCpy) const
128 MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
130 MEDCouplingFieldDouble *ret=clone(recDeepCpy);
133 MEDCouplingMesh *mCpy=_mesh->deepCpy();
141 * This method performs a deepCpy of \a this (**mesh included**)!
142 * So the resulting field of this call cannot be called with \a this with following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ...
143 * To avoid deep copying the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
144 * This method is exactly equivalent to MEDCouplingFieldDouble::cloneWithMesh called with parameter true.
146 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
147 * \sa ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
149 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const
151 return cloneWithMesh(true);
157 * \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").
158 * \param [in] deepCopy specifies if underlying arrays in \a this should be copied or only attached to the returned field.
159 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
161 * \ref cpp_mcfielddouble_buildnewtimereprfromthis "Here a C++ example."
163 * \ref py_mcfielddouble_buildnewtimereprfromthis "Here a Python example."
164 * \sa ParaMEDMEM::MEDCouplingFieldDouble::clone(bool recDeepCpy) const
166 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const
168 MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(td,deepCopy);
169 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),tdo,_type->clone());
170 ret->setMesh(getMesh());
171 ret->setName(getName());
172 ret->setDescription(getDescription());
177 * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason).
179 void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
183 setName(other->_name.c_str());
184 setDescription(other->_desc.c_str());
185 _time_discr->copyTinyStringsFrom(*other->_time_discr);
190 * Copy only times, order, iteration from other. The underlying mesh is not impacted by this method.
191 * Arrays are not impacted too.
193 void MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
197 _time_discr->copyTinyAttrFrom(*other->_time_discr);
201 std::string MEDCouplingFieldDouble::simpleRepr() const
203 std::ostringstream ret;
204 ret << "FieldDouble with name : \"" << getName() << "\"\n";
205 ret << "Description of field is : \"" << getDescription() << "\"\n";
206 ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
207 ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
208 ret << "FieldDouble nature of field is : " << MEDCouplingNatureOfField::getRepr(_nature) << "\n";
211 int nbOfCompo=getArray()->getNumberOfComponents();
212 ret << "FieldDouble default array has " << nbOfCompo << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
213 ret << "FieldDouble default array has following info on components : ";
214 for(int i=0;i<nbOfCompo;i++)
215 ret << "\"" << getArray()->getInfoOnComponent(i) << "\" ";
219 ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr();
221 ret << "Mesh support information : No mesh set !\n";
225 std::string MEDCouplingFieldDouble::advancedRepr() const
227 std::ostringstream ret;
228 ret << "FieldDouble with name : \"" << getName() << "\"\n";
229 ret << "Description of field is : \"" << getDescription() << "\"\n";
230 ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
231 ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
233 ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
235 ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr();
237 ret << "Mesh support information : No mesh set !\n";
238 std::vector<DataArrayDouble *> arrays;
239 _time_discr->getArrays(arrays);
241 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++)
243 ret << "Array #" << arrayId << " :\n__________\n";
245 (*iter)->reprWithoutNameStream(ret);
247 ret << "Array empty !";
253 void MEDCouplingFieldDouble::writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception)
255 std::vector<const MEDCouplingFieldDouble *> fs(1,this);
256 MEDCouplingFieldDouble::WriteVTK(fileName,fs);
259 bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception)
262 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::isEqualIfNotWhy : other instance is NULL !");
263 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
266 reason="field given in input is not castable in MEDCouplingFieldDouble !";
269 if(!MEDCouplingField::isEqualIfNotWhy(other,meshPrec,valsPrec,reason))
271 if(!_time_discr->isEqualIfNotWhy(otherC->_time_discr,valsPrec,reason))
273 reason.insert(0,"In FieldDouble time discretizations differ :");
279 bool MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const
281 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
284 if(!MEDCouplingField::isEqualWithoutConsideringStr(other,meshPrec,valsPrec))
286 if(!_time_discr->isEqualWithoutConsideringStr(otherC->_time_discr,valsPrec))
292 * This method states if \a this and 'other' are compatibles each other before performing any treatment.
293 * This method is good for methods like : mergeFields.
294 * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields.
296 bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const
298 if(!MEDCouplingField::areCompatibleForMerge(other))
300 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
303 if(!_time_discr->areCompatible(otherC->_time_discr))
309 * This method is more strict than MEDCouplingField::areCompatibleForMerge method.
310 * This method is used for operation on fields to operate a first check before attempting operation.
312 bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const
315 if(!MEDCouplingField::areStrictlyCompatible(other))
317 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
320 if(!_time_discr->areStrictlyCompatible(otherC->_time_discr,tmp))
326 * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
327 * number of components between \a this and 'other' can be different here (for operator*).
329 bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const
331 if(!MEDCouplingField::areStrictlyCompatible(other))
333 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
336 if(!_time_discr->areStrictlyCompatibleForMul(otherC->_time_discr))
342 * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
343 * number of components between \a this and 'other' can be different here (for operator/).
345 bool MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const
347 if(!MEDCouplingField::areStrictlyCompatible(other))
349 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
352 if(!_time_discr->areStrictlyCompatibleForDiv(otherC->_time_discr))
358 * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible,
359 * except that \a this and other can have different number of components.
361 bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const
363 if(!MEDCouplingField::areStrictlyCompatible(other))
365 if(!_time_discr->areCompatibleForMeld(other->_time_discr))
371 * This method performs a clone of mesh and a renumbering of underlying cells of it. The number of cells remains the same.
372 * The values of field are impacted in consequence to have the same geometrical field.
374 void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
376 renumberCellsWithoutMesh(old2NewBg,check);
377 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_mesh->deepCpy();
378 m->renumberCells(old2NewBg,check);
384 * \b WARNING : use this method with lot of care !
385 * This method performs half job of MEDCouplingFieldDouble::renumberCells. That is to say no permutation of cells is done on underlying mesh.
386 * 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
387 * avoid a systematic duplication and renumbering of _mesh attribute.
389 void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
392 throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !");
394 _type->renumberCells(old2NewBg,check);
395 std::vector<DataArrayDouble *> arrays;
396 _time_discr->getArrays(arrays);
397 _type->renumberArraysForCell(_mesh,arrays,old2NewBg,check);
403 * 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.
404 * The values of field are impacted in consequence to have the same geometrical field.
406 void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception)
408 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
410 throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !");
411 int nbOfNodes=meshC->getNumberOfNodes();
412 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
413 int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1;
414 renumberNodesWithoutMesh(old2NewBg,newNbOfNodes);
415 meshC2->renumberNodes(old2NewBg,newNbOfNodes);
420 * \b WARNING : use this method with lot of care !
421 * This method performs half job of MEDCouplingFieldDouble::renumberNodes. That is to say no permutation of cells is done on underlying mesh.
422 * That is to say, the field content is changed by this method.
424 void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps) throw(INTERP_KERNEL::Exception)
426 std::vector<DataArrayDouble *> arrays;
427 _time_discr->getArrays(arrays);
428 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
430 _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter);
434 * This method makes the assumption that the default array is set. If not an exception will be thrown.
435 * This method is usable only if the default array has exactly one component. If not an exception will be thrown too.
436 * This method returns all tuples ids that fit the range [vmin,vmax].
437 * The caller has the responsability of the returned DataArrayInt.
439 DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
442 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getIdsInRange : no default array set !");
443 return getArray()->getIdsInRange(vmin,vmax);
447 * Builds a newly created field, that the caller will have the responsability to deal with (decrRef).
448 * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done.
449 * This method returns a restriction of \a this so that only tuples id specified in 'part' will be contained in returned field.
450 * 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)
452 * If \a this is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6].
453 * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
454 * 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()'
455 * 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()'
456 * 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()'
458 * 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].
459 * \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,
460 * will contain 6 tuples and this field will lie on this restricted mesh.
462 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception)
465 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !");
466 const int *start=part->getConstPointer();
467 const int *end=start+part->getNbOfElems();
468 return buildSubPart(start,end);
472 * Builds a newly created field, that the caller will have the responsability to deal with.
473 * \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**.
474 * \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.
475 * \n Parameter [\a partBg, \a partEnd ) specifies \b cell \b ids \b whatever \b the \b spatial \b discretization of \a this
476 * (\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")
478 * If \a this is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6].
479 * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
481 *- 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()
482 *- 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()
483 *- 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()
485 * 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.
486 * \n If part contains following cellIds [3,7,6].
487 * \n If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, the returned field,
488 * will contain 6 tuples (and same number of components \c this->getArray()->getNumberOfComponents() ) and this field will lie on this restricted mesh.
490 * \param [in] partBg start (included) of input range cell ids to select [ \a partBg, \a partEnd )
491 * \param [in] partEnd end (not included) of input range cell ids to select [ \a partBg, \a partEnd )
492 * \return a newly allocated field the caller should deal with.
494 * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \c this->getMesh()
496 * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."
498 * \ref py_mcfielddouble_subpart1 "Here a Python example."
499 * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const
501 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception)
503 DataArrayInt *arrSelect;
504 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect);
505 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrSelect2(arrSelect);
506 MEDCouplingFieldDouble *ret=clone(false);//quick shallow copy.
507 const MEDCouplingFieldDiscretization *disc=getDiscretization();
509 ret->setDiscretization(disc->clonePart(partBg,partEnd));
511 std::vector<DataArrayDouble *> arrays;
512 _time_discr->getArrays(arrays);
513 std::vector<DataArrayDouble *> arrs;
514 const int *arrSelBg=arrSelect->begin();
515 const int *arrSelEnd=arrSelect->end();
516 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
518 DataArrayDouble *arr=0;
520 arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd);
523 ret->_time_discr->setArrays(arrs,0);
524 for(std::vector<DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
530 TypeOfTimeDiscretization MEDCouplingFieldDouble::getTimeDiscretization() const
532 return _time_discr->getEnum();
535 MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingField(type),
536 _time_discr(MEDCouplingTimeDiscretization::New(td))
540 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td):MEDCouplingField(*ft),
541 _time_discr(MEDCouplingTimeDiscretization::New(td))
545 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other),
546 _time_discr(other._time_discr->performCpy(deepCopy))
550 MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingField(type,n),_time_discr(td)
554 MEDCouplingFieldDouble::~MEDCouplingFieldDouble()
559 void MEDCouplingFieldDouble::checkCoherency() const throw(INTERP_KERNEL::Exception)
562 throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !");
563 _time_discr->checkCoherency();
564 _type->checkCoherencyBetween(_mesh,getArray());
568 * Returns the accumulation (the sum) of comId_th component of each tuples of \b default and \b only \b default array.
570 double MEDCouplingFieldDouble::accumulate(int compId) const
573 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
574 return getArray()->accumulate(compId);
578 * Returns the accumulation (the sum) of all tuples of \b default and \b only default array.
579 * The res is expected to be of size getNumberOfComponents().
581 void MEDCouplingFieldDouble::accumulate(double *res) const
584 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
585 getArray()->accumulate(res);
589 * 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.
590 * To getMaxValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'.
591 * If no arrays exists, an exception will be thrown.
593 double MEDCouplingFieldDouble::getMaxValue() const throw(INTERP_KERNEL::Exception)
595 std::vector<DataArrayDouble *> arrays;
596 _time_discr->getArrays(arrays);
597 double ret=-std::numeric_limits<double>::max();
598 bool isExistingArr=false;
599 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
605 ret=std::max(ret,(*iter)->getMaxValue(loc));
609 throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !");
614 * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMaxValue method because the returned
615 * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility
616 * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array.
617 * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used
618 * to compute tupleIds.
620 double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
622 std::vector<DataArrayDouble *> arrays;
623 _time_discr->getArrays(arrays);
624 double ret=-std::numeric_limits<double>::max();
625 bool isExistingArr=false;
627 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
633 ret=std::max(ret,(*iter)->getMaxValue2(tmp));
641 throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !");
646 * 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.
647 * To getMinValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'.
648 * If no arrays exists, an exception will be thrown.
650 double MEDCouplingFieldDouble::getMinValue() const throw(INTERP_KERNEL::Exception)
652 std::vector<DataArrayDouble *> arrays;
653 _time_discr->getArrays(arrays);
654 double ret=std::numeric_limits<double>::max();
655 bool isExistingArr=false;
656 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
662 ret=std::min(ret,(*iter)->getMinValue(loc));
666 throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !");
671 * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMinValue method because the returned
672 * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility
673 * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array.
674 * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used
675 * to compute tupleIds.
677 double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
679 std::vector<DataArrayDouble *> arrays;
680 _time_discr->getArrays(arrays);
681 double ret=-std::numeric_limits<double>::max();
682 bool isExistingArr=false;
684 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
690 ret=std::max(ret,(*iter)->getMinValue2(tmp));
698 throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !");
703 * 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.
704 * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
705 * If default array does not exist, an exception will be thrown.
707 double MEDCouplingFieldDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
710 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !");
711 return getArray()->getAverageValue();
715 * This method returns the euclidean norm of \a this.
717 * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]}
719 * If default array does not exist, an exception will be thrown.
721 double MEDCouplingFieldDouble::norm2() const throw(INTERP_KERNEL::Exception)
724 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !");
725 return getArray()->norm2();
729 * This method returns the max norm of \a this.
731 * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
733 * If default array does not exist, an exception will be thrown.
735 double MEDCouplingFieldDouble::normMax() const throw(INTERP_KERNEL::Exception)
738 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
739 return getArray()->normMax();
743 * This method returns the average value in \a this weighted by ParaMEDMEM::MEDCouplingField::buildMeasureField.
744 * \a this is expected to be a field with exactly \b one component. If not an exception will be thrown.
745 * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
746 * If default array does not exist, an exception will be thrown.
748 double MEDCouplingFieldDouble::getWeightedAverageValue() const throw(INTERP_KERNEL::Exception)
751 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
752 MEDCouplingFieldDouble *w=buildMeasureField(true);
753 double deno=w->getArray()->accumulate(0);
754 w->getArray()->multiplyEqual(getArray());
755 double res=w->getArray()->accumulate(0);
761 * Returns the normL1 of current field on compId component :
763 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
765 * If compId>=nbOfComponent an exception is thrown.
767 double MEDCouplingFieldDouble::normL1(int compId) const throw(INTERP_KERNEL::Exception)
770 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
771 int nbComps=getArray()->getNumberOfComponents();
773 throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
774 double *res=new double[nbComps];
777 _type->normL1(_mesh,getArray(),res);
779 catch(INTERP_KERNEL::Exception& e)
784 double ret=res[compId];
790 * Returns the normL1 of current field on each components :
792 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
794 * The res is expected to be of size getNumberOfComponents().
796 void MEDCouplingFieldDouble::normL1(double *res) const throw(INTERP_KERNEL::Exception)
799 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
800 _type->normL1(_mesh,getArray(),res);
804 * Returns the normL2 of current field on compId component :
806 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
808 * If compId>=nbOfComponent an exception is thrown.
810 double MEDCouplingFieldDouble::normL2(int compId) const throw(INTERP_KERNEL::Exception)
813 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
814 int nbComps=getArray()->getNumberOfComponents();
816 throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
817 double *res=new double[nbComps];
820 _type->normL2(_mesh,getArray(),res);
822 catch(INTERP_KERNEL::Exception& e)
827 double ret=res[compId];
833 * Returns the normL2 of current field on each components :
835 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
837 * The res is expected to be of size getNumberOfComponents().
839 void MEDCouplingFieldDouble::normL2(double *res) const throw(INTERP_KERNEL::Exception)
842 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
843 _type->normL2(_mesh,getArray(),res);
847 * Returns the accumulation (the sum) of comId_th component of each tuples weigthed by the field
848 * returns by getWeightingField relative of the _type of field of default array.
849 * This method is usefull to check the conservativity of interpolation method.
851 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception)
854 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
855 int nbComps=getArray()->getNumberOfComponents();
857 throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
858 double *res=new double[nbComps];
861 _type->integral(_mesh,getArray(),isWAbs,res);
863 catch(INTERP_KERNEL::Exception& e)
868 double ret=res[compId];
874 * Returns the accumulation (the sum) of each tuples weigthed by the field
875 * returns by getWeightingField relative of the _type of field of default array.
876 * This method is usefull to check the conservativity of interpolation method.
878 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception)
881 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
882 _type->integral(_mesh,getArray(),isWAbs,res);
886 * This method is reserved for field lying on structured mesh spatial support. It returns the value of cell localized by (i,j,k)
887 * If spatial support is not structured mesh an exception will be thrown.
888 * @param res out array expected to be equal to size getNumberOfComponents()
890 void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const throw(INTERP_KERNEL::Exception)
892 const DataArrayDouble *arr=_time_discr->getArray();
894 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
895 _type->getValueOnPos(arr,_mesh,i,j,k,res);
899 * Returns value of \a this on default time of point 'spaceLoc' using spatial discretization.
900 * If 'point' is outside the spatial discretization of this an exception will be thrown.
902 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const throw(INTERP_KERNEL::Exception)
904 const DataArrayDouble *arr=_time_discr->getArray();
906 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
907 _type->getValueOn(arr,_mesh,spaceLoc,res);
911 * Returns a newly allocated array with 'nbOfPoints' tuples and nb of components equal to 'this->getNumberOfComponents()'.
913 DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const throw(INTERP_KERNEL::Exception)
915 const DataArrayDouble *arr=_time_discr->getArray();
917 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
918 return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
922 * Returns value of \a this on time 'time' of point 'spaceLoc' using spatial discretization.
923 * If 'time' is not covered by this->_time_discr an exception will be thrown.
924 * If 'point' is outside the spatial discretization of this an exception will be thrown.
926 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const throw(INTERP_KERNEL::Exception)
928 std::vector< const DataArrayDouble *> arrs=_time_discr->getArraysForTime(time);
930 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
931 std::vector<double> res2;
932 for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
934 int sz=(int)res2.size();
935 res2.resize(sz+(*iter)->getNumberOfComponents());
936 _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]);
938 _time_discr->getValueForTime(time,res2,res);
942 * Applies a*x+b on 'compoId'th component of each cell.
944 void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
946 _time_discr->applyLin(a,b,compoId);
950 * This method sets \a this to a uniform scalar field with one component.
951 * All tuples will have the same value 'value'.
952 * An exception is thrown if no underlying mesh is defined.
954 MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) throw(INTERP_KERNEL::Exception)
957 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
958 int nbOfTuple=_type->getNumberOfTuples(_mesh);
959 _time_discr->setUniformValue(nbOfTuple,1,value);
964 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic.
965 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
966 * The main difference is that the field as been started to be constructed here.
967 * An exception is thrown if no underlying mesh is set before the call of this method.
969 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception)
972 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
973 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
974 _time_discr->fillFromAnalytic(loc,nbOfComp,func);
978 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic.
979 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
980 * The main difference is that the field as been started to be constructed here.
981 * An exception is thrown if no underlying mesh is set before the call of this method.
983 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
986 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
987 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
988 _time_discr->fillFromAnalytic(loc,nbOfComp,func);
992 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic2.
993 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
994 * The main difference is that the field as been started to be constructed here.
995 * An exception is throw if no underlying mesh is set before the call of this method.
997 void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
1000 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !");
1001 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1002 _time_discr->fillFromAnalytic2(loc,nbOfComp,func);
1006 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic3.
1007 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
1008 * The main difference is that the field as been started to be constructed here.
1009 * An exception is thrown if no underlying mesh is set before the call of this method.
1011 void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) throw(INTERP_KERNEL::Exception)
1014 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !");
1015 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
1016 _time_discr->fillFromAnalytic3(loc,nbOfComp,varsOrder,func);
1020 * Applyies the function specified by pointer 'func' on each tuples on all arrays contained in _time_discr.
1021 * If '*func' returns false during one evaluation an exception will be thrown.
1023 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
1025 _time_discr->applyFunc(nbOfComp,func);
1029 * This method is a specialization of other overloaded methods. When 'nbOfComp' equals 1 this method is equivalent to
1030 * ParaMEDMEM::MEDCouplingFieldDouble::operator=.
1032 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
1035 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
1036 int nbOfTuple=_type->getNumberOfTuples(_mesh);
1037 _time_discr->setUniformValue(nbOfTuple,nbOfComp,val);
1041 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1042 * If '*func' fails in evaluation during one evaluation an exception will be thrown.
1043 * The field will contain 'nbOfComp' components after the call.
1045 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
1047 _time_discr->applyFunc(nbOfComp,func);
1051 * This method is equivalent to MEDCouplingFieldDouble::applyFunc, except that here components info are used to determine variables position in 'func'.
1052 * If there is vars detected in 'func' that is not in an info on components an exception will be thrown.
1054 void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
1056 _time_discr->applyFunc2(nbOfComp,func);
1060 * This method is equivalent to MEDCouplingFieldDouble::applyFunc, except that here 'varsOrder' is used to determine variables position in 'func'.
1061 * If there is vars detected in 'func' that is not in 'varsOrder' an exception will be thrown.
1063 void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) throw(INTERP_KERNEL::Exception)
1065 _time_discr->applyFunc3(nbOfComp,varsOrder,func);
1069 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1070 * If '*func' fails in evaluation during one evaluation an exception will be thrown.
1071 * The field will contain exactly the same number of components after the call.
1073 void MEDCouplingFieldDouble::applyFunc(const char *func) throw(INTERP_KERNEL::Exception)
1075 _time_discr->applyFunc(func);
1079 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1080 * The field will contain exactly the same number of components after the call.
1081 * Use is not warranted for the moment !
1083 void MEDCouplingFieldDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
1085 _time_discr->applyFuncFast32(func);
1089 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1090 * The field will contain exactly the same number of components after the call.
1091 * Use is not warranted for the moment !
1093 void MEDCouplingFieldDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
1095 _time_discr->applyFuncFast64(func);
1099 * This method makes the assumption that the default array has been set before.
1100 * If not an exception will be sent.
1101 * If default array set, the number of components will be sent.
1103 int MEDCouplingFieldDouble::getNumberOfComponents() const throw(INTERP_KERNEL::Exception)
1106 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
1107 return getArray()->getNumberOfComponents();
1111 * This method makes the assumption that _mesh has be set before the call of this method and description of gauss
1112 * localizations in case of Gauss field. If not an exception will sent.
1113 * \b Contrary to MEDCouplingFieldDouble::getNumberOfComponents and MEDCouplingFieldDouble::getNumberOfValues is
1114 * \b not aware of the presence of the default array.
1115 * \b WARNING \b no coherency check is done here. MEDCouplingFieldDouble::checkCoherency method should be called to check that !
1117 int MEDCouplingFieldDouble::getNumberOfTuples() const throw(INTERP_KERNEL::Exception)
1120 throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
1121 return _type->getNumberOfTuples(_mesh);
1125 * This method makes the assumption that the default array has been set before.
1126 * If not an exception will be sent.
1127 * If default array set, the number of values present in the default array will be sent.
1129 int MEDCouplingFieldDouble::getNumberOfValues() const throw(INTERP_KERNEL::Exception)
1132 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
1133 return getArray()->getNbOfElems();
1136 void MEDCouplingFieldDouble::updateTime() const
1138 MEDCouplingField::updateTime();
1139 updateTimeWith(*_time_discr);
1142 std::size_t MEDCouplingFieldDouble::getHeapMemorySize() const
1146 ret+=_time_discr->getHeapMemorySize();
1147 return MEDCouplingField::getHeapMemorySize()+ret;
1150 void MEDCouplingFieldDouble::setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception)
1152 MEDCouplingField::setNature(nat);
1153 _type->checkCompatibilityWithNature(nat);
1157 * This method synchronizes time information (time, iteration, order, time unit) regarding the information in \c this->_mesh.
1158 * \throw If no mesh is set in this. Or if \a this is not compatible with time setting (typically NO_TIME)
1160 void MEDCouplingFieldDouble::synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception)
1163 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::synchronizeTimeWithMesh : no mesh set in this !");
1165 double val=_mesh->getTime(it,ordr);
1166 std::string timeUnit(_mesh->getTimeUnit());
1167 setTime(val,it,ordr);
1168 setTimeUnit(timeUnit.c_str());
1171 double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
1173 return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
1176 void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
1178 _time_discr->setArray(array,this);
1181 void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
1183 _time_discr->setEndArray(array,this);
1186 void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs) throw(INTERP_KERNEL::Exception)
1188 _time_discr->setArrays(arrs,this);
1191 void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
1194 _time_discr->getTinySerializationStrInformation(tinyInfo);
1195 tinyInfo.push_back(_name);
1196 tinyInfo.push_back(_desc);
1197 tinyInfo.push_back(getTimeUnit());
1201 * This method retrieves some critical values to resize and prepare remote instance.
1202 * The first two elements returned in tinyInfo correspond to the parameters to give in constructor.
1203 * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1205 void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
1208 tinyInfo.push_back((int)_type->getEnum());
1209 tinyInfo.push_back((int)_time_discr->getEnum());
1210 tinyInfo.push_back((int)_nature);
1211 _time_discr->getTinySerializationIntInformation(tinyInfo);
1212 std::vector<int> tinyInfo2;
1213 _type->getTinySerializationIntInformation(tinyInfo2);
1214 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1215 tinyInfo.push_back((int)tinyInfo2.size());
1219 * This method retrieves some critical values to resize and prepare remote instance.
1220 * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1222 void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
1225 _time_discr->getTinySerializationDbleInformation(tinyInfo);
1226 std::vector<double> tinyInfo2;
1227 _type->getTinySerializationDbleInformation(tinyInfo2);
1228 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1229 tinyInfo.push_back((int)tinyInfo2.size());//very bad, lack of time to improve it
1233 * This method has to be called to the new instance filled by CORBA, MPI, File...
1234 * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied.
1235 * @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.
1236 * @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.
1237 * No decrRef must be applied to every instances in returned vector.
1239 void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays)
1242 std::vector<int> tinyInfoITmp(tinyInfoI);
1243 int sz=tinyInfoITmp.back();
1244 tinyInfoITmp.pop_back();
1245 std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz);
1246 std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end());
1247 _time_discr->resizeForUnserialization(tinyInfoI2,arrays);
1248 std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end());
1249 _type->resizeForUnserialization(tinyInfoITmp3,dataInt);
1252 void MEDCouplingFieldDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS)
1254 std::vector<int> tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end());
1256 std::vector<double> tmp(tinyInfoD);
1257 int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it
1259 std::vector<double> tmp1(tmp.begin(),tmp.end()-sz);
1260 std::vector<double> tmp2(tmp.end()-sz,tmp.end());
1262 _time_discr->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS);
1263 _nature=(NatureOfField)tinyInfoI[2];
1264 _type->finishUnserialization(tmp2);
1265 int nbOfElemS=(int)tinyInfoS.size();
1266 _name=tinyInfoS[nbOfElemS-3];
1267 _desc=tinyInfoS[nbOfElemS-2];
1268 setTimeUnit(tinyInfoS[nbOfElemS-1].c_str());
1272 * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller.
1273 * The values returned must be consulted only in readonly mode.
1275 void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) const
1277 _time_discr->getArrays(arrays);
1278 _type->getSerializationIntArray(dataInt);
1282 * This method tries to to change the mesh support of \a this following the parameter 'levOfCheck' and 'prec'.
1283 * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method. This method is used to perform the job.
1284 * If this->_mesh is not defined or other an exeption will be throw.
1286 void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception)
1288 if(_mesh==0 || other==0)
1289 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
1290 DataArrayInt *cellCor=0,*nodeCor=0;
1291 other->checkGeoEquivalWith(_mesh,levOfCheck,prec,cellCor,nodeCor);
1292 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2(cellCor),nodeCor2(nodeCor);
1294 renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
1296 renumberNodesWithoutMesh(nodeCor->getConstPointer(),_mesh->getNumberOfNodes());
1297 setMesh(const_cast<MEDCouplingMesh *>(other));
1301 * 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.
1302 * 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.
1303 * This method requires that 'f' and \a this are coherent (check coherency) and that 'f' and \a this would be coherent for a merge.
1304 * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method.
1306 void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception)
1309 f->checkCoherency();
1310 if(!areCompatibleForMerge(f))
1311 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::diffWith : Fields are not compatible ; unable to apply mergeFields on them !");
1312 changeUnderlyingMesh(f->getMesh(),levOfCheck,prec);
1317 * Merge nodes of underlying mesh. In case of some node will be merged the underlying mesh instance will change.
1318 * The first 'eps' stands for geometric approximation. The second 'epsOnVals' is for epsilon on values in case of node merging.
1319 * If 2 nodes distant from less than 'eps' and with value different with more than 'epsOnVals' an exception will be thrown.
1321 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals) throw(INTERP_KERNEL::Exception)
1323 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1325 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1326 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1329 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2);
1330 if(!ret)//no nodes have been merged.
1332 std::vector<DataArrayDouble *> arrays;
1333 _time_discr->getArrays(arrays);
1334 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1336 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1342 * Merge nodes with (barycenter computation) of underlying mesh. In case of some node will be merged the underlying mesh instance will change.
1343 * The first 'eps' stands for geometric approximation. The second 'epsOnVals' is for epsilon on values in case of node merging.
1344 * If 2 nodes distant from less than 'eps' and with value different with more than 'epsOnVals' an exception will be thrown.
1346 bool MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals) throw(INTERP_KERNEL::Exception)
1348 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1350 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1351 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1354 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes2(eps,ret,ret2);
1355 if(!ret)//no nodes have been merged.
1357 std::vector<DataArrayDouble *> arrays;
1358 _time_discr->getArrays(arrays);
1359 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1361 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1367 * This method applyies ParaMEDMEM::MEDCouplingPointSet::zipCoords method on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingPointSet.
1368 * If some nodes have disappeared true is returned.
1369 * 'epsOnVals' stands for epsilon in case of merge of cells. This value is used as tolerance in case the corresponding values differ.
1371 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals) throw(INTERP_KERNEL::Exception)
1373 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1375 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1376 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1377 int oldNbOfNodes=meshC2->getNumberOfNodes();
1378 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipCoordsTraducer();
1379 if(meshC2->getNumberOfNodes()!=oldNbOfNodes)
1381 std::vector<DataArrayDouble *> arrays;
1382 _time_discr->getArrays(arrays);
1383 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1385 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
1393 * This method applyies ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingUMesh.
1394 * The semantic of 'compType' is given in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer method.
1395 * 'epsOnVals' stands for epsilon in case of merge of cells. This value is used as tolerance in case the corresponding values differ.
1397 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals) throw(INTERP_KERNEL::Exception)
1399 const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
1401 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1402 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCpy());
1403 int oldNbOfCells=meshC2->getNumberOfCells();
1404 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipConnectivityTraducer(compType);
1405 if(meshC2->getNumberOfCells()!=oldNbOfCells)
1407 std::vector<DataArrayDouble *> arrays;
1408 _time_discr->getArrays(arrays);
1409 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1411 _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter);
1419 * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists.
1420 * For the moment, this method is implemented for fields on cells.
1422 * \return a newly allocated field double containing the result that the user should deallocate.
1424 MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const throw(INTERP_KERNEL::Exception)
1426 const MEDCouplingMesh *mesh=getMesh();
1428 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !");
1429 if(getTypeOfField()!=ON_CELLS)
1430 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !");
1431 const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1432 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=clone(false);
1433 ret->setMesh(umesh);
1434 DataArrayInt *cellIds=0;
1435 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds);
1436 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds2=cellIds;
1437 ret->setMesh(mesh2);
1438 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end());
1439 std::vector<DataArrayDouble *> arrays;
1440 _time_discr->getArrays(arrays);
1442 std::vector<DataArrayDouble *> newArr(arrays.size());
1443 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > newArr2(arrays.size());
1444 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++)
1448 newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
1449 newArr[i]=newArr2[i];
1452 ret->setArrays(newArr);
1457 * This method applyies ParaMEDMEM::MEDCouplingUMesh::simplexize on 'this->_mesh'.
1458 * The semantic of 'policy' is given in ParaMEDMEM::MEDCouplingUMesh::simplexize method.
1460 bool MEDCouplingFieldDouble::simplexize(int policy) throw(INTERP_KERNEL::Exception)
1462 int oldNbOfCells=_mesh->getNumberOfCells();
1463 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> meshC2(_mesh->deepCpy());
1464 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->simplexize(policy);
1465 int newNbOfCells=meshC2->getNumberOfCells();
1466 if(oldNbOfCells==newNbOfCells)
1468 std::vector<DataArrayDouble *> arrays;
1469 _time_discr->getArrays(arrays);
1470 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1472 _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter);
1477 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
1479 MEDCouplingTimeDiscretization *td=_time_discr->doublyContractedProduct();
1480 td->copyTinyAttrFrom(*_time_discr);
1481 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1482 ret->setName("DoublyContractedProduct");
1483 ret->setMesh(getMesh());
1487 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const throw(INTERP_KERNEL::Exception)
1489 MEDCouplingTimeDiscretization *td=_time_discr->determinant();
1490 td->copyTinyAttrFrom(*_time_discr);
1491 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1492 ret->setName("Determinant");
1493 ret->setMesh(getMesh());
1497 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
1499 MEDCouplingTimeDiscretization *td=_time_discr->eigenValues();
1500 td->copyTinyAttrFrom(*_time_discr);
1501 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1502 ret->setName("EigenValues");
1503 ret->setMesh(getMesh());
1507 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
1509 MEDCouplingTimeDiscretization *td=_time_discr->eigenVectors();
1510 td->copyTinyAttrFrom(*_time_discr);
1511 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1512 ret->setName("EigenVectors");
1513 ret->setMesh(getMesh());
1517 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const throw(INTERP_KERNEL::Exception)
1519 MEDCouplingTimeDiscretization *td=_time_discr->inverse();
1520 td->copyTinyAttrFrom(*_time_discr);
1521 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1522 ret->setName("Inversion");
1523 ret->setMesh(getMesh());
1527 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const throw(INTERP_KERNEL::Exception)
1529 MEDCouplingTimeDiscretization *td=_time_discr->trace();
1530 td->copyTinyAttrFrom(*_time_discr);
1531 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1532 ret->setName("Trace");
1533 ret->setMesh(getMesh());
1537 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const throw(INTERP_KERNEL::Exception)
1539 MEDCouplingTimeDiscretization *td=_time_discr->deviator();
1540 td->copyTinyAttrFrom(*_time_discr);
1541 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1542 ret->setName("Trace");
1543 ret->setMesh(getMesh());
1547 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const throw(INTERP_KERNEL::Exception)
1549 MEDCouplingTimeDiscretization *td=_time_discr->magnitude();
1550 td->copyTinyAttrFrom(*_time_discr);
1551 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1552 ret->setName("Magnitude");
1553 ret->setMesh(getMesh());
1557 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
1559 MEDCouplingTimeDiscretization *td=_time_discr->maxPerTuple();
1560 td->copyTinyAttrFrom(*_time_discr);
1561 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1562 std::ostringstream oss;
1563 oss << "Max_" << getName();
1564 ret->setName(oss.str().c_str());
1565 ret->setMesh(getMesh());
1569 void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception)
1571 _time_discr->changeNbOfComponents(newNbOfComp,dftValue);
1574 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1576 MEDCouplingTimeDiscretization *td=_time_discr->keepSelectedComponents(compoIds);
1577 td->copyTinyAttrFrom(*_time_discr);
1578 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1579 ret->setName(getName());
1580 ret->setMesh(getMesh());
1584 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
1586 _time_discr->setSelectedComponents(f->_time_discr,compoIds);
1589 void MEDCouplingFieldDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
1591 _time_discr->sortPerTuple(asc);
1594 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1596 if(!f1->areCompatibleForMerge(f2))
1597 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !");
1598 const MEDCouplingMesh *m1=f1->getMesh();
1599 const MEDCouplingMesh *m2=f2->getMesh();
1600 MEDCouplingMesh *m=m1->mergeMyselfWith(m2);
1601 MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr);
1602 td->copyTinyAttrFrom(*f1->_time_discr);
1603 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1606 ret->setName(f1->getName());
1607 ret->setDescription(f1->getDescription());
1612 * This method returns a newly created field that is the union of all fields in input array 'a'.
1613 * This method expects that 'a' is non empty. If not an exception will be thrown.
1614 * 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.
1615 * Generally speaking the first instance field in 'a' will be used to assign tiny attributes of returned field.
1617 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a) throw(INTERP_KERNEL::Exception)
1620 throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !");
1621 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms(a.size());
1622 std::vector< const MEDCouplingUMesh *> ms2(a.size());
1623 std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
1624 std::vector<const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
1625 const MEDCouplingFieldDouble *ref=(*it++);
1626 for(;it!=a.end();it++)
1627 if(!ref->areCompatibleForMerge(*it))
1628 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !");
1629 for(int i=0;i<(int)a.size();i++)
1631 if(!a[i]->getMesh())
1632 throw INTERP_KERNEL::Exception("MergeFields : A field as no underlying mesh !");
1633 ms[i]=a[i]->getMesh()->buildUnstructured();
1635 tds[i]=a[i]->_time_discr;
1637 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::MergeUMeshes(ms2);
1638 m->setName(ms2[0]->getName()); m->setDescription(ms2[0]->getDescription());
1639 MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds);
1640 td->copyTinyAttrFrom(*(a[0]->_time_discr));
1641 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone());
1643 ret->setName(a[0]->getName());
1644 ret->setDescription(a[0]->getDescription());
1648 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1650 if(!f1->areCompatibleForMeld(f2))
1651 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MeldFields on them !");
1652 MEDCouplingTimeDiscretization *td=f1->_time_discr->meld(f2->_time_discr);
1653 td->copyTinyAttrFrom(*f1->_time_discr);
1654 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1655 ret->setMesh(f1->getMesh());
1659 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1661 if(!f1->areStrictlyCompatible(f2))
1662 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DotFields on them !");
1663 MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr);
1664 td->copyTinyAttrFrom(*f1->_time_discr);
1665 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1666 ret->setMesh(f1->getMesh());
1670 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1672 if(!f1->areStrictlyCompatible(f2))
1673 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply CrossProductFields on them !");
1674 MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr);
1675 td->copyTinyAttrFrom(*f1->_time_discr);
1676 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1677 ret->setMesh(f1->getMesh());
1681 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1683 if(!f1->areStrictlyCompatible(f2))
1684 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MaxFields on them !");
1685 MEDCouplingTimeDiscretization *td=f1->_time_discr->max(f2->_time_discr);
1686 td->copyTinyAttrFrom(*f1->_time_discr);
1687 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1688 ret->setMesh(f1->getMesh());
1692 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1694 if(!f1->areStrictlyCompatible(f2))
1695 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MinFields on them !");
1696 MEDCouplingTimeDiscretization *td=f1->_time_discr->min(f2->_time_discr);
1697 td->copyTinyAttrFrom(*f1->_time_discr);
1698 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1699 ret->setMesh(f1->getMesh());
1703 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1705 if(!f1->areStrictlyCompatible(f2))
1706 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply AddFields on them !");
1707 MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr);
1708 td->copyTinyAttrFrom(*f1->_time_discr);
1709 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1710 ret->setMesh(f1->getMesh());
1714 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1716 if(!areStrictlyCompatible(&other))
1717 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply += on them !");
1718 _time_discr->addEqual(other._time_discr);
1722 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(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 SubstractFields on them !");
1726 MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(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->substractEqual(other._time_discr);
1741 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1743 if(!f1->areCompatibleForMul(f2))
1744 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MultiplyFields on them !");
1745 MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(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(!areCompatibleForMul(&other))
1755 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply *= on them !");
1756 _time_discr->multiplyEqual(other._time_discr);
1760 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1762 if(!f1->areCompatibleForDiv(f2))
1763 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DivideFields on them !");
1764 MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(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(!areCompatibleForDiv(&other))
1774 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !");
1775 _time_discr->divideEqual(other._time_discr);
1780 * This method writes the field series 'fs' in the VTK file 'fileName'.
1781 * 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.
1782 * If the single mesh is empty an exception will be thrown.
1783 * Finally there is a field in 'fs' with no name an exception will be thrown too.
1785 void MEDCouplingFieldDouble::WriteVTK(const char *fileName, const std::vector<const MEDCouplingFieldDouble *>& fs) throw(INTERP_KERNEL::Exception)
1789 std::size_t nfs=fs.size();
1790 const MEDCouplingMesh *m=fs[0]->getMesh();
1791 for(std::size_t i=1;i<nfs;i++)
1792 if(fs[i]->getMesh()!=m)
1793 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.");
1795 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !");
1796 std::ostringstream coss,noss;
1797 for(std::size_t i=0;i<nfs;i++)
1799 const MEDCouplingFieldDouble *cur=fs[i];
1800 std::string name(cur->getName());
1803 std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
1804 throw INTERP_KERNEL::Exception(oss.str().c_str());
1806 TypeOfField typ=cur->getTypeOfField();
1808 cur->getArray()->writeVTK(coss,8,cur->getName());
1809 else if(typ==ON_NODES)
1810 cur->getArray()->writeVTK(noss,8,cur->getName());
1812 m->writeVTKAdvanced(fileName,coss.str(),noss.str());