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;
36 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td)
38 return new MEDCouplingFieldDouble(type,td);
41 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td)
43 return new MEDCouplingFieldDouble(ft,td);
46 void MEDCouplingFieldDouble::setTimeUnit(const char *unit)
48 _time_discr->setTimeUnit(unit);
51 const char *MEDCouplingFieldDouble::getTimeUnit() const
53 return _time_discr->getTimeUnit();
57 * This method performs a copy of \a this **without any copy of the underlying mesh** ( see warning section of this method).
58 * The copy of arrays is deep if \b recDeepCpy equals to true, no copy of arrays is done if \b recDeepCpy equals to false.
60 * \c clone(false) is rather dedicated for advanced users that want to limit the amount of memory.
62 * It allows the user to perform methods
63 * MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields with \a this and the returned field.
65 * \warning The \b underlying \b mesh of the returned field is \b always the same (same pointer) than \a this \b whatever \b the \b value \b of \b recDeepCpy \b parameter.
66 * If the user wants to duplicated deeply the underlying mesh he should call MEDCouplingFieldDouble::cloneWithMesh method or MEDCouplingFieldDouble::deepCpy instead.
68 * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied of only attached to the returned field.
69 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
71 MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
73 return new MEDCouplingFieldDouble(*this,recDeepCpy);
77 * This method behaves exactly like MEDCouplingFieldDouble::clone method \b except \b that \b here \b the \b underlying \b mesh \b is \b systematically
78 * (whatever the value of the input parameter 'recDeepCpy') \b deeply \b duplicated.\n \n
79 * The result of \c cloneWithMesh(true) is exactly the same than calling \ref MEDCouplingFieldDouble::deepCpy "deepCpy".
81 * So the resulting field of this call cannot be called with \a this with the following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ...
82 * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
84 MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
86 MEDCouplingFieldDouble *ret=clone(recDeepCpy);
89 MEDCouplingMesh *mCpy=_mesh->deepCpy();
97 * This method performs a deepCpy of \a this \b mesh \b included !
98 * So the resulting field of this call cannot be called with \a this with following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ...
99 * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
100 * This method is exactly equivalent to MEDCouplingFieldDouble::cloneWithMesh called with parameter true.
102 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const
104 return cloneWithMesh(true);
107 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const
109 MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(td,deepCopy);
110 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),tdo,_type->clone());
111 ret->setMesh(getMesh());
112 ret->setName(getName());
113 ret->setDescription(getDescription());
118 * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason).
120 void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
124 setName(other->_name.c_str());
125 setDescription(other->_desc.c_str());
126 _time_discr->copyTinyStringsFrom(*other->_time_discr);
131 * Copy only times, order, iteration from other. The underlying mesh is not impacted by this method.
132 * Arrays are not impacted too.
134 void MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
138 _time_discr->copyTinyAttrFrom(*other->_time_discr);
142 std::string MEDCouplingFieldDouble::simpleRepr() const
144 std::ostringstream ret;
145 ret << "FieldDouble with name : \"" << getName() << "\"\n";
146 ret << "Description of field is : \"" << getDescription() << "\"\n";
147 ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
148 ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
149 ret << "FieldDouble nature of field is : " << MEDCouplingNatureOfField::getRepr(_nature) << "\n";
152 int nbOfCompo=getArray()->getNumberOfComponents();
153 ret << "FieldDouble default array has " << nbOfCompo << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
154 ret << "FieldDouble default array has following info on components : ";
155 for(int i=0;i<nbOfCompo;i++)
156 ret << "\"" << getArray()->getInfoOnComponent(i) << "\" ";
160 ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr();
162 ret << "Mesh support information : No mesh set !\n";
166 std::string MEDCouplingFieldDouble::advancedRepr() const
168 std::ostringstream ret;
169 ret << "FieldDouble with name : \"" << getName() << "\"\n";
170 ret << "Description of field is : \"" << getDescription() << "\"\n";
171 ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
172 ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
174 ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
176 ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr();
178 ret << "Mesh support information : No mesh set !\n";
179 std::vector<DataArrayDouble *> arrays;
180 _time_discr->getArrays(arrays);
182 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++)
184 ret << "Array #" << arrayId << " :\n__________\n";
186 (*iter)->reprWithoutNameStream(ret);
188 ret << "Array empty !";
194 bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception)
197 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::isEqualIfNotWhy : other instance is NULL !");
198 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
201 reason="field given in input is not castable in MEDCouplingFieldDouble !";
204 if(!MEDCouplingField::isEqualIfNotWhy(other,meshPrec,valsPrec,reason))
206 if(!_time_discr->isEqualIfNotWhy(otherC->_time_discr,valsPrec,reason))
208 reason.insert(0,"In FieldDouble time discretizations differ :");
214 bool MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const
216 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
219 if(!MEDCouplingField::isEqualWithoutConsideringStr(other,meshPrec,valsPrec))
221 if(!_time_discr->isEqualWithoutConsideringStr(otherC->_time_discr,valsPrec))
227 * This method states if \a this and 'other' are compatibles each other before performing any treatment.
228 * This method is good for methods like : mergeFields.
229 * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields.
231 bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const
233 if(!MEDCouplingField::areCompatibleForMerge(other))
235 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
238 if(!_time_discr->areCompatible(otherC->_time_discr))
244 * This method is more strict than MEDCouplingField::areCompatibleForMerge method.
245 * This method is used for operation on fields to operate a first check before attempting operation.
247 bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const
250 if(!MEDCouplingField::areStrictlyCompatible(other))
252 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
255 if(!_time_discr->areStrictlyCompatible(otherC->_time_discr,tmp))
261 * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
262 * number of components between \a this and 'other' can be different here (for operator*).
264 bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const
266 if(!MEDCouplingField::areStrictlyCompatible(other))
268 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
271 if(!_time_discr->areStrictlyCompatibleForMul(otherC->_time_discr))
277 * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
278 * number of components between \a this and 'other' can be different here (for operator/).
280 bool MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const
282 if(!MEDCouplingField::areStrictlyCompatible(other))
284 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
287 if(!_time_discr->areStrictlyCompatibleForDiv(otherC->_time_discr))
293 * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible,
294 * except that \a this and other can have different number of components.
296 bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const
298 if(!MEDCouplingField::areStrictlyCompatible(other))
300 if(!_time_discr->areCompatibleForMeld(other->_time_discr))
306 * This method performs a clone of mesh and a renumbering of underlying cells of it. The number of cells remains the same.
307 * The values of field are impacted in consequence to have the same geometrical field.
309 void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
311 renumberCellsWithoutMesh(old2NewBg,check);
312 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_mesh->deepCpy();
313 m->renumberCells(old2NewBg,check);
319 * \b WARNING : use this method with lot of care !
320 * This method performs half job of MEDCouplingFieldDouble::renumberCells. That is to say no permutation of cells is done on underlying mesh.
321 * 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
322 * avoid a systematic duplication and renumbering of _mesh attribute.
324 void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
327 throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !");
329 _type->renumberCells(old2NewBg,check);
330 std::vector<DataArrayDouble *> arrays;
331 _time_discr->getArrays(arrays);
332 _type->renumberArraysForCell(_mesh,arrays,old2NewBg,check);
338 * 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.
339 * The values of field are impacted in consequence to have the same geometrical field.
341 void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception)
343 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
345 throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !");
346 int nbOfNodes=meshC->getNumberOfNodes();
347 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
348 renumberNodesWithoutMesh(old2NewBg);
349 meshC2->renumberNodes(old2NewBg,*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1);
354 * \b WARNING : use this method with lot of care !
355 * This method performs half job of MEDCouplingFieldDouble::renumberNodes. That is to say no permutation of cells is done on underlying mesh.
356 * That is to say, the field content is changed by this method.
358 void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, double eps) throw(INTERP_KERNEL::Exception)
360 std::vector<DataArrayDouble *> arrays;
361 _time_discr->getArrays(arrays);
362 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
364 _type->renumberValuesOnNodes(eps,old2NewBg,*iter);
368 * This method makes the assumption that the default array is set. If not an exception will be thrown.
369 * This method is usable only if the default array has exactly one component. If not an exception will be thrown too.
370 * This method returns all tuples ids that fit the range [vmin,vmax].
371 * The caller has the responsability of the returned DataArrayInt.
373 DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
376 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getIdsInRange : no default array set !");
377 return getArray()->getIdsInRange(vmin,vmax);
381 * Builds a newly created field, that the caller will have the responsability to deal with (decrRef).
382 * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done.
383 * This method returns a restriction of \a this so that only tuples id specified in 'part' will be contained in returned field.
384 * 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)
386 * If \a this is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6].
387 * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
388 * 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()'
389 * 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()'
390 * 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()'
392 * 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].
393 * \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,
394 * will contain 6 tuples and this field will lie on this restricted mesh.
396 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception)
399 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !");
400 const int *start=part->getConstPointer();
401 const int *end=start+part->getNbOfElems();
402 return buildSubPart(start,end);
406 * Builds a newly created field, that the caller will have the responsability to deal with.
407 * \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**.
408 * \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.
409 * \n Parameter [\a partBg, \a partEnd ) specifies \b cell \b ids \b whatever \b the \b spatial \b discretization of \a this
410 * (\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")
412 * If \a this is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6].
413 * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
415 *- 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()
416 *- 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()
417 *- 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()
419 * 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.
420 * \n If part contains following cellIds [3,7,6].
421 * \n If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, the returned field,
422 * will contain 6 tuples (and same number of components \c this->getArray()->getNumberOfComponents() ) and this field will lie on this restricted mesh.
424 * \param [in] partBg start (included) of input range cell ids to select [ \a partBg, \a partEnd )
425 * \param [in] partEnd end (not included) of input range cell ids to select [ \a partBg, \a partEnd )
426 * \return a newly allocated field the caller should deal with.
428 * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \c this->getMesh()
430 * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."
432 * \ref py_mcfielddouble_subpart1 "Here a Python example."
433 * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const
435 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception)
437 DataArrayInt *arrSelect;
438 MEDCouplingMesh *m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect);
439 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrSelect2(arrSelect);
440 MEDCouplingFieldDouble *ret=clone(false);//quick shallow copy.
443 std::vector<DataArrayDouble *> arrays;
444 _time_discr->getArrays(arrays);
445 std::vector<DataArrayDouble *> arrs;
446 const int *arrSelBg=arrSelect->begin();
447 const int *arrSelEnd=arrSelect->end();
448 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
450 DataArrayDouble *arr=0;
452 arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd);
455 ret->_time_discr->setArrays(arrs,0);
456 for(std::vector<DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
462 TypeOfTimeDiscretization MEDCouplingFieldDouble::getTimeDiscretization() const
464 return _time_discr->getEnum();
467 MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingField(type),
468 _time_discr(MEDCouplingTimeDiscretization::New(td))
472 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td):MEDCouplingField(*ft),
473 _time_discr(MEDCouplingTimeDiscretization::New(td))
477 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other),
478 _time_discr(other._time_discr->performCpy(deepCopy))
482 MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingField(type,n),_time_discr(td)
486 MEDCouplingFieldDouble::~MEDCouplingFieldDouble()
491 void MEDCouplingFieldDouble::checkCoherency() const throw(INTERP_KERNEL::Exception)
494 throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !");
495 _time_discr->checkCoherency();
496 _type->checkCoherencyBetween(_mesh,getArray());
500 * Returns the accumulation (the sum) of comId_th component of each tuples of \b default and \b only \b default array.
502 double MEDCouplingFieldDouble::accumulate(int compId) const
505 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
506 return getArray()->accumulate(compId);
510 * Returns the accumulation (the sum) of all tuples of \b default and \b only default array.
511 * The res is expected to be of size getNumberOfComponents().
513 void MEDCouplingFieldDouble::accumulate(double *res) const
516 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
517 getArray()->accumulate(res);
521 * 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.
522 * To getMaxValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'.
523 * If no arrays exists, an exception will be thrown.
525 double MEDCouplingFieldDouble::getMaxValue() const throw(INTERP_KERNEL::Exception)
527 std::vector<DataArrayDouble *> arrays;
528 _time_discr->getArrays(arrays);
529 double ret=-std::numeric_limits<double>::max();
530 bool isExistingArr=false;
531 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
537 ret=std::max(ret,(*iter)->getMaxValue(loc));
541 throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !");
546 * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMaxValue method because the returned
547 * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility
548 * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array.
549 * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used
550 * to compute tupleIds.
552 double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
554 std::vector<DataArrayDouble *> arrays;
555 _time_discr->getArrays(arrays);
556 double ret=-std::numeric_limits<double>::max();
557 bool isExistingArr=false;
559 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
565 ret=std::max(ret,(*iter)->getMaxValue2(tmp));
573 throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !");
578 * 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.
579 * To getMinValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'.
580 * If no arrays exists, an exception will be thrown.
582 double MEDCouplingFieldDouble::getMinValue() const throw(INTERP_KERNEL::Exception)
584 std::vector<DataArrayDouble *> arrays;
585 _time_discr->getArrays(arrays);
586 double ret=std::numeric_limits<double>::max();
587 bool isExistingArr=false;
588 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
594 ret=std::min(ret,(*iter)->getMinValue(loc));
598 throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !");
603 * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMinValue method because the returned
604 * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility
605 * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array.
606 * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used
607 * to compute tupleIds.
609 double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
611 std::vector<DataArrayDouble *> arrays;
612 _time_discr->getArrays(arrays);
613 double ret=-std::numeric_limits<double>::max();
614 bool isExistingArr=false;
616 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
622 ret=std::max(ret,(*iter)->getMinValue2(tmp));
630 throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !");
635 * 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.
636 * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
637 * If default array does not exist, an exception will be thrown.
639 double MEDCouplingFieldDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
642 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !");
643 return getArray()->getAverageValue();
647 * This method returns the euclidean norm of \a this.
649 * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]}
651 * If default array does not exist, an exception will be thrown.
653 double MEDCouplingFieldDouble::norm2() const throw(INTERP_KERNEL::Exception)
656 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !");
657 return getArray()->norm2();
661 * This method returns the max norm of \a this.
663 * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
665 * If default array does not exist, an exception will be thrown.
667 double MEDCouplingFieldDouble::normMax() const throw(INTERP_KERNEL::Exception)
670 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
671 return getArray()->normMax();
675 * This method returns the average value in \a this weighted by ParaMEDMEM::MEDCouplingField::buildMeasureField.
676 * \a this is expected to be a field with exactly \b one component. If not an exception will be thrown.
677 * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
678 * If default array does not exist, an exception will be thrown.
680 double MEDCouplingFieldDouble::getWeightedAverageValue() const throw(INTERP_KERNEL::Exception)
683 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
684 MEDCouplingFieldDouble *w=buildMeasureField(true);
685 double deno=w->getArray()->accumulate(0);
686 w->getArray()->multiplyEqual(getArray());
687 double res=w->getArray()->accumulate(0);
693 * Returns the normL1 of current field on compId component :
695 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
697 * If compId>=nbOfComponent an exception is thrown.
699 double MEDCouplingFieldDouble::normL1(int compId) const throw(INTERP_KERNEL::Exception)
702 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
703 int nbComps=getArray()->getNumberOfComponents();
705 throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
706 double *res=new double[nbComps];
709 _type->normL1(_mesh,getArray(),res);
711 catch(INTERP_KERNEL::Exception& e)
716 double ret=res[compId];
722 * Returns the normL1 of current field on each components :
724 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
726 * The res is expected to be of size getNumberOfComponents().
728 void MEDCouplingFieldDouble::normL1(double *res) const throw(INTERP_KERNEL::Exception)
731 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
732 _type->normL1(_mesh,getArray(),res);
736 * Returns the normL2 of current field on compId component :
738 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
740 * If compId>=nbOfComponent an exception is thrown.
742 double MEDCouplingFieldDouble::normL2(int compId) const throw(INTERP_KERNEL::Exception)
745 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
746 int nbComps=getArray()->getNumberOfComponents();
748 throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
749 double *res=new double[nbComps];
752 _type->normL2(_mesh,getArray(),res);
754 catch(INTERP_KERNEL::Exception& e)
759 double ret=res[compId];
765 * Returns the normL2 of current field on each components :
767 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
769 * The res is expected to be of size getNumberOfComponents().
771 void MEDCouplingFieldDouble::normL2(double *res) const throw(INTERP_KERNEL::Exception)
774 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
775 _type->normL2(_mesh,getArray(),res);
779 * Returns the accumulation (the sum) of comId_th component of each tuples weigthed by the field
780 * returns by getWeightingField relative of the _type of field of default array.
781 * This method is usefull to check the conservativity of interpolation method.
783 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception)
786 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
787 int nbComps=getArray()->getNumberOfComponents();
789 throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
790 double *res=new double[nbComps];
793 _type->integral(_mesh,getArray(),isWAbs,res);
795 catch(INTERP_KERNEL::Exception& e)
800 double ret=res[compId];
806 * Returns the accumulation (the sum) of each tuples weigthed by the field
807 * returns by getWeightingField relative of the _type of field of default array.
808 * This method is usefull to check the conservativity of interpolation method.
810 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception)
813 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
814 _type->integral(_mesh,getArray(),isWAbs,res);
818 * This method is reserved for field lying on structured mesh spatial support. It returns the value of cell localized by (i,j,k)
819 * If spatial support is not structured mesh an exception will be thrown.
820 * @param res out array expected to be equal to size getNumberOfComponents()
822 void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const throw(INTERP_KERNEL::Exception)
824 const DataArrayDouble *arr=_time_discr->getArray();
826 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
827 _type->getValueOnPos(arr,_mesh,i,j,k,res);
831 * Returns value of \a this on default time of point 'spaceLoc' using spatial discretization.
832 * If 'point' is outside the spatial discretization of this an exception will be thrown.
834 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const throw(INTERP_KERNEL::Exception)
836 const DataArrayDouble *arr=_time_discr->getArray();
838 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
839 _type->getValueOn(arr,_mesh,spaceLoc,res);
843 * Returns a newly allocated array with 'nbOfPoints' tuples and nb of components equal to 'this->getNumberOfComponents()'.
845 DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const throw(INTERP_KERNEL::Exception)
847 const DataArrayDouble *arr=_time_discr->getArray();
849 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
850 return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
854 * Returns value of \a this on time 'time' of point 'spaceLoc' using spatial discretization.
855 * If 'time' is not covered by this->_time_discr an exception will be thrown.
856 * If 'point' is outside the spatial discretization of this an exception will be thrown.
858 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const throw(INTERP_KERNEL::Exception)
860 std::vector< const DataArrayDouble *> arrs=_time_discr->getArraysForTime(time);
862 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
863 std::vector<double> res2;
864 for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
866 int sz=(int)res2.size();
867 res2.resize(sz+(*iter)->getNumberOfComponents());
868 _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]);
870 _time_discr->getValueForTime(time,res2,res);
874 * Applies a*x+b on 'compoId'th component of each cell.
876 void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
878 _time_discr->applyLin(a,b,compoId);
882 * This method sets \a this to a uniform scalar field with one component.
883 * All tuples will have the same value 'value'.
884 * An exception is thrown if no underlying mesh is defined.
886 MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) throw(INTERP_KERNEL::Exception)
889 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
890 int nbOfTuple=_type->getNumberOfTuples(_mesh);
891 _time_discr->setUniformValue(nbOfTuple,1,value);
896 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic.
897 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
898 * The main difference is that the field as been started to be constructed here.
899 * An exception is thrown if no underlying mesh is set before the call of this method.
901 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception)
904 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
905 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
906 _time_discr->fillFromAnalytic(loc,nbOfComp,func);
910 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic.
911 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
912 * The main difference is that the field as been started to be constructed here.
913 * An exception is thrown if no underlying mesh is set before the call of this method.
915 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
918 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
919 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
920 _time_discr->fillFromAnalytic(loc,nbOfComp,func);
924 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic2.
925 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
926 * The main difference is that the field as been started to be constructed here.
927 * An exception is throw if no underlying mesh is set before the call of this method.
929 void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
932 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !");
933 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
934 _time_discr->fillFromAnalytic2(loc,nbOfComp,func);
938 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic3.
939 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
940 * The main difference is that the field as been started to be constructed here.
941 * An exception is thrown if no underlying mesh is set before the call of this method.
943 void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) throw(INTERP_KERNEL::Exception)
946 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !");
947 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
948 _time_discr->fillFromAnalytic3(loc,nbOfComp,varsOrder,func);
952 * Applyies the function specified by pointer 'func' on each tuples on all arrays contained in _time_discr.
953 * If '*func' returns false during one evaluation an exception will be thrown.
955 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
957 _time_discr->applyFunc(nbOfComp,func);
961 * This method is a specialization of other overloaded methods. When 'nbOfComp' equals 1 this method is equivalent to
962 * ParaMEDMEM::MEDCouplingFieldDouble::operator=.
964 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
967 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
968 int nbOfTuple=_type->getNumberOfTuples(_mesh);
969 _time_discr->setUniformValue(nbOfTuple,nbOfComp,val);
973 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
974 * If '*func' fails in evaluation during one evaluation an exception will be thrown.
975 * The field will contain 'nbOfComp' components after the call.
977 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
979 _time_discr->applyFunc(nbOfComp,func);
983 * This method is equivalent to MEDCouplingFieldDouble::applyFunc, except that here components info are used to determine variables position in 'func'.
984 * If there is vars detected in 'func' that is not in an info on components an exception will be thrown.
986 void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
988 _time_discr->applyFunc2(nbOfComp,func);
992 * This method is equivalent to MEDCouplingFieldDouble::applyFunc, except that here 'varsOrder' is used to determine variables position in 'func'.
993 * If there is vars detected in 'func' that is not in 'varsOrder' an exception will be thrown.
995 void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) throw(INTERP_KERNEL::Exception)
997 _time_discr->applyFunc3(nbOfComp,varsOrder,func);
1001 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1002 * If '*func' fails in evaluation during one evaluation an exception will be thrown.
1003 * The field will contain exactly the same number of components after the call.
1005 void MEDCouplingFieldDouble::applyFunc(const char *func) throw(INTERP_KERNEL::Exception)
1007 _time_discr->applyFunc(func);
1011 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1012 * The field will contain exactly the same number of components after the call.
1013 * Use is not warranted for the moment !
1015 void MEDCouplingFieldDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
1017 _time_discr->applyFuncFast32(func);
1021 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1022 * The field will contain exactly the same number of components after the call.
1023 * Use is not warranted for the moment !
1025 void MEDCouplingFieldDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
1027 _time_discr->applyFuncFast64(func);
1031 * This method makes the assumption that the default array has been set before.
1032 * If not an exception will be sent.
1033 * If default array set, the number of components will be sent.
1035 int MEDCouplingFieldDouble::getNumberOfComponents() const throw(INTERP_KERNEL::Exception)
1038 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
1039 return getArray()->getNumberOfComponents();
1043 * This method makes the assumption that _mesh has be set before the call of this method and description of gauss
1044 * localizations in case of Gauss field. If not an exception will sent.
1045 * \b Contrary to MEDCouplingFieldDouble::getNumberOfComponents and MEDCouplingFieldDouble::getNumberOfValues is
1046 * \b not aware of the presence of the default array.
1047 * \b WARNING \b no coherency check is done here. MEDCouplingFieldDouble::checkCoherency method should be called to check that !
1049 int MEDCouplingFieldDouble::getNumberOfTuples() const throw(INTERP_KERNEL::Exception)
1052 throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
1053 return _type->getNumberOfTuples(_mesh);
1057 * This method makes the assumption that the default array has been set before.
1058 * If not an exception will be sent.
1059 * If default array set, the number of values present in the default array will be sent.
1061 int MEDCouplingFieldDouble::getNumberOfValues() const throw(INTERP_KERNEL::Exception)
1064 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
1065 return getArray()->getNbOfElems();
1068 void MEDCouplingFieldDouble::updateTime() const
1070 MEDCouplingField::updateTime();
1071 updateTimeWith(*_time_discr);
1074 void MEDCouplingFieldDouble::setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception)
1076 MEDCouplingField::setNature(nat);
1077 _type->checkCompatibilityWithNature(nat);
1080 double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
1082 return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
1085 void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
1087 _time_discr->setArray(array,this);
1090 void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
1092 _time_discr->setEndArray(array,this);
1095 void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs) throw(INTERP_KERNEL::Exception)
1097 _time_discr->setArrays(arrs,this);
1100 void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
1103 _time_discr->getTinySerializationStrInformation(tinyInfo);
1104 tinyInfo.push_back(_name);
1105 tinyInfo.push_back(_desc);
1106 tinyInfo.push_back(getTimeUnit());
1110 * This method retrieves some critical values to resize and prepare remote instance.
1111 * The first two elements returned in tinyInfo correspond to the parameters to give in constructor.
1112 * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1114 void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
1117 tinyInfo.push_back((int)_type->getEnum());
1118 tinyInfo.push_back((int)_time_discr->getEnum());
1119 tinyInfo.push_back((int)_nature);
1120 _time_discr->getTinySerializationIntInformation(tinyInfo);
1121 std::vector<int> tinyInfo2;
1122 _type->getTinySerializationIntInformation(tinyInfo2);
1123 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1124 tinyInfo.push_back((int)tinyInfo2.size());
1128 * This method retrieves some critical values to resize and prepare remote instance.
1129 * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1131 void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
1134 _time_discr->getTinySerializationDbleInformation(tinyInfo);
1135 std::vector<double> tinyInfo2;
1136 _type->getTinySerializationDbleInformation(tinyInfo2);
1137 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1138 tinyInfo.push_back((int)tinyInfo2.size());//very bad, lack of time to improve it
1142 * This method has to be called to the new instance filled by CORBA, MPI, File...
1143 * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied.
1144 * @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.
1145 * @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.
1146 * No decrRef must be applied to every instances in returned vector.
1148 void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays)
1151 std::vector<int> tinyInfoITmp(tinyInfoI);
1152 int sz=tinyInfoITmp.back();
1153 tinyInfoITmp.pop_back();
1154 std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz);
1155 std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end());
1156 _time_discr->resizeForUnserialization(tinyInfoI2,arrays);
1157 std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end());
1158 _type->resizeForUnserialization(tinyInfoITmp3,dataInt);
1161 void MEDCouplingFieldDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS)
1163 std::vector<int> tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end());
1165 std::vector<double> tmp(tinyInfoD);
1166 int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it
1168 std::vector<double> tmp1(tmp.begin(),tmp.end()-sz);
1169 std::vector<double> tmp2(tmp.end()-sz,tmp.end());
1171 _time_discr->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS);
1172 _nature=(NatureOfField)tinyInfoI[2];
1173 _type->finishUnserialization(tmp2);
1174 int nbOfElemS=(int)tinyInfoS.size();
1175 _name=tinyInfoS[nbOfElemS-3];
1176 _desc=tinyInfoS[nbOfElemS-2];
1177 setTimeUnit(tinyInfoS[nbOfElemS-1].c_str());
1181 * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller.
1182 * The values returned must be consulted only in readonly mode.
1184 void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) const
1186 _time_discr->getArrays(arrays);
1187 _type->getSerializationIntArray(dataInt);
1191 * This method tries to to change the mesh support of \a this following the parameter 'levOfCheck' and 'prec'.
1192 * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method. This method is used to perform the job.
1193 * If this->_mesh is not defined or other an exeption will be throw.
1195 void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception)
1197 if(_mesh==0 || other==0)
1198 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
1199 DataArrayInt *cellCor,*nodeCor;
1200 other->checkGeoEquivalWith(_mesh,levOfCheck,prec,cellCor,nodeCor);
1203 renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
1208 renumberNodesWithoutMesh(nodeCor->getConstPointer());
1211 setMesh(const_cast<MEDCouplingMesh *>(other));
1215 * 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.
1216 * 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.
1217 * This method requires that 'f' and \a this are coherent (check coherency) and that 'f' and \a this would be coherent for a merge.
1218 * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method.
1220 void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception)
1223 f->checkCoherency();
1224 if(!areCompatibleForMerge(f))
1225 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::diffWith : Fields are not compatible ; unable to apply mergeFields on them !");
1226 changeUnderlyingMesh(f->getMesh(),levOfCheck,prec);
1231 * Merge nodes of underlying mesh. In case of some node will be merged the underlying mesh instance will change.
1232 * The first 'eps' stands for geometric approximation. The second 'epsOnVals' is for epsilon on values in case of node merging.
1233 * If 2 nodes distant from less than 'eps' and with value different with more than 'epsOnVals' an exception will be thrown.
1235 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals) throw(INTERP_KERNEL::Exception)
1237 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1239 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1240 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1243 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2);
1244 if(!ret)//no nodes have been merged.
1246 std::vector<DataArrayDouble *> arrays;
1247 _time_discr->getArrays(arrays);
1248 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1250 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),*iter);
1256 * Merge nodes with (barycenter computation) of underlying mesh. In case of some node will be merged the underlying mesh instance will change.
1257 * The first 'eps' stands for geometric approximation. The second 'epsOnVals' is for epsilon on values in case of node merging.
1258 * If 2 nodes distant from less than 'eps' and with value different with more than 'epsOnVals' an exception will be thrown.
1260 bool MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals) throw(INTERP_KERNEL::Exception)
1262 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1264 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1265 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1268 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes2(eps,ret,ret2);
1269 if(!ret)//no nodes have been merged.
1271 std::vector<DataArrayDouble *> arrays;
1272 _time_discr->getArrays(arrays);
1273 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1275 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),*iter);
1281 * This method applyies ParaMEDMEM::MEDCouplingPointSet::zipCoords method on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingPointSet.
1282 * If some nodes have disappeared true is returned.
1283 * 'epsOnVals' stands for epsilon in case of merge of cells. This value is used as tolerance in case the corresponding values differ.
1285 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals) throw(INTERP_KERNEL::Exception)
1287 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1289 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1290 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1291 int oldNbOfNodes=meshC2->getNumberOfNodes();
1292 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipCoordsTraducer();
1293 if(meshC2->getNumberOfNodes()!=oldNbOfNodes)
1295 std::vector<DataArrayDouble *> arrays;
1296 _time_discr->getArrays(arrays);
1297 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1299 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),*iter);
1307 * This method applyies ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingUMesh.
1308 * The semantic of 'compType' is given in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer method.
1309 * 'epsOnVals' stands for epsilon in case of merge of cells. This value is used as tolerance in case the corresponding values differ.
1311 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals) throw(INTERP_KERNEL::Exception)
1313 const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
1315 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1316 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCpy());
1317 int oldNbOfCells=meshC2->getNumberOfCells();
1318 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipConnectivityTraducer(compType);
1319 if(meshC2->getNumberOfCells()!=oldNbOfCells)
1321 std::vector<DataArrayDouble *> arrays;
1322 _time_discr->getArrays(arrays);
1323 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1325 _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),*iter);
1333 * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists.
1334 * For the moment, this method is implemented for fields on cells.
1336 * \return a newly allocated field double containing the result that the user should deallocate.
1338 MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const throw(INTERP_KERNEL::Exception)
1340 const MEDCouplingMesh *mesh=getMesh();
1342 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !");
1343 if(getTypeOfField()!=ON_CELLS)
1344 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !");
1345 const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1346 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=clone(false);
1347 ret->setMesh(umesh);
1348 DataArrayInt *cellIds=0;
1349 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds);
1350 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds2=cellIds;
1351 ret->setMesh(mesh2);
1352 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end());
1353 std::vector<DataArrayDouble *> arrays;
1354 _time_discr->getArrays(arrays);
1356 std::vector<DataArrayDouble *> newArr(arrays.size());
1357 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > newArr2(arrays.size());
1358 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++)
1362 newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
1363 newArr[i]=newArr2[i];
1366 ret->setArrays(newArr);
1367 ret->incrRef(); return ret;
1371 * This method applyies ParaMEDMEM::MEDCouplingUMesh::simplexize on 'this->_mesh'.
1372 * The semantic of 'policy' is given in ParaMEDMEM::MEDCouplingUMesh::simplexize method.
1374 bool MEDCouplingFieldDouble::simplexize(int policy) throw(INTERP_KERNEL::Exception)
1376 int oldNbOfCells=_mesh->getNumberOfCells();
1377 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> meshC2(_mesh->deepCpy());
1378 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->simplexize(policy);
1379 int newNbOfCells=meshC2->getNumberOfCells();
1380 if(oldNbOfCells==newNbOfCells)
1382 std::vector<DataArrayDouble *> arrays;
1383 _time_discr->getArrays(arrays);
1384 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1386 _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter);
1391 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
1393 MEDCouplingTimeDiscretization *td=_time_discr->doublyContractedProduct();
1394 td->copyTinyAttrFrom(*_time_discr);
1395 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1396 ret->setName("DoublyContractedProduct");
1397 ret->setMesh(getMesh());
1401 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const throw(INTERP_KERNEL::Exception)
1403 MEDCouplingTimeDiscretization *td=_time_discr->determinant();
1404 td->copyTinyAttrFrom(*_time_discr);
1405 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1406 ret->setName("Determinant");
1407 ret->setMesh(getMesh());
1411 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
1413 MEDCouplingTimeDiscretization *td=_time_discr->eigenValues();
1414 td->copyTinyAttrFrom(*_time_discr);
1415 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1416 ret->setName("EigenValues");
1417 ret->setMesh(getMesh());
1421 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
1423 MEDCouplingTimeDiscretization *td=_time_discr->eigenVectors();
1424 td->copyTinyAttrFrom(*_time_discr);
1425 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1426 ret->setName("EigenVectors");
1427 ret->setMesh(getMesh());
1431 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const throw(INTERP_KERNEL::Exception)
1433 MEDCouplingTimeDiscretization *td=_time_discr->inverse();
1434 td->copyTinyAttrFrom(*_time_discr);
1435 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1436 ret->setName("Inversion");
1437 ret->setMesh(getMesh());
1441 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const throw(INTERP_KERNEL::Exception)
1443 MEDCouplingTimeDiscretization *td=_time_discr->trace();
1444 td->copyTinyAttrFrom(*_time_discr);
1445 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1446 ret->setName("Trace");
1447 ret->setMesh(getMesh());
1451 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const throw(INTERP_KERNEL::Exception)
1453 MEDCouplingTimeDiscretization *td=_time_discr->deviator();
1454 td->copyTinyAttrFrom(*_time_discr);
1455 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1456 ret->setName("Trace");
1457 ret->setMesh(getMesh());
1461 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const throw(INTERP_KERNEL::Exception)
1463 MEDCouplingTimeDiscretization *td=_time_discr->magnitude();
1464 td->copyTinyAttrFrom(*_time_discr);
1465 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1466 ret->setName("Magnitude");
1467 ret->setMesh(getMesh());
1471 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
1473 MEDCouplingTimeDiscretization *td=_time_discr->maxPerTuple();
1474 td->copyTinyAttrFrom(*_time_discr);
1475 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1476 std::ostringstream oss;
1477 oss << "Max_" << getName();
1478 ret->setName(oss.str().c_str());
1479 ret->setMesh(getMesh());
1483 void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception)
1485 _time_discr->changeNbOfComponents(newNbOfComp,dftValue);
1488 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1490 MEDCouplingTimeDiscretization *td=_time_discr->keepSelectedComponents(compoIds);
1491 td->copyTinyAttrFrom(*_time_discr);
1492 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1493 ret->setName(getName());
1494 ret->setMesh(getMesh());
1498 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
1500 _time_discr->setSelectedComponents(f->_time_discr,compoIds);
1503 void MEDCouplingFieldDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
1505 _time_discr->sortPerTuple(asc);
1508 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1510 if(!f1->areCompatibleForMerge(f2))
1511 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !");
1512 const MEDCouplingMesh *m1=f1->getMesh();
1513 const MEDCouplingMesh *m2=f2->getMesh();
1514 MEDCouplingMesh *m=m1->mergeMyselfWith(m2);
1515 MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr);
1516 td->copyTinyAttrFrom(*f1->_time_discr);
1517 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1520 ret->setName(f1->getName());
1521 ret->setDescription(f1->getDescription());
1526 * This method returns a newly created field that is the union of all fields in input array 'a'.
1527 * This method expects that 'a' is non empty. If not an exception will be thrown.
1528 * 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.
1529 * Generally speaking the first instance field in 'a' will be used to assign tiny attributes of returned field.
1531 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a) throw(INTERP_KERNEL::Exception)
1534 throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !");
1535 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms(a.size());
1536 std::vector< const MEDCouplingUMesh *> ms2(a.size());
1537 std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
1538 std::vector<const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
1539 const MEDCouplingFieldDouble *ref=(*it++);
1540 for(;it!=a.end();it++)
1541 if(!ref->areCompatibleForMerge(*it))
1542 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !");
1543 for(int i=0;i<(int)a.size();i++)
1545 if(!a[i]->getMesh())
1546 throw INTERP_KERNEL::Exception("MergeFields : A field as no underlying mesh !");
1547 ms[i]=a[i]->getMesh()->buildUnstructured();
1549 tds[i]=a[i]->_time_discr;
1551 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::MergeUMeshes(ms2);
1552 m->setName(ms2[0]->getName()); m->setDescription(ms2[0]->getDescription());
1553 MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds);
1554 td->copyTinyAttrFrom(*(a[0]->_time_discr));
1555 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone());
1557 ret->setName(a[0]->getName());
1558 ret->setDescription(a[0]->getDescription());
1562 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1564 if(!f1->areCompatibleForMeld(f2))
1565 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MeldFields on them !");
1566 MEDCouplingTimeDiscretization *td=f1->_time_discr->meld(f2->_time_discr);
1567 td->copyTinyAttrFrom(*f1->_time_discr);
1568 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1569 ret->setMesh(f1->getMesh());
1573 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1575 if(!f1->areStrictlyCompatible(f2))
1576 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DotFields on them !");
1577 MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr);
1578 td->copyTinyAttrFrom(*f1->_time_discr);
1579 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1580 ret->setMesh(f1->getMesh());
1584 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1586 if(!f1->areStrictlyCompatible(f2))
1587 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply CrossProductFields on them !");
1588 MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr);
1589 td->copyTinyAttrFrom(*f1->_time_discr);
1590 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1591 ret->setMesh(f1->getMesh());
1595 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1597 if(!f1->areStrictlyCompatible(f2))
1598 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MaxFields on them !");
1599 MEDCouplingTimeDiscretization *td=f1->_time_discr->max(f2->_time_discr);
1600 td->copyTinyAttrFrom(*f1->_time_discr);
1601 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1602 ret->setMesh(f1->getMesh());
1606 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1608 if(!f1->areStrictlyCompatible(f2))
1609 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MinFields on them !");
1610 MEDCouplingTimeDiscretization *td=f1->_time_discr->min(f2->_time_discr);
1611 td->copyTinyAttrFrom(*f1->_time_discr);
1612 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1613 ret->setMesh(f1->getMesh());
1617 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1619 if(!f1->areStrictlyCompatible(f2))
1620 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply AddFields on them !");
1621 MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr);
1622 td->copyTinyAttrFrom(*f1->_time_discr);
1623 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1624 ret->setMesh(f1->getMesh());
1628 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1630 if(!areStrictlyCompatible(&other))
1631 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply += on them !");
1632 _time_discr->addEqual(other._time_discr);
1636 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1638 if(!f1->areStrictlyCompatible(f2))
1639 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply SubstractFields on them !");
1640 MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(f2->_time_discr);
1641 td->copyTinyAttrFrom(*f1->_time_discr);
1642 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1643 ret->setMesh(f1->getMesh());
1647 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1649 if(!areStrictlyCompatible(&other))
1650 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply -= on them !");
1651 _time_discr->substractEqual(other._time_discr);
1655 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1657 if(!f1->areCompatibleForMul(f2))
1658 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MultiplyFields on them !");
1659 MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr);
1660 td->copyTinyAttrFrom(*f1->_time_discr);
1661 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1662 ret->setMesh(f1->getMesh());
1666 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1668 if(!areCompatibleForMul(&other))
1669 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply *= on them !");
1670 _time_discr->multiplyEqual(other._time_discr);
1674 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1676 if(!f1->areCompatibleForDiv(f2))
1677 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DivideFields on them !");
1678 MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(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 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1687 if(!areCompatibleForDiv(&other))
1688 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !");
1689 _time_discr->divideEqual(other._time_discr);
1694 * This method writes the field series 'fs' in the VTK file 'fileName'.
1695 * 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.
1696 * If the single mesh is empty an exception will be thrown.
1697 * Finally there is a field in 'fs' with no name an exception will be thrown too.
1699 void MEDCouplingFieldDouble::WriteVTK(const char *fileName, const std::vector<const MEDCouplingFieldDouble *>& fs) throw(INTERP_KERNEL::Exception)
1703 std::size_t nfs=fs.size();
1704 const MEDCouplingMesh *m=fs[0]->getMesh();
1705 for(std::size_t i=1;i<nfs;i++)
1706 if(fs[i]->getMesh()!=m)
1707 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.");
1709 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !");
1710 std::ostringstream coss,noss;
1711 for(std::size_t i=0;i<nfs;i++)
1713 const MEDCouplingFieldDouble *cur=fs[i];
1714 std::string name(cur->getName());
1717 std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
1718 throw INTERP_KERNEL::Exception(oss.str().c_str());
1720 TypeOfField typ=cur->getTypeOfField();
1722 cur->getArray()->writeVTK(coss,8,cur->getName());
1723 else if(typ==ON_NODES)
1724 cur->getArray()->writeVTK(noss,8,cur->getName());
1726 m->writeVTKAdvanced(fileName,coss.str(),noss.str());