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
20 #include "MEDCouplingFieldDouble.hxx"
21 #include "MEDCouplingFieldTemplate.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingTimeDiscretization.hxx"
24 #include "MEDCouplingFieldDiscretization.hxx"
25 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
26 #include "MEDCouplingNatureOfField.hxx"
33 using namespace ParaMEDMEM;
35 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td)
37 return new MEDCouplingFieldDouble(type,td);
40 MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td)
42 return new MEDCouplingFieldDouble(ft,td);
45 void MEDCouplingFieldDouble::setTimeUnit(const char *unit)
47 _time_discr->setTimeUnit(unit);
50 const char *MEDCouplingFieldDouble::getTimeUnit() const
52 return _time_discr->getTimeUnit();
56 * This method performs a copy of \a this **without any copy of the underlying mesh** ( see warning section of this method).
57 * The copy of arrays is deep if \b recDeepCpy equals to true, no copy of arrays is done if \b recDeepCpy equals to false.
59 * \c clone(false) is rather dedicated for advanced users that want to limit the amount of memory.
61 * It allows the user to perform methods
62 * MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields with \a this and the returned field.
64 * \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.
65 * If the user wants to duplicated deeply the underlying mesh he should call MEDCouplingFieldDouble::cloneWithMesh method or MEDCouplingFieldDouble::deepCpy instead.
67 * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied of only attached to the returned field.
68 * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with.
70 MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const
72 return new MEDCouplingFieldDouble(*this,recDeepCpy);
76 * This method behaves exactly like MEDCouplingFieldDouble::clone method \b except \b that \b here \b the \b underlying \b mesh \b is \b systematically
77 * (whatever the value of the input parameter 'recDeepCpy') \b deeply \b duplicated.\n \n
78 * The result of \c cloneWithMesh(true) is exactly the same than calling \ref MEDCouplingFieldDouble::deepCpy "deepCpy".
80 * So the resulting field of this call cannot be called with \a this with the following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ...
81 * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
83 MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const
85 MEDCouplingFieldDouble *ret=clone(recDeepCpy);
88 MEDCouplingMesh *mCpy=_mesh->deepCpy();
96 * This method performs a deepCpy of \a this \b mesh \b included !
97 * So the resulting field of this call cannot be called with \a this with following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ...
98 * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead.
99 * This method is exactly equivalent to MEDCouplingFieldDouble::cloneWithMesh called with parameter true.
101 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const
103 return cloneWithMesh(true);
106 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const
108 MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(td,deepCopy);
109 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),tdo,_type->clone());
110 ret->setMesh(getMesh());
111 ret->setName(getName());
112 ret->setDescription(getDescription());
117 * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason).
119 void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
123 setName(other->_name.c_str());
124 setDescription(other->_desc.c_str());
125 _time_discr->copyTinyStringsFrom(*other->_time_discr);
130 * Copy only times, order, iteration from other. The underlying mesh is not impacted by this method.
131 * Arrays are not impacted too.
133 void MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
137 _time_discr->copyTinyAttrFrom(*other->_time_discr);
141 std::string MEDCouplingFieldDouble::simpleRepr() const
143 std::ostringstream ret;
144 ret << "FieldDouble with name : \"" << getName() << "\"\n";
145 ret << "Description of field is : \"" << getDescription() << "\"\n";
146 ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
147 ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
148 ret << "FieldDouble nature of field is : " << MEDCouplingNatureOfField::getRepr(_nature) << "\n";
151 int nbOfCompo=getArray()->getNumberOfComponents();
152 ret << "FieldDouble default array has " << nbOfCompo << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
153 ret << "FieldDouble default array has following info on components : ";
154 for(int i=0;i<nbOfCompo;i++)
155 ret << "\"" << getArray()->getInfoOnComponent(i) << "\" ";
159 ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr();
161 ret << "Mesh support information : No mesh set !\n";
165 std::string MEDCouplingFieldDouble::advancedRepr() const
167 std::ostringstream ret;
168 ret << "FieldDouble with name : \"" << getName() << "\"\n";
169 ret << "Description of field is : \"" << getDescription() << "\"\n";
170 ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
171 ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
173 ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n";
175 ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr();
177 ret << "Mesh support information : No mesh set !\n";
178 std::vector<DataArrayDouble *> arrays;
179 _time_discr->getArrays(arrays);
181 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++)
183 ret << "Array #" << arrayId << " :\n__________\n";
185 (*iter)->reprWithoutNameStream(ret);
187 ret << "Array empty !";
193 bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception)
196 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::isEqualIfNotWhy : other instance is NULL !");
197 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
200 reason="field given in input is not castable in MEDCouplingFieldDouble !";
203 if(!MEDCouplingField::isEqualIfNotWhy(other,meshPrec,valsPrec,reason))
205 if(!_time_discr->isEqualIfNotWhy(otherC->_time_discr,valsPrec,reason))
207 reason.insert(0,"In FieldDouble time discretizations differ :");
213 bool MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const
215 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
218 if(!MEDCouplingField::isEqualWithoutConsideringStr(other,meshPrec,valsPrec))
220 if(!_time_discr->isEqualWithoutConsideringStr(otherC->_time_discr,valsPrec))
226 * This method states if \a this and 'other' are compatibles each other before performing any treatment.
227 * This method is good for methods like : mergeFields.
228 * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields.
230 bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const
232 if(!MEDCouplingField::areCompatibleForMerge(other))
234 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
237 if(!_time_discr->areCompatible(otherC->_time_discr))
243 * This method is more strict than MEDCouplingField::areCompatibleForMerge method.
244 * This method is used for operation on fields to operate a first check before attempting operation.
246 bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const
249 if(!MEDCouplingField::areStrictlyCompatible(other))
251 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
254 if(!_time_discr->areStrictlyCompatible(otherC->_time_discr,tmp))
260 * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
261 * number of components between \a this and 'other' can be different here (for operator*).
263 bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const
265 if(!MEDCouplingField::areStrictlyCompatible(other))
267 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
270 if(!_time_discr->areStrictlyCompatibleForMul(otherC->_time_discr))
276 * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
277 * number of components between \a this and 'other' can be different here (for operator/).
279 bool MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const
281 if(!MEDCouplingField::areStrictlyCompatible(other))
283 const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
286 if(!_time_discr->areStrictlyCompatibleForDiv(otherC->_time_discr))
292 * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible,
293 * except that \a this and other can have different number of components.
295 bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const
297 if(!MEDCouplingField::areStrictlyCompatible(other))
299 if(!_time_discr->areCompatibleForMeld(other->_time_discr))
305 * This method performs a clone of mesh and a renumbering of underlying cells of it. The number of cells remains the same.
306 * The values of field are impacted in consequence to have the same geometrical field.
308 void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
310 renumberCellsWithoutMesh(old2NewBg,check);
311 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_mesh->deepCpy();
312 m->renumberCells(old2NewBg,check);
318 * \b WARNING : use this method with lot of care !
319 * This method performs half job of MEDCouplingFieldDouble::renumberCells. That is to say no permutation of cells is done on underlying mesh.
320 * 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
321 * avoid a systematic duplication and renumbering of _mesh attribute.
323 void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
326 throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !");
328 _type->renumberCells(old2NewBg,check);
329 std::vector<DataArrayDouble *> arrays;
330 _time_discr->getArrays(arrays);
331 _type->renumberArraysForCell(_mesh,arrays,old2NewBg,check);
337 * 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.
338 * The values of field are impacted in consequence to have the same geometrical field.
340 void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception)
342 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
344 throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !");
345 int nbOfNodes=meshC->getNumberOfNodes();
346 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
347 renumberNodesWithoutMesh(old2NewBg);
348 meshC2->renumberNodes(old2NewBg,*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1);
353 * \b WARNING : use this method with lot of care !
354 * This method performs half job of MEDCouplingFieldDouble::renumberNodes. That is to say no permutation of cells is done on underlying mesh.
355 * That is to say, the field content is changed by this method.
357 void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, double eps) throw(INTERP_KERNEL::Exception)
359 std::vector<DataArrayDouble *> arrays;
360 _time_discr->getArrays(arrays);
361 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
363 _type->renumberValuesOnNodes(eps,old2NewBg,*iter);
367 * This method makes the assumption that the default array is set. If not an exception will be thrown.
368 * This method is usable only if the default array has exactly one component. If not an exception will be thrown too.
369 * This method returns all tuples ids that fit the range [vmin,vmax].
370 * The caller has the responsability of the returned DataArrayInt.
372 DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
375 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getIdsInRange : no default array set !");
376 return getArray()->getIdsInRange(vmin,vmax);
380 * Builds a newly created field, that the caller will have the responsability to deal with (decrRef).
381 * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done.
382 * This method returns a restriction of \a this so that only tuples id specified in 'part' will be contained in returned field.
383 * 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)
385 * If \a this is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6].
386 * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
387 * 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()'
388 * 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()'
389 * 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()'
391 * 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].
392 * \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,
393 * will contain 6 tuples and this field will lie on this restricted mesh.
395 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception)
398 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !");
399 const int *start=part->getConstPointer();
400 const int *end=start+part->getNbOfElems();
401 return buildSubPart(start,end);
405 * Builds a newly created field, that the caller will have the responsability to deal with.
406 * \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**.
407 * \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.
408 * \n Parameter [\a partBg, \a partEnd ) specifies \b cell \b ids \b whatever \b the \b spatial \b discretization of \a this
409 * (\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")
411 * If \a this is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6].
412 * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
414 *- 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()
415 *- 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()
416 *- 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()
418 * 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.
419 * \n If part contains following cellIds [3,7,6].
420 * \n If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, the returned field,
421 * will contain 6 tuples (and same number of components \c this->getArray()->getNumberOfComponents() ) and this field will lie on this restricted mesh.
423 * \param [in] partBg start (included) of input range cell ids to select [ \a partBg, \a partEnd )
424 * \param [in] partEnd end (not included) of input range cell ids to select [ \a partBg, \a partEnd )
425 * \return a newly allocated field the caller should deal with.
427 * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \c this->getMesh()
429 * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."
431 * \ref py_mcfielddouble_subpart1 "Here a Python example."
432 * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const
434 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception)
436 DataArrayInt *arrSelect;
437 MEDCouplingMesh *m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect);
438 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrSelect2(arrSelect);
439 MEDCouplingFieldDouble *ret=clone(false);//quick shallow copy.
442 std::vector<DataArrayDouble *> arrays;
443 _time_discr->getArrays(arrays);
444 std::vector<DataArrayDouble *> arrs;
445 const int *arrSelBg=arrSelect->begin();
446 const int *arrSelEnd=arrSelect->end();
447 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
449 DataArrayDouble *arr=0;
451 arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd);
454 ret->_time_discr->setArrays(arrs,0);
455 for(std::vector<DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
461 TypeOfTimeDiscretization MEDCouplingFieldDouble::getTimeDiscretization() const
463 return _time_discr->getEnum();
466 MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingField(type),
467 _time_discr(MEDCouplingTimeDiscretization::New(td))
471 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td):MEDCouplingField(*ft),
472 _time_discr(MEDCouplingTimeDiscretization::New(td))
476 MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other),
477 _time_discr(other._time_discr->performCpy(deepCopy))
481 MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingField(type,n),_time_discr(td)
485 MEDCouplingFieldDouble::~MEDCouplingFieldDouble()
490 void MEDCouplingFieldDouble::checkCoherency() const throw(INTERP_KERNEL::Exception)
493 throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !");
494 _time_discr->checkCoherency();
495 _type->checkCoherencyBetween(_mesh,getArray());
499 * Returns the accumulation (the sum) of comId_th component of each tuples of \b default and \b only \b default array.
501 double MEDCouplingFieldDouble::accumulate(int compId) const
504 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
505 return getArray()->accumulate(compId);
509 * Returns the accumulation (the sum) of all tuples of \b default and \b only default array.
510 * The res is expected to be of size getNumberOfComponents().
512 void MEDCouplingFieldDouble::accumulate(double *res) const
515 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !");
516 getArray()->accumulate(res);
520 * 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.
521 * To getMaxValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'.
522 * If no arrays exists, an exception will be thrown.
524 double MEDCouplingFieldDouble::getMaxValue() const throw(INTERP_KERNEL::Exception)
526 std::vector<DataArrayDouble *> arrays;
527 _time_discr->getArrays(arrays);
528 double ret=-std::numeric_limits<double>::max();
529 bool isExistingArr=false;
530 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
536 ret=std::max(ret,(*iter)->getMaxValue(loc));
540 throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !");
545 * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMaxValue method because the returned
546 * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility
547 * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array.
548 * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used
549 * to compute tupleIds.
551 double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
553 std::vector<DataArrayDouble *> arrays;
554 _time_discr->getArrays(arrays);
555 double ret=-std::numeric_limits<double>::max();
556 bool isExistingArr=false;
558 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
564 ret=std::max(ret,(*iter)->getMaxValue2(tmp));
572 throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !");
577 * 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.
578 * To getMinValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'.
579 * If no arrays exists, an exception will be thrown.
581 double MEDCouplingFieldDouble::getMinValue() const throw(INTERP_KERNEL::Exception)
583 std::vector<DataArrayDouble *> arrays;
584 _time_discr->getArrays(arrays);
585 double ret=std::numeric_limits<double>::max();
586 bool isExistingArr=false;
587 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
593 ret=std::min(ret,(*iter)->getMinValue(loc));
597 throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !");
602 * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMinValue method because the returned
603 * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility
604 * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array.
605 * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used
606 * to compute tupleIds.
608 double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
610 std::vector<DataArrayDouble *> arrays;
611 _time_discr->getArrays(arrays);
612 double ret=-std::numeric_limits<double>::max();
613 bool isExistingArr=false;
615 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
621 ret=std::max(ret,(*iter)->getMinValue2(tmp));
629 throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !");
634 * 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.
635 * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
636 * If default array does not exist, an exception will be thrown.
638 double MEDCouplingFieldDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
641 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !");
642 return getArray()->getAverageValue();
646 * This method returns the euclidean norm of \a this.
648 * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]}
650 * If default array does not exist, an exception will be thrown.
652 double MEDCouplingFieldDouble::norm2() const throw(INTERP_KERNEL::Exception)
655 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !");
656 return getArray()->norm2();
660 * This method returns the max norm of \a this.
662 * \max_{0 \leq i < nbOfEntity}{abs(val[i])}
664 * If default array does not exist, an exception will be thrown.
666 double MEDCouplingFieldDouble::normMax() const throw(INTERP_KERNEL::Exception)
669 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !");
670 return getArray()->normMax();
674 * This method returns the average value in \a this weighted by ParaMEDMEM::MEDCouplingField::buildMeasureField.
675 * \a this is expected to be a field with exactly \b one component. If not an exception will be thrown.
676 * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
677 * If default array does not exist, an exception will be thrown.
679 double MEDCouplingFieldDouble::getWeightedAverageValue() const throw(INTERP_KERNEL::Exception)
682 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
683 MEDCouplingFieldDouble *w=buildMeasureField(true);
684 double deno=w->getArray()->accumulate(0);
685 w->getArray()->multiplyEqual(getArray());
686 double res=w->getArray()->accumulate(0);
692 * Returns the normL1 of current field on compId component :
694 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
696 * If compId>=nbOfComponent an exception is thrown.
698 double MEDCouplingFieldDouble::normL1(int compId) const throw(INTERP_KERNEL::Exception)
701 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
702 int nbComps=getArray()->getNumberOfComponents();
704 throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
705 double *res=new double[nbComps];
708 _type->normL1(_mesh,getArray(),res);
710 catch(INTERP_KERNEL::Exception& e)
715 double ret=res[compId];
721 * Returns the normL1 of current field on each components :
723 * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}
725 * The res is expected to be of size getNumberOfComponents().
727 void MEDCouplingFieldDouble::normL1(double *res) const throw(INTERP_KERNEL::Exception)
730 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
731 _type->normL1(_mesh,getArray(),res);
735 * Returns the normL2 of current field on compId component :
737 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
739 * If compId>=nbOfComponent an exception is thrown.
741 double MEDCouplingFieldDouble::normL2(int compId) const throw(INTERP_KERNEL::Exception)
744 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
745 int nbComps=getArray()->getNumberOfComponents();
747 throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
748 double *res=new double[nbComps];
751 _type->normL2(_mesh,getArray(),res);
753 catch(INTERP_KERNEL::Exception& e)
758 double ret=res[compId];
764 * Returns the normL2 of current field on each components :
766 * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}}
768 * The res is expected to be of size getNumberOfComponents().
770 void MEDCouplingFieldDouble::normL2(double *res) const throw(INTERP_KERNEL::Exception)
773 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
774 _type->normL2(_mesh,getArray(),res);
778 * Returns the accumulation (the sum) of comId_th component of each tuples weigthed by the field
779 * returns by getWeightingField relative of the _type of field of default array.
780 * This method is usefull to check the conservativity of interpolation method.
782 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception)
785 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
786 int nbComps=getArray()->getNumberOfComponents();
788 throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
789 double *res=new double[nbComps];
792 _type->integral(_mesh,getArray(),isWAbs,res);
794 catch(INTERP_KERNEL::Exception& e)
799 double ret=res[compId];
805 * Returns the accumulation (the sum) of each tuples weigthed by the field
806 * returns by getWeightingField relative of the _type of field of default array.
807 * This method is usefull to check the conservativity of interpolation method.
809 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception)
812 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2");
813 _type->integral(_mesh,getArray(),isWAbs,res);
817 * This method is reserved for field lying on structured mesh spatial support. It returns the value of cell localized by (i,j,k)
818 * If spatial support is not structured mesh an exception will be thrown.
819 * @param res out array expected to be equal to size getNumberOfComponents()
821 void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const throw(INTERP_KERNEL::Exception)
823 const DataArrayDouble *arr=_time_discr->getArray();
825 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos");
826 _type->getValueOnPos(arr,_mesh,i,j,k,res);
830 * Returns value of \a this on default time of point 'spaceLoc' using spatial discretization.
831 * If 'point' is outside the spatial discretization of this an exception will be thrown.
833 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const throw(INTERP_KERNEL::Exception)
835 const DataArrayDouble *arr=_time_discr->getArray();
837 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
838 _type->getValueOn(arr,_mesh,spaceLoc,res);
842 * Returns a newly allocated array with 'nbOfPoints' tuples and nb of components equal to 'this->getNumberOfComponents()'.
844 DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const throw(INTERP_KERNEL::Exception)
846 const DataArrayDouble *arr=_time_discr->getArray();
848 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti");
849 return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints);
853 * Returns value of \a this on time 'time' of point 'spaceLoc' using spatial discretization.
854 * If 'time' is not covered by this->_time_discr an exception will be thrown.
855 * If 'point' is outside the spatial discretization of this an exception will be thrown.
857 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const throw(INTERP_KERNEL::Exception)
859 std::vector< const DataArrayDouble *> arrs=_time_discr->getArraysForTime(time);
861 throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn");
862 std::vector<double> res2;
863 for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++)
865 int sz=(int)res2.size();
866 res2.resize(sz+(*iter)->getNumberOfComponents());
867 _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]);
869 _time_discr->getValueForTime(time,res2,res);
873 * Applies a*x+b on 'compoId'th component of each cell.
875 void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId)
877 _time_discr->applyLin(a,b,compoId);
881 * This method sets \a this to a uniform scalar field with one component.
882 * All tuples will have the same value 'value'.
883 * An exception is thrown if no underlying mesh is defined.
885 MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) throw(INTERP_KERNEL::Exception)
888 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !");
889 int nbOfTuple=_type->getNumberOfTuples(_mesh);
890 _time_discr->setUniformValue(nbOfTuple,1,value);
895 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic.
896 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
897 * The main difference is that the field as been started to be constructed here.
898 * An exception is thrown if no underlying mesh is set before the call of this method.
900 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception)
903 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
904 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
905 _time_discr->fillFromAnalytic(loc,nbOfComp,func);
909 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic.
910 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
911 * The main difference is that the field as been started to be constructed here.
912 * An exception is thrown if no underlying mesh is set before the call of this method.
914 void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
917 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !");
918 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
919 _time_discr->fillFromAnalytic(loc,nbOfComp,func);
923 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic2.
924 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
925 * The main difference is that the field as been started to be constructed here.
926 * An exception is throw if no underlying mesh is set before the call of this method.
928 void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
931 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !");
932 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
933 _time_discr->fillFromAnalytic2(loc,nbOfComp,func);
937 * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic3.
938 * See MEDCouplingMesh::fillFromAnalytic method doc to have more details.
939 * The main difference is that the field as been started to be constructed here.
940 * An exception is thrown if no underlying mesh is set before the call of this method.
942 void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) throw(INTERP_KERNEL::Exception)
945 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !");
946 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh);
947 _time_discr->fillFromAnalytic3(loc,nbOfComp,varsOrder,func);
951 * Applyies the function specified by pointer 'func' on each tuples on all arrays contained in _time_discr.
952 * If '*func' returns false during one evaluation an exception will be thrown.
954 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func)
956 _time_discr->applyFunc(nbOfComp,func);
960 * This method is a specialization of other overloaded methods. When 'nbOfComp' equals 1 this method is equivalent to
961 * ParaMEDMEM::MEDCouplingFieldDouble::operator=.
963 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val)
966 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !");
967 int nbOfTuple=_type->getNumberOfTuples(_mesh);
968 _time_discr->setUniformValue(nbOfTuple,nbOfComp,val);
972 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
973 * If '*func' fails in evaluation during one evaluation an exception will be thrown.
974 * The field will contain 'nbOfComp' components after the call.
976 void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
978 _time_discr->applyFunc(nbOfComp,func);
982 * This method is equivalent to MEDCouplingFieldDouble::applyFunc, except that here components info are used to determine variables position in 'func'.
983 * If there is vars detected in 'func' that is not in an info on components an exception will be thrown.
985 void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception)
987 _time_discr->applyFunc2(nbOfComp,func);
991 * This method is equivalent to MEDCouplingFieldDouble::applyFunc, except that here 'varsOrder' is used to determine variables position in 'func'.
992 * If there is vars detected in 'func' that is not in 'varsOrder' an exception will be thrown.
994 void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) throw(INTERP_KERNEL::Exception)
996 _time_discr->applyFunc3(nbOfComp,varsOrder,func);
1000 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1001 * If '*func' fails in evaluation during one evaluation an exception will be thrown.
1002 * The field will contain exactly the same number of components after the call.
1004 void MEDCouplingFieldDouble::applyFunc(const char *func) throw(INTERP_KERNEL::Exception)
1006 _time_discr->applyFunc(func);
1010 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1011 * The field will contain exactly the same number of components after the call.
1012 * Use is not warranted for the moment !
1014 void MEDCouplingFieldDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
1016 _time_discr->applyFuncFast32(func);
1020 * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr.
1021 * The field will contain exactly the same number of components after the call.
1022 * Use is not warranted for the moment !
1024 void MEDCouplingFieldDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
1026 _time_discr->applyFuncFast64(func);
1030 * This method makes the assumption that the default array has been set before.
1031 * If not an exception will be sent.
1032 * If default array set, the number of components will be sent.
1034 int MEDCouplingFieldDouble::getNumberOfComponents() const throw(INTERP_KERNEL::Exception)
1037 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !");
1038 return getArray()->getNumberOfComponents();
1042 * This method makes the assumption that _mesh has be set before the call of this method and description of gauss
1043 * localizations in case of Gauss field. If not an exception will sent.
1044 * \b Contrary to MEDCouplingFieldDouble::getNumberOfComponents and MEDCouplingFieldDouble::getNumberOfValues is
1045 * \b not aware of the presence of the default array.
1046 * \b WARNING \b no coherency check is done here. MEDCouplingFieldDouble::checkCoherency method should be called to check that !
1048 int MEDCouplingFieldDouble::getNumberOfTuples() const throw(INTERP_KERNEL::Exception)
1051 throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !");
1052 return _type->getNumberOfTuples(_mesh);
1056 * This method makes the assumption that the default array has been set before.
1057 * If not an exception will be sent.
1058 * If default array set, the number of values present in the default array will be sent.
1060 int MEDCouplingFieldDouble::getNumberOfValues() const throw(INTERP_KERNEL::Exception)
1063 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !");
1064 return getArray()->getNbOfElems();
1067 void MEDCouplingFieldDouble::updateTime() const
1069 MEDCouplingField::updateTime();
1070 updateTimeWith(*_time_discr);
1073 void MEDCouplingFieldDouble::setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception)
1075 MEDCouplingField::setNature(nat);
1076 _type->checkCompatibilityWithNature(nat);
1079 double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const
1081 return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId);
1084 void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
1086 _time_discr->setArray(array,this);
1089 void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
1091 _time_discr->setEndArray(array,this);
1094 void MEDCouplingFieldDouble::setArrays(const std::vector<DataArrayDouble *>& arrs) throw(INTERP_KERNEL::Exception)
1096 _time_discr->setArrays(arrs,this);
1099 void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
1102 _time_discr->getTinySerializationStrInformation(tinyInfo);
1103 tinyInfo.push_back(_name);
1104 tinyInfo.push_back(_desc);
1105 tinyInfo.push_back(getTimeUnit());
1109 * This method retrieves some critical values to resize and prepare remote instance.
1110 * The first two elements returned in tinyInfo correspond to the parameters to give in constructor.
1111 * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1113 void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
1116 tinyInfo.push_back((int)_type->getEnum());
1117 tinyInfo.push_back((int)_time_discr->getEnum());
1118 tinyInfo.push_back((int)_nature);
1119 _time_discr->getTinySerializationIntInformation(tinyInfo);
1120 std::vector<int> tinyInfo2;
1121 _type->getTinySerializationIntInformation(tinyInfo2);
1122 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1123 tinyInfo.push_back((int)tinyInfo2.size());
1127 * This method retrieves some critical values to resize and prepare remote instance.
1128 * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny.
1130 void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
1133 _time_discr->getTinySerializationDbleInformation(tinyInfo);
1134 std::vector<double> tinyInfo2;
1135 _type->getTinySerializationDbleInformation(tinyInfo2);
1136 tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end());
1137 tinyInfo.push_back((int)tinyInfo2.size());//very bad, lack of time to improve it
1141 * This method has to be called to the new instance filled by CORBA, MPI, File...
1142 * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied.
1143 * @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.
1144 * @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.
1145 * No decrRef must be applied to every instances in returned vector.
1147 void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays)
1150 std::vector<int> tinyInfoITmp(tinyInfoI);
1151 int sz=tinyInfoITmp.back();
1152 tinyInfoITmp.pop_back();
1153 std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz);
1154 std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end());
1155 _time_discr->resizeForUnserialization(tinyInfoI2,arrays);
1156 std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end());
1157 _type->resizeForUnserialization(tinyInfoITmp3,dataInt);
1160 void MEDCouplingFieldDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS)
1162 std::vector<int> tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end());
1164 std::vector<double> tmp(tinyInfoD);
1165 int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it
1167 std::vector<double> tmp1(tmp.begin(),tmp.end()-sz);
1168 std::vector<double> tmp2(tmp.end()-sz,tmp.end());
1170 _time_discr->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS);
1171 _nature=(NatureOfField)tinyInfoI[2];
1172 _type->finishUnserialization(tmp2);
1173 int nbOfElemS=(int)tinyInfoS.size();
1174 _name=tinyInfoS[nbOfElemS-3];
1175 _desc=tinyInfoS[nbOfElemS-2];
1176 setTimeUnit(tinyInfoS[nbOfElemS-1].c_str());
1180 * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller.
1181 * The values returned must be consulted only in readonly mode.
1183 void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) const
1185 _time_discr->getArrays(arrays);
1186 _type->getSerializationIntArray(dataInt);
1190 * This method tries to to change the mesh support of \a this following the parameter 'levOfCheck' and 'prec'.
1191 * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method. This method is used to perform the job.
1192 * If this->_mesh is not defined or other an exeption will be throw.
1194 void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception)
1196 if(_mesh==0 || other==0)
1197 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
1198 DataArrayInt *cellCor,*nodeCor;
1199 other->checkGeoEquivalWith(_mesh,levOfCheck,prec,cellCor,nodeCor);
1202 renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
1207 renumberNodesWithoutMesh(nodeCor->getConstPointer());
1210 setMesh(const_cast<MEDCouplingMesh *>(other));
1214 * 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.
1215 * 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.
1216 * This method requires that 'f' and \a this are coherent (check coherency) and that 'f' and \a this would be coherent for a merge.
1217 * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method.
1219 void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception)
1222 f->checkCoherency();
1223 if(!areCompatibleForMerge(f))
1224 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::diffWith : Fields are not compatible ; unable to apply mergeFields on them !");
1225 changeUnderlyingMesh(f->getMesh(),levOfCheck,prec);
1230 * Merge nodes of underlying mesh. In case of some node will be merged the underlying mesh instance will change.
1231 * The first 'eps' stands for geometric approximation. The second 'epsOnVals' is for epsilon on values in case of node merging.
1232 * If 2 nodes distant from less than 'eps' and with value different with more than 'epsOnVals' an exception will be thrown.
1234 bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals) throw(INTERP_KERNEL::Exception)
1236 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1238 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1239 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1242 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2);
1243 if(!ret)//no nodes have been merged.
1245 std::vector<DataArrayDouble *> arrays;
1246 _time_discr->getArrays(arrays);
1247 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1249 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),*iter);
1255 * Merge nodes with (barycenter computation) of underlying mesh. In case of some node will be merged the underlying mesh instance will change.
1256 * The first 'eps' stands for geometric approximation. The second 'epsOnVals' is for epsilon on values in case of node merging.
1257 * If 2 nodes distant from less than 'eps' and with value different with more than 'epsOnVals' an exception will be thrown.
1259 bool MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals) throw(INTERP_KERNEL::Exception)
1261 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1263 throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !");
1264 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1267 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes2(eps,ret,ret2);
1268 if(!ret)//no nodes have been merged.
1270 std::vector<DataArrayDouble *> arrays;
1271 _time_discr->getArrays(arrays);
1272 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1274 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),*iter);
1280 * This method applyies ParaMEDMEM::MEDCouplingPointSet::zipCoords method on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingPointSet.
1281 * If some nodes have disappeared true is returned.
1282 * 'epsOnVals' stands for epsilon in case of merge of cells. This value is used as tolerance in case the corresponding values differ.
1284 bool MEDCouplingFieldDouble::zipCoords(double epsOnVals) throw(INTERP_KERNEL::Exception)
1286 const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh);
1288 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1289 MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
1290 int oldNbOfNodes=meshC2->getNumberOfNodes();
1291 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipCoordsTraducer();
1292 if(meshC2->getNumberOfNodes()!=oldNbOfNodes)
1294 std::vector<DataArrayDouble *> arrays;
1295 _time_discr->getArrays(arrays);
1296 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1298 _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),*iter);
1306 * This method applyies ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingUMesh.
1307 * The semantic of 'compType' is given in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer method.
1308 * 'epsOnVals' stands for epsilon in case of merge of cells. This value is used as tolerance in case the corresponding values differ.
1310 bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals) throw(INTERP_KERNEL::Exception)
1312 const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh);
1314 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !");
1315 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCpy());
1316 int oldNbOfCells=meshC2->getNumberOfCells();
1317 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipConnectivityTraducer(compType);
1318 if(meshC2->getNumberOfCells()!=oldNbOfCells)
1320 std::vector<DataArrayDouble *> arrays;
1321 _time_discr->getArrays(arrays);
1322 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
1324 _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),*iter);
1332 * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists.
1333 * For the moment, this method is implemented for fields on cells.
1335 * \return a newly allocated field double containing the result that the user should deallocate.
1337 MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const throw(INTERP_KERNEL::Exception)
1339 const MEDCouplingMesh *mesh=getMesh();
1341 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !");
1342 if(getTypeOfField()!=ON_CELLS)
1343 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !");
1344 const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> umesh(mesh->buildUnstructured());
1345 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=clone(false);
1346 ret->setMesh(umesh);
1347 DataArrayInt *cellIds=0;
1348 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds);
1349 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds2=cellIds;
1350 ret->setMesh(mesh2);
1351 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end());
1352 std::vector<DataArrayDouble *> arrays;
1353 _time_discr->getArrays(arrays);
1355 std::vector<DataArrayDouble *> newArr(arrays.size());
1356 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > newArr2(arrays.size());
1357 for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++)
1361 newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
1362 newArr[i]=newArr2[i];
1365 ret->setArrays(newArr);
1366 ret->incrRef(); return ret;
1370 * This method applyies ParaMEDMEM::MEDCouplingUMesh::simplexize on 'this->_mesh'.
1371 * The semantic of 'policy' is given in ParaMEDMEM::MEDCouplingUMesh::simplexize method.
1373 bool MEDCouplingFieldDouble::simplexize(int policy) throw(INTERP_KERNEL::Exception)
1375 int oldNbOfCells=_mesh->getNumberOfCells();
1376 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> meshC2(_mesh->deepCpy());
1377 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->simplexize(policy);
1378 int newNbOfCells=meshC2->getNumberOfCells();
1379 if(oldNbOfCells==newNbOfCells)
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->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter);
1390 MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
1392 MEDCouplingTimeDiscretization *td=_time_discr->doublyContractedProduct();
1393 td->copyTinyAttrFrom(*_time_discr);
1394 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1395 ret->setName("DoublyContractedProduct");
1396 ret->setMesh(getMesh());
1400 MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const throw(INTERP_KERNEL::Exception)
1402 MEDCouplingTimeDiscretization *td=_time_discr->determinant();
1403 td->copyTinyAttrFrom(*_time_discr);
1404 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1405 ret->setName("Determinant");
1406 ret->setMesh(getMesh());
1410 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
1412 MEDCouplingTimeDiscretization *td=_time_discr->eigenValues();
1413 td->copyTinyAttrFrom(*_time_discr);
1414 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1415 ret->setName("EigenValues");
1416 ret->setMesh(getMesh());
1420 MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
1422 MEDCouplingTimeDiscretization *td=_time_discr->eigenVectors();
1423 td->copyTinyAttrFrom(*_time_discr);
1424 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1425 ret->setName("EigenVectors");
1426 ret->setMesh(getMesh());
1430 MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const throw(INTERP_KERNEL::Exception)
1432 MEDCouplingTimeDiscretization *td=_time_discr->inverse();
1433 td->copyTinyAttrFrom(*_time_discr);
1434 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1435 ret->setName("Inversion");
1436 ret->setMesh(getMesh());
1440 MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const throw(INTERP_KERNEL::Exception)
1442 MEDCouplingTimeDiscretization *td=_time_discr->trace();
1443 td->copyTinyAttrFrom(*_time_discr);
1444 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1445 ret->setName("Trace");
1446 ret->setMesh(getMesh());
1450 MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const throw(INTERP_KERNEL::Exception)
1452 MEDCouplingTimeDiscretization *td=_time_discr->deviator();
1453 td->copyTinyAttrFrom(*_time_discr);
1454 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1455 ret->setName("Trace");
1456 ret->setMesh(getMesh());
1460 MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const throw(INTERP_KERNEL::Exception)
1462 MEDCouplingTimeDiscretization *td=_time_discr->magnitude();
1463 td->copyTinyAttrFrom(*_time_discr);
1464 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1465 ret->setName("Magnitude");
1466 ret->setMesh(getMesh());
1470 MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
1472 MEDCouplingTimeDiscretization *td=_time_discr->maxPerTuple();
1473 td->copyTinyAttrFrom(*_time_discr);
1474 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1475 std::ostringstream oss;
1476 oss << "Max_" << getName();
1477 ret->setName(oss.str().c_str());
1478 ret->setMesh(getMesh());
1482 void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception)
1484 _time_discr->changeNbOfComponents(newNbOfComp,dftValue);
1487 MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1489 MEDCouplingTimeDiscretization *td=_time_discr->keepSelectedComponents(compoIds);
1490 td->copyTinyAttrFrom(*_time_discr);
1491 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone());
1492 ret->setName(getName());
1493 ret->setMesh(getMesh());
1497 void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
1499 _time_discr->setSelectedComponents(f->_time_discr,compoIds);
1502 void MEDCouplingFieldDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
1504 _time_discr->sortPerTuple(asc);
1507 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1509 if(!f1->areCompatibleForMerge(f2))
1510 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !");
1511 const MEDCouplingMesh *m1=f1->getMesh();
1512 const MEDCouplingMesh *m2=f2->getMesh();
1513 MEDCouplingMesh *m=m1->mergeMyselfWith(m2);
1514 MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr);
1515 td->copyTinyAttrFrom(*f1->_time_discr);
1516 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1519 ret->setName(f1->getName());
1520 ret->setDescription(f1->getDescription());
1525 * This method returns a newly created field that is the union of all fields in input array 'a'.
1526 * This method expects that 'a' is non empty. If not an exception will be thrown.
1527 * 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.
1528 * Generally speaking the first instance field in 'a' will be used to assign tiny attributes of returned field.
1530 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a) throw(INTERP_KERNEL::Exception)
1533 throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !");
1534 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms(a.size());
1535 std::vector< const MEDCouplingUMesh *> ms2(a.size());
1536 std::vector< const MEDCouplingTimeDiscretization *> tds(a.size());
1537 std::vector<const MEDCouplingFieldDouble *>::const_iterator it=a.begin();
1538 const MEDCouplingFieldDouble *ref=(*it++);
1539 for(;it!=a.end();it++)
1540 if(!ref->areCompatibleForMerge(*it))
1541 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !");
1542 for(int i=0;i<(int)a.size();i++)
1544 if(!a[i]->getMesh())
1545 throw INTERP_KERNEL::Exception("MergeFields : A field as no underlying mesh !");
1546 ms[i]=a[i]->getMesh()->buildUnstructured();
1548 tds[i]=a[i]->_time_discr;
1550 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::MergeUMeshes(ms2);
1551 m->setName(ms2[0]->getName()); m->setDescription(ms2[0]->getDescription());
1552 MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds);
1553 td->copyTinyAttrFrom(*(a[0]->_time_discr));
1554 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone());
1556 ret->setName(a[0]->getName());
1557 ret->setDescription(a[0]->getDescription());
1561 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1563 if(!f1->areCompatibleForMeld(f2))
1564 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MeldFields on them !");
1565 MEDCouplingTimeDiscretization *td=f1->_time_discr->meld(f2->_time_discr);
1566 td->copyTinyAttrFrom(*f1->_time_discr);
1567 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1568 ret->setMesh(f1->getMesh());
1572 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1574 if(!f1->areStrictlyCompatible(f2))
1575 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DotFields on them !");
1576 MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr);
1577 td->copyTinyAttrFrom(*f1->_time_discr);
1578 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1579 ret->setMesh(f1->getMesh());
1583 MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1585 if(!f1->areStrictlyCompatible(f2))
1586 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply CrossProductFields on them !");
1587 MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr);
1588 td->copyTinyAttrFrom(*f1->_time_discr);
1589 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1590 ret->setMesh(f1->getMesh());
1594 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1596 if(!f1->areStrictlyCompatible(f2))
1597 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MaxFields on them !");
1598 MEDCouplingTimeDiscretization *td=f1->_time_discr->max(f2->_time_discr);
1599 td->copyTinyAttrFrom(*f1->_time_discr);
1600 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1601 ret->setMesh(f1->getMesh());
1605 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1607 if(!f1->areStrictlyCompatible(f2))
1608 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MinFields on them !");
1609 MEDCouplingTimeDiscretization *td=f1->_time_discr->min(f2->_time_discr);
1610 td->copyTinyAttrFrom(*f1->_time_discr);
1611 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1612 ret->setMesh(f1->getMesh());
1616 MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1618 if(!f1->areStrictlyCompatible(f2))
1619 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply AddFields on them !");
1620 MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr);
1621 td->copyTinyAttrFrom(*f1->_time_discr);
1622 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1623 ret->setMesh(f1->getMesh());
1627 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1629 if(!areStrictlyCompatible(&other))
1630 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply += on them !");
1631 _time_discr->addEqual(other._time_discr);
1635 MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1637 if(!f1->areStrictlyCompatible(f2))
1638 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply SubstractFields on them !");
1639 MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(f2->_time_discr);
1640 td->copyTinyAttrFrom(*f1->_time_discr);
1641 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1642 ret->setMesh(f1->getMesh());
1646 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1648 if(!areStrictlyCompatible(&other))
1649 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply -= on them !");
1650 _time_discr->substractEqual(other._time_discr);
1654 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1656 if(!f1->areCompatibleForMul(f2))
1657 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MultiplyFields on them !");
1658 MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr);
1659 td->copyTinyAttrFrom(*f1->_time_discr);
1660 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1661 ret->setMesh(f1->getMesh());
1665 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1667 if(!areCompatibleForMul(&other))
1668 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply *= on them !");
1669 _time_discr->multiplyEqual(other._time_discr);
1673 MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception)
1675 if(!f1->areCompatibleForDiv(f2))
1676 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DivideFields on them !");
1677 MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(f2->_time_discr);
1678 td->copyTinyAttrFrom(*f1->_time_discr);
1679 MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
1680 ret->setMesh(f1->getMesh());
1684 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception)
1686 if(!areCompatibleForDiv(&other))
1687 throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !");
1688 _time_discr->divideEqual(other._time_discr);
1693 * This method writes the field series 'fs' in the VTK file 'fileName'.
1694 * 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.
1695 * If the single mesh is empty an exception will be thrown.
1696 * Finally there is a field in 'fs' with no name an exception will be thrown too.
1698 void MEDCouplingFieldDouble::WriteVTK(const char *fileName, const std::vector<const MEDCouplingFieldDouble *>& fs) throw(INTERP_KERNEL::Exception)
1702 std::size_t nfs=fs.size();
1703 const MEDCouplingMesh *m=fs[0]->getMesh();
1704 for(std::size_t i=1;i<nfs;i++)
1705 if(fs[i]->getMesh()!=m)
1706 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.");
1708 throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !");
1709 std::ostringstream coss,noss;
1710 for(std::size_t i=0;i<nfs;i++)
1712 const MEDCouplingFieldDouble *cur=fs[i];
1713 std::string name(cur->getName());
1716 std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !";
1717 throw INTERP_KERNEL::Exception(oss.str().c_str());
1719 TypeOfField typ=cur->getTypeOfField();
1721 cur->getArray()->writeVTK(coss,8,cur->getName());
1722 else if(typ==ON_NODES)
1723 cur->getArray()->writeVTK(noss,8,cur->getName());
1725 m->writeVTKAdvanced(fileName,coss.str(),noss.str());