X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingFieldDouble.cxx;h=f803a4a56a5f68a9660b521b2a637cc81d08e969;hb=9abc40a840f69fd7f07b356cd31876b64dc81e14;hp=4f14393c45d4f5415b3ba0751bff51be09e30fdb;hpb=8763c12d01e33d6845dd53be65b001514d00bd42;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx old mode 100644 new mode 100755 index 4f14393c4..f803a4a56 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -16,42 +16,50 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// Author : Anthony Geay (CEA/DEN) +// Author : Anthony Geay (EDF R&D) #include "MEDCouplingFieldDouble.hxx" #include "MEDCouplingFieldTemplate.hxx" +#include "MEDCouplingFieldT.txx" +#include "MEDCouplingFieldInt32.hxx" +#include "MEDCouplingFieldInt64.hxx" +#include "MEDCouplingFieldFloat.hxx" #include "MEDCouplingUMesh.hxx" #include "MEDCouplingTimeDiscretization.hxx" #include "MEDCouplingFieldDiscretization.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MCAuto.txx" +#include "MEDCouplingVoronoi.hxx" #include "MEDCouplingNatureOfField.hxx" +#include "MEDCouplingMemArray.txx" #include "InterpKernelAutoPtr.hxx" +#include "InterpKernelGaussCoords.hxx" #include #include #include #include -using namespace ParaMEDMEM; +using namespace MEDCoupling; +template class MEDCoupling::MEDCouplingFieldT; /*! * Creates a new MEDCouplingFieldDouble, of given spatial type and time discretization. * For more info, see \ref MEDCouplingFirstSteps3. * \param [in] type - the type of spatial discretization of the created field, one of - * (\ref ParaMEDMEM::ON_CELLS "ON_CELLS", - * \ref ParaMEDMEM::ON_NODES "ON_NODES", - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE", - * \ref ParaMEDMEM::ON_NODES_KR "ON_NODES_KR"). + * (\ref MEDCoupling::ON_CELLS "ON_CELLS", + * \ref MEDCoupling::ON_NODES "ON_NODES", + * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT", + * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE", + * \ref MEDCoupling::ON_NODES_KR "ON_NODES_KR"). * \param [in] td - the type of time discretization of the created field, one of - * (\ref ParaMEDMEM::NO_TIME "NO_TIME", - * \ref ParaMEDMEM::ONE_TIME "ONE_TIME", - * \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", - * \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). + * (\ref MEDCoupling::NO_TIME "NO_TIME", + * \ref MEDCoupling::ONE_TIME "ONE_TIME", + * \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME", + * \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. + * caller is to delete this field using decrRef() as it is no more needed. */ MEDCouplingFieldDouble* MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td) { @@ -60,7 +68,7 @@ MEDCouplingFieldDouble* MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTime /*! * Creates a new MEDCouplingFieldDouble, of a given time discretization and with a - * spatial type and supporting mesh copied from a given + * spatial type and supporting mesh copied from a given * \ref MEDCouplingFieldTemplatesPage "field template". * For more info, see \ref MEDCouplingFirstSteps3. * \warning This method does not deeply copy neither the mesh nor the spatial @@ -69,12 +77,12 @@ MEDCouplingFieldDouble* MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTime * \param [in] ft - the \ref MEDCouplingFieldTemplatesPage "field template" defining * the spatial discretization and the supporting mesh. * \param [in] td - the type of time discretization of the created field, one of - * (\ref ParaMEDMEM::NO_TIME "NO_TIME", - * \ref ParaMEDMEM::ONE_TIME "ONE_TIME", - * \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", - * \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). + * (\ref MEDCoupling::NO_TIME "NO_TIME", + * \ref MEDCoupling::ONE_TIME "ONE_TIME", + * \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME", + * \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. + * caller is to delete this field using decrRef() as it is no more needed. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td) { @@ -85,30 +93,25 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTempla * Sets a time \a unit of \a this field. For more info, see \ref MEDCouplingFirstSteps3. * \param [in] unit \a unit (string) in which time is measured. */ -void MEDCouplingFieldDouble::setTimeUnit(const std::string& unit) -{ - _time_discr->setTimeUnit(unit); -} +//void MEDCouplingFieldDouble::setTimeUnit(const std::string& unit) /*! * Returns a time unit of \a this field. * \return a string describing units in which time is measured. */ -std::string MEDCouplingFieldDouble::getTimeUnit() const -{ - return _time_discr->getTimeUnit(); -} +//std::string MEDCouplingFieldDouble::getTimeUnit() const + /*! * This method if possible the time information (time unit, time iteration, time unit and time value) with its support * that is to say its mesh. - * + * * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is * NO_TIME. */ void MEDCouplingFieldDouble::synchronizeTimeWithSupport() { - _time_discr->synchronizeTimeWith(_mesh); + timeDiscr()->synchronizeTimeWith(_mesh); } /*! @@ -119,11 +122,11 @@ void MEDCouplingFieldDouble::synchronizeTimeWithSupport() * - \ref MEDCouplingTemporalDisc "temporal discretization" data that holds array(s) * of field values, * - \ref MEDCouplingSpatialDisc "a spatial discretization". - * + * * \c clone(false) is rather dedicated for advanced users that want to limit the amount * of memory. It allows the user to perform methods like operator+(), operator*() * etc. with \a this and the returned field. If the user wants to duplicate deeply the - * underlying mesh he should call cloneWithMesh() method or deepCpy() instead. + * underlying mesh he should call cloneWithMesh() method or deepCopy() instead. * \warning The underlying \b mesh of the returned field is **always the same** * (pointer) as \a this one **whatever the value** of \a recDeepCpy parameter. * \param [in] recDeepCpy - if \c true, the copy of the underlying data arrays is @@ -137,38 +140,6 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const return new MEDCouplingFieldDouble(*this,recDeepCpy); } -/*! - * Returns a new MEDCouplingFieldDouble which is a copy of \a this one. The data - * of \a this field is copied either deep or shallow depending on \a recDeepCpy - * parameter. But the underlying mesh is always deep copied. - * Data that can be copied either deeply or shallow are: - * - \ref MEDCouplingTemporalDisc "temporal discretization" data that holds array(s) - * of field values, - * - \ref MEDCouplingSpatialDisc "a spatial discretization". - * - * This method behaves exactly like clone() except that here the underlying **mesh is - * always deeply duplicated**, whatever the value \a recDeepCpy parameter. - * The result of \c cloneWithMesh(true) is exactly the same as that of deepCpy(). - * So the resulting field can not be used together with \a this one in the methods - * like operator+(), operator*() etc. To avoid deep copying the underlying mesh, - * the user can call clone(). - * \param [in] recDeepCpy - if \c true, the copy of the underlying data arrays is - * deep, else all data arrays of \a this field are shared by the new field. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \sa clone() - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const -{ - MEDCouplingAutoRefCountObjectPtr ret=clone(recDeepCpy); - if(_mesh) - { - MEDCouplingAutoRefCountObjectPtr mCpy=_mesh->deepCpy(); - ret->setMesh(mCpy); - } - return ret.retn(); -} - /*! * Returns a new MEDCouplingFieldDouble which is a deep copy of \a this one **including * the mesh**. @@ -180,7 +151,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) c * caller is to delete this field using decrRef() as it is no more needed. * \sa cloneWithMesh() */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const +MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCopy() const { return cloneWithMesh(true); } @@ -191,26 +162,28 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const * shares the data array(s) with \a this field, or holds a deep copy of it, depending on * \a deepCopy parameter. But the underlying \b mesh is always **shallow copied**. * \param [in] td - the type of time discretization of the created field, one of - * (\ref ParaMEDMEM::NO_TIME "NO_TIME", - * \ref ParaMEDMEM::ONE_TIME "ONE_TIME", - * \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", - * \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). - * \param [in] deepCopy - if \c true, the copy of the underlying data arrays is + * (\ref MEDCoupling::NO_TIME "NO_TIME", + * \ref MEDCoupling::ONE_TIME "ONE_TIME", + * \ref MEDCoupling::LINEAR_TIME "LINEAR_TIME", + * \ref MEDCoupling::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). + * \param [in] deepCpy - if \c true, the copy of the underlying data arrays is * deep, else all data arrays of \a this field are shared by the new field. * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * + * caller is to delete this field using decrRef() as it is no more needed. + * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_buildNewTimeReprFromThis "Here is a C++ example."
* \ref py_mcfielddouble_buildNewTimeReprFromThis "Here is a Python example." + * \endif * \sa clone() */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const +MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const { - MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(td,deepCopy); - MEDCouplingAutoRefCountObjectPtr disc; + MEDCouplingTimeDiscretization *tdo=timeDiscr()->buildNewTimeReprFromThis(td,deepCpy); + MCAuto disc; if(_type) disc=_type->clone(); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),tdo,disc.retn()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),tdo,disc.retn())); ret->setMesh(getMesh()); ret->setName(getName()); ret->setDescription(getDescription()); @@ -218,54 +191,54 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfT } /*! - * This method converts a field on nodes (\a this) to a cell field (returned field). The convertion is a \b non \b conservative remapping ! - * This method is useful only for users that need a fast convertion from node to cell spatial discretization. The algorithm applied is simply to attach + * This method converts a field on nodes (\a this) to a cell field (returned field). The conversion is a \b non \b conservative remapping ! + * This method is useful only for users that need a fast conversion from node to cell spatial discretization. The algorithm applied is simply to attach * to each cell the average of values on nodes constituting this cell. * * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The * caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this. * \throw If \a this spatial discretization is empty or not ON_NODES. - * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkCoherency). - * + * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkConsistencyLight). + * * \warning This method is a \b non \b conservative method of remapping from node spatial discretization to cell spatial discretization. - * If a conservative method of interpolation is required ParaMEDMEM::MEDCouplingRemapper class should be used instead with "P1P0" method. + * If a conservative method of interpolation is required MEDCoupling::MEDCouplingRemapper class should be used instead with "P1P0" method. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::nodeToCellDiscretization() const { - checkCoherency(); + checkConsistencyLight(); TypeOfField tf(getTypeOfField()); if(tf!=ON_NODES) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::nodeToCellDiscretization : this field is expected to be on ON_NODES !"); - MEDCouplingAutoRefCountObjectPtr ret(clone(false)); - MEDCouplingAutoRefCountObjectPtr nsp(new MEDCouplingFieldDiscretizationP0); + MCAuto ret(clone(false)); + MCAuto nsp(new MEDCouplingFieldDiscretizationP0); ret->setDiscretization(nsp); - const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkCoherency call - int nbCells(m->getNumberOfCells()); + const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkConsistencyLight call + mcIdType nbCells=ToIdType(m->getNumberOfCells()); std::vector arrs(getArrays()); std::size_t sz(arrs.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > outArrsSafe(sz); std::vector outArrs(sz); + std::vector< MCAuto > outArrsSafe(sz); std::vector outArrs(sz); for(std::size_t j=0;jgetNumberOfComponents()); + std::size_t nbCompo(arrs[j]->getNumberOfComponents()); outArrsSafe[j]=DataArrayDouble::New(); outArrsSafe[j]->alloc(nbCells,nbCompo); outArrsSafe[j]->copyStringInfoFrom(*arrs[j]); outArrs[j]=outArrsSafe[j]; double *pt(outArrsSafe[j]->getPointer()); const double *srcPt(arrs[j]->begin()); - for(int i=0;i nodeIds; + std::vector nodeIds; m->getNodeIdsOfCell(i,nodeIds); std::fill(pt,pt+nbCompo,0.); std::size_t nbNodesInCell(nodeIds.size()); for(std::size_t k=0;k()); if(nbNodesInCell!=0) - std::transform(pt,pt+nbCompo,pt,std::bind2nd(std::multiplies(),1./((double)nbNodesInCell))); + std::transform(pt,pt+nbCompo,pt,std::bind(std::multiplies(),std::placeholders::_1,1./((double)nbNodesInCell))); else { std::ostringstream oss; oss << "MEDCouplingFieldDouble::nodeToCellDiscretization : Cell id #" << i << " has been detected to have no nodes !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + throw INTERP_KERNEL::Exception(oss.str()); } } } @@ -274,38 +247,38 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::nodeToCellDiscretization() const } /*! - * This method converts a field on cell (\a this) to a node field (returned field). The convertion is a \b non \b conservative remapping ! - * This method is useful only for users that need a fast convertion from cell to node spatial discretization. The algorithm applied is simply to attach + * This method converts a field on cell (\a this) to a node field (returned field). The conversion is a \b non \b conservative remapping ! + * This method is useful only for users that need a fast conversion from cell to node spatial discretization. The algorithm applied is simply to attach * to each node the average of values on cell sharing this node. If \a this lies on a mesh having orphan nodes the values applied on them will be NaN (division by 0.). * * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The * caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this. * \throw If \a this spatial discretization is empty or not ON_CELLS. - * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkCoherency). + * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkConsistencyLight). * * \warning This method is a \b non \b conservative method of remapping from cell spatial discretization to node spatial discretization. - * If a conservative method of interpolation is required ParaMEDMEM::MEDCouplingRemapper class should be used instead with "P0P1" method. + * If a conservative method of interpolation is required MEDCoupling::MEDCouplingRemapper class should be used instead with "P0P1" method. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::cellToNodeDiscretization() const { - checkCoherency(); + checkConsistencyLight(); TypeOfField tf(getTypeOfField()); if(tf!=ON_CELLS) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::cellToNodeDiscretization : this field is expected to be on ON_CELLS !"); - MEDCouplingAutoRefCountObjectPtr ret(clone(false)); - MEDCouplingAutoRefCountObjectPtr nsp(new MEDCouplingFieldDiscretizationP1); + MCAuto ret(clone(false)); + MCAuto nsp(new MEDCouplingFieldDiscretizationP1); ret->setDiscretization(nsp); - const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkCoherency call - MEDCouplingAutoRefCountObjectPtr rn(DataArrayInt::New()),rni(DataArrayInt::New()); + const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkConsistencyLight call + MCAuto rn(DataArrayIdType::New()),rni(DataArrayIdType::New()); m->getReverseNodalConnectivity(rn,rni); - MEDCouplingAutoRefCountObjectPtr rni2(rni->deltaShiftIndex()); - MEDCouplingAutoRefCountObjectPtr rni3(rni2->convertToDblArr()); rni2=0; + MCAuto rni2(rni->deltaShiftIndex()); + MCAuto rni3(rni2->convertToDblArr()); rni2=0; std::vector arrs(getArrays()); std::size_t sz(arrs.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > outArrsSafe(sz); std::vector outArrs(sz); + std::vector< MCAuto > outArrsSafe(sz); std::vector outArrs(sz); for(std::size_t j=0;j tmp(arrs[j]->selectByTupleIdSafe(rn->begin(),rn->end())); + MCAuto tmp(arrs[j]->selectByTupleIdSafe(rn->begin(),rn->end())); outArrsSafe[j]=(tmp->accumulatePerChunck(rni->begin(),rni->end())); tmp=0; outArrsSafe[j]->divideEqual(rni3); outArrsSafe[j]->copyStringInfoFrom(*arrs[j]); @@ -315,95 +288,6 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::cellToNodeDiscretization() const return ret.retn(); } -/*! - * Copies tiny info (component names, name and description) from an \a other field to - * \a this one. - * \warning The underlying mesh is not renamed (for safety reason). - * \param [in] other - the field to copy the tiny info from. - * \throw If \a this->getNumberOfComponents() != \a other->getNumberOfComponents() - */ -void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingField *other) -{ - MEDCouplingField::copyTinyStringsFrom(other); - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(otherC) - { - _time_discr->copyTinyStringsFrom(*otherC->_time_discr); - } -} - -/*! - * Copies only times, order and iteration from an \a other field to - * \a this one. The underlying mesh is not impacted by this method. - * Arrays are not impacted neither. - * \param [in] other - the field to tiny attributes from. - * \throw If \a this->getNumberOfComponents() != \a other->getNumberOfComponents() - */ -void MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *other) -{ - if(other) - { - _time_discr->copyTinyAttrFrom(*other->_time_discr); - } - -} - -void MEDCouplingFieldDouble::copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other) -{ - copyTinyStringsFrom(other); - copyTinyAttrFrom(other); -} - -/*! - * Returns a string describing \a this field. This string is outputted by \c print - * Python command. The string includes info on - * - name, - * - description, - * - \ref MEDCouplingSpatialDisc "spatial discretization", - * - \ref MEDCouplingTemporalDisc "time discretization", - * - \ref NatureOfField, - * - components, - * - mesh. - * - * \return std::string - the string describing \a this field. - */ -std::string MEDCouplingFieldDouble::simpleRepr() const -{ - std::ostringstream ret; - ret << "FieldDouble with name : \"" << getName() << "\"\n"; - ret << "Description of field is : \"" << getDescription() << "\"\n"; - if(_type) - { ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; } - else - { ret << "FieldDouble has no spatial discretization !\n"; } - if(_time_discr) - { ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n"; } - else - { ret << "FieldDouble has no time discretization !\n"; } - ret << "FieldDouble nature of field is : \"" << MEDCouplingNatureOfField::GetReprNoThrow(_nature) << "\"\n"; - if(getArray()) - { - if(getArray()->isAllocated()) - { - int nbOfCompo=getArray()->getNumberOfComponents(); - ret << "FieldDouble default array has " << nbOfCompo << " components and " << getArray()->getNumberOfTuples() << " tuples.\n"; - ret << "FieldDouble default array has following info on components : "; - for(int i=0;igetInfoOnComponent(i) << "\" "; - ret << "\n"; - } - else - { - ret << "Array set but not allocated !\n"; - } - } - if(_mesh) - ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr(); - else - ret << "Mesh support information : No mesh set !\n"; - return ret.str(); -} - /*! * Returns a string describing \a this field. The string includes info on * - name, @@ -425,8 +309,8 @@ std::string MEDCouplingFieldDouble::advancedRepr() const { ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; } else { ret << "FieldDouble has no space discretization set !\n"; } - if(_time_discr) - { ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n"; } + if(timeDiscr()) + { ret << "FieldDouble time discretization is : " << timeDiscr()->getStringRepr() << "\n"; } else { ret << "FieldDouble has no time discretization set !\n"; } if(getArray()) @@ -436,7 +320,7 @@ std::string MEDCouplingFieldDouble::advancedRepr() const else ret << "Mesh support information : No mesh set !\n"; std::vector arrays; - _time_discr->getArrays(arrays); + timeDiscr()->getArrays(arrays); int arrayId=0; for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++) { @@ -450,52 +334,10 @@ std::string MEDCouplingFieldDouble::advancedRepr() const return ret.str(); } -void MEDCouplingFieldDouble::writeVTK(const std::string& fileName, bool isBinary) const +std::string MEDCouplingFieldDouble::writeVTK(const std::string& fileName, bool isBinary) const { std::vector fs(1,this); - MEDCouplingFieldDouble::WriteVTK(fileName,fs,isBinary); -} - -bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::isEqualIfNotWhy : other instance is NULL !"); - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - { - reason="field given in input is not castable in MEDCouplingFieldDouble !"; - return false; - } - if(!MEDCouplingField::isEqualIfNotWhy(other,meshPrec,valsPrec,reason)) - return false; - if(!_time_discr->isEqualIfNotWhy(otherC->_time_discr,valsPrec,reason)) - { - reason.insert(0,"In FieldDouble time discretizations differ :"); - return false; - } - return true; -} - -/*! - * Checks equality of \a this and \a other field. Only numeric data is considered, - * i.e. names, description etc are not compared. - * \param [in] other - the field to compare with. - * \param [in] meshPrec - a precision used to compare node coordinates of meshes. - * \param [in] valsPrec - a precision used to compare data arrays of the two fields. - * \return bool - \c true if the two fields are equal, \c false else. - * \throw If \a other == NULL. - * \throw If the spatial discretization of \a this field is NULL. - */ -bool MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const -{ - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!MEDCouplingField::isEqualWithoutConsideringStr(other,meshPrec,valsPrec)) - return false; - if(!_time_discr->isEqualWithoutConsideringStr(otherC->_time_discr,valsPrec)) - return false; - return true; + return MEDCouplingFieldDouble::WriteVTK(fileName,fs,isBinary); } /*! @@ -507,59 +349,10 @@ bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other { if(!MEDCouplingField::areCompatibleForMerge(other)) return false; - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); + const MEDCouplingFieldDouble *otherC(dynamic_cast(other)); if(!otherC) return false; - if(!_time_discr->areCompatible(otherC->_time_discr)) - return false; - return true; -} - -/*! - * This method is more strict than MEDCouplingField::areCompatibleForMerge method. - * This method is used for operation on fields to operate a first check before attempting operation. - */ -bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const -{ - std::string tmp; - if(!MEDCouplingField::areStrictlyCompatible(other)) - return false; - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_time_discr->areStrictlyCompatible(otherC->_time_discr,tmp)) - return false; - return true; -} - -/*! - * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that - * number of components between \a this and 'other' can be different here (for operator*). - */ -bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const -{ - if(!MEDCouplingField::areStrictlyCompatible(other)) - return false; - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_time_discr->areStrictlyCompatibleForMul(otherC->_time_discr)) - return false; - return true; -} - -/*! - * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that - * number of components between \a this and 'other' can be different here (for operator/). - */ -bool MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const -{ - if(!MEDCouplingField::areStrictlyCompatible(other)) - return false; - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_time_discr->areStrictlyCompatibleForDiv(otherC->_time_discr)) + if(!timeDiscr()->areCompatible(otherC->timeDiscr())) return false; return true; } @@ -572,82 +365,14 @@ bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble * { if(!MEDCouplingField::areStrictlyCompatible(other)) return false; - if(!_time_discr->areCompatibleForMeld(other->_time_discr)) + if(!timeDiscr()->areCompatibleForMeld(other->timeDiscr())) return false; return true; } -/*! - * Permutes values of \a this field according to a given permutation array for cells - * renumbering. The underlying mesh is deeply copied and its cells are also permuted. - * The number of cells remains the same; for that the permutation array \a old2NewBg - * should not contain equal ids. - * ** Warning, this method modifies the mesh aggreagated by \a this (by performing a deep copy ) **. - * - * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is - * to be equal to \a this->getMesh()->getNumberOfCells(). - * \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation - * array, so that its maximal cell id to correspond to (be less than) the number - * of cells in mesh. This new array is then used for the renumbering. If \a - * check == \c false, \a old2NewBg is used as is, that is less secure as validity - * of ids in \a old2NewBg is not checked. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If \a check == \c true and \a old2NewBg contains equal ids. - * \throw If mesh nature does not allow renumbering (e.g. structured mesh). - * - * \ref cpp_mcfielddouble_renumberCells "Here is a C++ example".
- * \ref py_mcfielddouble_renumberCells "Here is a Python example". - */ -void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) -{ - renumberCellsWithoutMesh(old2NewBg,check); - MEDCouplingAutoRefCountObjectPtr m=_mesh->deepCpy(); - m->renumberCells(old2NewBg,check); - setMesh(m); - updateTime(); -} - -/*! - * Permutes values of \a this field according to a given permutation array for cells - * renumbering. The underlying mesh is \b not permuted. - * The number of cells remains the same; for that the permutation array \a old2NewBg - * should not contain equal ids. - * This method performs a part of job of renumberCells(). The reasonable use of this - * method is only for multi-field instances lying on the same mesh to avoid a - * systematic duplication and renumbering of _mesh attribute. - * \warning Use this method with a lot of care! - * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is - * to be equal to \a this->getMesh()->getNumberOfCells(). - * \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation - * array, so that its maximal cell id to correspond to (be less than) the number - * of cells in mesh. This new array is then used for the renumbering. If \a - * check == \c false, \a old2NewBg is used as is, that is less secure as validity - * of ids in \a old2NewBg is not checked. - * \throw If the mesh is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If \a check == \c true and \a old2NewBg contains equal ids. - * \throw If mesh nature does not allow renumbering (e.g. structured mesh). - */ -void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check) -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !"); - // - _type->renumberCells(old2NewBg,check); - std::vector arrays; - _time_discr->getArrays(arrays); - std::vector arrays2(arrays.size()); std::copy(arrays.begin(),arrays.end(),arrays2.begin()); - _type->renumberArraysForCell(_mesh,arrays2,old2NewBg,check); - // - updateTime(); -} - /*! * Permutes values of \a this field according to a given permutation array for node - * renumbering. The underlying mesh is deeply copied and its nodes are also permuted. + * renumbering. The underlying mesh is deeply copied and its nodes are also permuted. * The number of nodes can change, contrary to renumberCells(). * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is * to be equal to \a this->getMesh()->getNumberOfNodes(). @@ -657,19 +382,21 @@ void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool * \throw If the spatial discretization of \a this field is NULL. * \throw If \a check == \c true and \a old2NewBg contains equal ids. * \throw If mesh nature does not allow renumbering (e.g. structured mesh). - * \throw If values at merged nodes deffer more than \a eps. - * + * \throw If values at merged nodes differ more than \a eps. + * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_renumberNodes "Here is a C++ example".
* \ref py_mcfielddouble_renumberNodes "Here is a Python example". + * \endif */ -void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps) +void MEDCouplingFieldDouble::renumberNodes(const mcIdType *old2NewBg, double eps) { const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); if(!meshC) throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !"); - int nbOfNodes=meshC->getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); - int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1; + mcIdType nbOfNodes=meshC->getNumberOfNodes(); + MCAuto meshC2((MEDCouplingPointSet *)meshC->deepCopy()); + mcIdType newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1; renumberNodesWithoutMesh(old2NewBg,newNbOfNodes,eps); meshC2->renumberNodes(old2NewBg,newNbOfNodes); setMesh(meshC2); @@ -677,17 +404,17 @@ void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps) /*! * Permutes values of \a this field according to a given permutation array for nodes - * renumbering. The underlying mesh is \b not permuted. + * renumbering. The underlying mesh is \b not permuted. * The number of nodes can change, contrary to renumberCells(). * A given epsilon specifies a threshold of error in case of two nodes are merged but * the difference of values on these nodes are higher than \a eps. * This method performs a part of job of renumberNodes(), excluding node renumbering * in mesh. The reasonable use of this * method is only for multi-field instances lying on the same mesh to avoid a - * systematic duplication and renumbering of _mesh attribute. + * systematic duplication and renumbering of _mesh attribute. * \warning Use this method with a lot of care! * \warning In case of an exception thrown, the contents of the data array can be - * partially modified until the exception occurs. + * partially modified until the exception occurs. * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is * to be equal to \a this->getMesh()->getNumberOfNodes(). * \param [in] newNbOfNodes - a number of nodes in the mesh after renumbering. @@ -695,14 +422,14 @@ void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps) * the values differ more than \a eps, an exception is thrown. * \throw If the mesh is not set. * \throw If the spatial discretization of \a this field is NULL. - * \throw If values at merged nodes deffer more than \a eps. + * \throw If values at merged nodes differ more than \a eps. */ -void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps) +void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const mcIdType *old2NewBg, mcIdType newNbOfNodes, double eps) { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !"); std::vector arrays; - _time_discr->getArrays(arrays); + timeDiscr()->getArrays(arrays); for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) if(*iter) _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter); @@ -710,219 +437,72 @@ void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int /*! * Returns all tuple ids of \a this scalar field that fit the range [\a vmin, - * \a vmax]. This method calls DataArrayDouble::getIdsInRange(). + * \a vmax]. This method calls DataArrayDouble::findIdsInRange(). * \param [in] vmin - a lower boundary of the range. Tuples with values less than \a * vmin are not included in the result array. * \param [in] vmax - an upper boundary of the range. Tuples with values more than \a * vmax are not included in the result array. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids of selected + * \return DataArrayIdType * - a new instance of DataArrayIdType holding ids of selected * tuples. The caller is to delete this array using decrRef() as it is no * more needed. * \throw If the data array is not set. * \throw If \a this->getNumberOfComponents() != 1. */ -DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const +DataArrayIdType *MEDCouplingFieldDouble::findIdsInRange(double vmin, double vmax) const { if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getIdsInRange : no default array set !"); - return getArray()->getIdsInRange(vmin,vmax); + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::findIdsInRange : no default array set !"); + return getArray()->findIdsInRange(vmin,vmax); } -/*! - * Builds a newly created field, that the caller will have the responsability to deal with (decrRef()). - * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done. - * This method returns a restriction of \a this so that only tuples with ids specified in \a part will be contained in the returned field. - * Parameter \a part specifies **cell ids whatever the spatial discretization of this** ( - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS", - * \ref ParaMEDMEM::ON_NODES "ON_NODES", - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE", - * \ref ParaMEDMEM::ON_NODES_KR "ON_NODES_KR"). - * - * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a part contains following cell ids [3,7,6]. - * Then the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
- * Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh().
- * Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh().
- * Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh(). - * - * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a part contains following cellIds [3,7,6]. - * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field - * will contain 6 tuples and \a this field will lie on this restricted mesh. - * - * \param [in] part - an array of cell ids to include to the result field. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The caller is to delete this field using decrRef() as it is no more needed. - * - * \ref cpp_mcfielddouble_subpart1 "Here is a C++ example".
- * \ref py_mcfielddouble_subpart1 "Here is a Python example". - * \sa MEDCouplingFieldDouble::buildSubPartRange - */ - -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const +template +typename Traits::FieldType *ConvertToUField(const MEDCouplingFieldDouble *self) { - if(part==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !"); - return buildSubPart(part->begin(),part->end()); -} - -/*! - * Builds a newly created field, that the caller will have the responsability to deal with. - * \n This method makes the assumption that \a this field is correctly defined when this method is called (\a this->checkCoherency() returns without any exception thrown), **no check of this will be done**. - * \n This method returns a restriction of \a this so that only tuple ids specified in [ \a partBg , \a partEnd ) will be contained in the returned field. - * \n Parameter [\a partBg, \a partEnd ) specifies **cell ids whatever the spatial discretization** of \a this ( - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS", - * \ref ParaMEDMEM::ON_NODES "ON_NODES", - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE", - * \ref ParaMEDMEM::ON_NODES_KR "ON_NODES_KR"). - * - * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a partBg contains the following cell ids [3,7,6]. - * Then the returned field will lie on mesh having 3 cells and will contain 3 tuples. - *- Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh(). - *- Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh(). - *- Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh(). - * - * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a partBg contains following cellIds [3,7,6]. - * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field - * will contain 6 tuples and \a this field will lie on this restricted mesh. - * - * \param [in] partBg - start (included) of input range of cell ids to select [ \a partBg, \a partEnd ) - * \param [in] partEnd - end (not included) of input range of cell ids to select [ \a partBg, \a partEnd ) - * \return a newly allocated field the caller should deal with. - * - * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \a this->getMesh(). - * - * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."
- * \ref py_mcfielddouble_subpart1 "Here a Python example." - * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); - DataArrayInt *arrSelect; - MEDCouplingAutoRefCountObjectPtr m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect); - MEDCouplingAutoRefCountObjectPtr arrSelect2(arrSelect); - MEDCouplingAutoRefCountObjectPtr ret=clone(false);//quick shallow copy. - const MEDCouplingFieldDiscretization *disc=getDiscretization(); - if(disc) - ret->setDiscretization(MEDCouplingAutoRefCountObjectPtr(disc->clonePart(partBg,partEnd))); - ret->setMesh(m); - std::vector arrays; - _time_discr->getArrays(arrays); - std::vector arrs; - std::vector< MEDCouplingAutoRefCountObjectPtr > arrsSafe; - const int *arrSelBg=arrSelect->begin(); - const int *arrSelEnd=arrSelect->end(); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + MCAuto tmp(MEDCouplingFieldTemplate::New(*self)); + int t1,t2; + double t0(self->getTime(t1,t2)); + MCAuto::FieldType > ret(Traits::FieldType::New(*tmp,self->getTimeDiscretization())); + ret->setTime(t0,t1,t2); + if(self->getArray()) { - DataArrayDouble *arr=0; - if(*iter) - arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); - arrs.push_back(arr); arrsSafe.push_back(arr); + MCAuto::ArrayType> arr(self->getArray()->convertToOtherTypeOfArr()); + ret->setArray(arr); } - ret->_time_discr->setArrays(arrs,0); return ret.retn(); } -/*! - * This method is equivalent to MEDCouplingFieldDouble::buildSubPart, the only difference is that the input range of cell ids is - * given using a range given \a begin, \a end and \a step to optimize the part computation. - * - * \sa MEDCouplingFieldDouble::buildSubPart - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPartRange(int begin, int end, int step) const +MEDCouplingFieldInt32 *MEDCouplingFieldDouble::convertToIntField() const { - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); - DataArrayInt *arrSelect; - int beginOut,endOut,stepOut; - MEDCouplingAutoRefCountObjectPtr m=_type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,arrSelect); - MEDCouplingAutoRefCountObjectPtr arrSelect2(arrSelect); - MEDCouplingAutoRefCountObjectPtr ret=clone(false);//quick shallow copy. - const MEDCouplingFieldDiscretization *disc=getDiscretization(); - if(disc) - ret->setDiscretization(MEDCouplingAutoRefCountObjectPtr(disc->clonePartRange(begin,end,step))); - ret->setMesh(m); - std::vector arrays; - _time_discr->getArrays(arrays); - std::vector arrs; - std::vector< MEDCouplingAutoRefCountObjectPtr > arrsSafe; - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - { - DataArrayDouble *arr=0; - if(*iter) - { - if(arrSelect) - { - const int *arrSelBg=arrSelect->begin(); - const int *arrSelEnd=arrSelect->end(); - arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); - } - else - arr=(*iter)->selectByTupleId2(beginOut,endOut,stepOut); - } - arrs.push_back(arr); arrsSafe.push_back(arr); - } - ret->_time_discr->setArrays(arrs,0); - return ret.retn(); + return ConvertToUField(this); } - -/*! - * Returns a type of \ref MEDCouplingTemporalDisc "time discretization" of \a this field. - * \return ParaMEDMEM::TypeOfTimeDiscretization - an enum item describing the time - * discretization type. - */ -TypeOfTimeDiscretization MEDCouplingFieldDouble::getTimeDiscretization() const +MEDCouplingFieldInt64 *MEDCouplingFieldDouble::convertToInt64Field() const +{ + return ConvertToUField(this); +} +MEDCouplingFieldFloat *MEDCouplingFieldDouble::convertToFloatField() const { - return _time_discr->getEnum(); + return ConvertToUField(this); } -MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingField(type), - _time_discr(MEDCouplingTimeDiscretization::New(td)) +MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingFieldT(type,MEDCouplingTimeDiscretization::New(td)) { } /*! * ** WARINING : This method do not deeply copy neither mesh nor spatial discretization. Only a shallow copy (reference) is done for mesh and spatial discretization ! ** */ -MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingField(ft,false), - _time_discr(MEDCouplingTimeDiscretization::New(td)) +MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingFieldT(ft,MEDCouplingTimeDiscretization::New(td),false) { } -MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other,deepCopy), - _time_discr(other._time_discr->performCpy(deepCopy)) +MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCpy):MEDCouplingFieldT(other,deepCpy) { } -MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingField(type,n),_time_discr(td) +MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingFieldT(type,n,td) { } -MEDCouplingFieldDouble::~MEDCouplingFieldDouble() -{ - delete _time_discr; -} - -/*! - * Checks if \a this field is correctly defined, else an exception is thrown. - * \throw If the mesh is not set. - * \throw If the data array is not set. - * \throw If the spatial discretization of \a this field is NULL. - * \throw If \a this->getTimeTolerance() < 0. - * \throw If the temporal discretization data is incorrect. - * \throw If mesh data does not correspond to field data. - */ -void MEDCouplingFieldDouble::checkCoherency() const -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::checkCoherency : no spatial discretization !"); - _time_discr->checkCoherency(); - _type->checkCoherencyBetween(_mesh,getArray()); -} - /*! * Accumulate values of a given component of \a this field. * \param [in] compId - the index of the component of interest. @@ -940,7 +520,7 @@ double MEDCouplingFieldDouble::accumulate(int compId) const /*! * Accumulates values of each component of \a this array. - * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated + * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated * by the caller, that is filled by this method with sum value for each * component. * \throw If the data array is not set. @@ -963,15 +543,15 @@ void MEDCouplingFieldDouble::accumulate(double *res) const double MEDCouplingFieldDouble::getMaxValue() const { std::vector arrays; - _time_discr->getArrays(arrays); - double ret=-std::numeric_limits::max(); + timeDiscr()->getArrays(arrays); + double ret(-std::numeric_limits::max()); bool isExistingArr=false; for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) { if(*iter) { isExistingArr=true; - int loc; + mcIdType loc; ret=std::max(ret,(*iter)->getMaxValue(loc)); } } @@ -983,30 +563,30 @@ double MEDCouplingFieldDouble::getMaxValue() const /*! * Returns the maximal value and all its locations within \a this scalar field. * Only the first of available data arrays is checked. - * \param [out] tupleIds - a new instance of DataArrayInt containg indices of + * \param [out] tupleIds - a new instance of DataArrayIdType containing indices of * tuples holding the maximal value. The caller is to delete it using * decrRef() as it is no more needed. * \return double - the maximal value among all values of the first array of \a this filed. * \throw If \a this->getNumberOfComponents() != 1. * \throw If there is an empty data array in \a this field. */ -double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const +double MEDCouplingFieldDouble::getMaxValue2(DataArrayIdType*& tupleIds) const { std::vector arrays; - _time_discr->getArrays(arrays); - double ret=-std::numeric_limits::max(); + timeDiscr()->getArrays(arrays); + double ret(-std::numeric_limits::max()); bool isExistingArr=false; tupleIds=0; - MEDCouplingAutoRefCountObjectPtr ret1; + MCAuto ret1; for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) { if(*iter) { isExistingArr=true; - DataArrayInt *tmp; + DataArrayIdType *tmp; ret=std::max(ret,(*iter)->getMaxValue2(tmp)); - MEDCouplingAutoRefCountObjectPtr tmpSafe(tmp); - if(!((const DataArrayInt *)ret1)) + MCAuto tmpSafe(tmp); + if(!((const DataArrayIdType *)ret1)) ret1=tmpSafe; } } @@ -1027,15 +607,15 @@ double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const double MEDCouplingFieldDouble::getMinValue() const { std::vector arrays; - _time_discr->getArrays(arrays); - double ret=std::numeric_limits::max(); + timeDiscr()->getArrays(arrays); + double ret(std::numeric_limits::max()); bool isExistingArr=false; for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) { if(*iter) { isExistingArr=true; - int loc; + mcIdType loc; ret=std::min(ret,(*iter)->getMinValue(loc)); } } @@ -1047,30 +627,30 @@ double MEDCouplingFieldDouble::getMinValue() const /*! * Returns the minimal value and all its locations within \a this scalar field. * Only the first of available data arrays is checked. - * \param [out] tupleIds - a new instance of DataArrayInt containg indices of + * \param [out] tupleIds - a new instance of DataArrayIdType containing indices of * tuples holding the minimal value. The caller is to delete it using * decrRef() as it is no more needed. * \return double - the minimal value among all values of the first array of \a this filed. * \throw If \a this->getNumberOfComponents() != 1. * \throw If there is an empty data array in \a this field. */ -double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const +double MEDCouplingFieldDouble::getMinValue2(DataArrayIdType*& tupleIds) const { std::vector arrays; - _time_discr->getArrays(arrays); - double ret=-std::numeric_limits::max(); + timeDiscr()->getArrays(arrays); + double ret(-std::numeric_limits::max()); bool isExistingArr=false; tupleIds=0; - MEDCouplingAutoRefCountObjectPtr ret1; + MCAuto ret1; for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) { if(*iter) { isExistingArr=true; - DataArrayInt *tmp; + DataArrayIdType *tmp; ret=std::max(ret,(*iter)->getMinValue2(tmp)); - MEDCouplingAutoRefCountObjectPtr tmpSafe(tmp); - if(!((const DataArrayInt *)ret1)) + MCAuto tmpSafe(tmp); + if(!((const DataArrayIdType *)ret1)) ret1=tmpSafe; } } @@ -1107,29 +687,16 @@ double MEDCouplingFieldDouble::norm2() const return getArray()->norm2(); } -/*! - * This method returns the max norm of \a this field. - * \f[ - * \max_{0 \leq i < nbOfEntity}{abs(val[i])} - * \f] - * \throw If the data array is not set. - */ -double MEDCouplingFieldDouble::normMax() const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !"); - return getArray()->normMax(); -} /*! - * Computes sums of values of each component of \a this field wighted with - * values returned by buildMeasureField(). + * Computes the weighted average of values of each component of \a this field, the weights being the + * values returned by buildMeasureField(). * \param [out] res - pointer to an array of result sum values, of size at least \a * this->getNumberOfComponents(), that is to be allocated by the caller. - * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by - * buildMeasureField() that makes this method slower. If a user is sure that all - * cells of the underlying mesh have correct orientation, he can put \a isWAbs == - * \c false that speeds up this method. + * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by + * buildMeasureField(). It makes this method slower. If you are sure that all + * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs == + * \c false to speed up the method. * \throw If the mesh is not set. * \throw If the data array is not set. */ @@ -1137,22 +704,23 @@ void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) c { if(getArray()==0) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !"); - MEDCouplingAutoRefCountObjectPtr w=buildMeasureField(isWAbs); - double deno=w->getArray()->accumulate(0); - MEDCouplingAutoRefCountObjectPtr arr=getArray()->deepCpy(); + MCAuto w=buildMeasureField(isWAbs); + double deno=w->getArray()->accumulate((std::size_t)0); + MCAuto arr=getArray()->deepCopy(); arr->multiplyEqual(w->getArray()); - std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind2nd(std::multiplies(),1./deno)); arr->accumulate(res); + std::size_t nCompo = getArray()->getNumberOfComponents(); + std::transform(res,res+nCompo,res,std::bind(std::multiplies(),std::placeholders::_1,1./deno)); } /*! - * Computes a sum of values of a given component of \a this field wighted with + * Computes the weighted average of values of a given component of \a this field, the weights being the * values returned by buildMeasureField(). * \param [in] compId - an index of the component of interest. - * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by - * buildMeasureField() that makes this method slower. If a user is sure that all - * cells of the underlying mesh have correct orientation, he can put \a isWAbs == - * \c false that speeds up this method. + * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weights computed by + * buildMeasureField(). It makes this method slower. If you are sure that all + * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs == + * \c false to speed up the method. * \throw If the mesh is not set. * \throw If the data array is not set. * \throw If \a compId is not valid. @@ -1160,11 +728,11 @@ void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) c */ double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const { - int nbComps=getArray()->getNumberOfComponents(); - if(compId<0 || compId>=nbComps) + std::size_t nbComps=getArray()->getNumberOfComponents(); + if(compId<0 || compId>=ToIdType(nbComps)) { std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + throw INTERP_KERNEL::Exception(oss.str()); } INTERP_KERNEL::AutoPtr res=new double[nbComps]; getWeightedAverageValue(res,isWAbs); @@ -1186,13 +754,13 @@ double MEDCouplingFieldDouble::normL1(int compId) const { if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1 !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !"); - int nbComps=getArray()->getNumberOfComponents(); - if(compId<0 || compId>=nbComps) + std::size_t nbComps=getArray()->getNumberOfComponents(); + if(compId<0 || compId>=ToIdType(nbComps)) { std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + throw INTERP_KERNEL::Exception(oss.str()); } INTERP_KERNEL::AutoPtr res=new double[nbComps]; _type->normL1(_mesh,getArray(),res); @@ -1213,7 +781,7 @@ void MEDCouplingFieldDouble::normL1(double *res) const { if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !"); _type->normL1(_mesh,getArray(),res); } @@ -1233,13 +801,13 @@ double MEDCouplingFieldDouble::normL2(int compId) const { if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !"); - int nbComps=getArray()->getNumberOfComponents(); - if(compId<0 || compId>=nbComps) + std::size_t nbComps=getArray()->getNumberOfComponents(); + if(compId<0 || compId>=ToIdType(nbComps)) { std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + throw INTERP_KERNEL::Exception(oss.str()); } INTERP_KERNEL::AutoPtr res=new double[nbComps]; _type->normL2(_mesh,getArray(),res); @@ -1260,11 +828,53 @@ void MEDCouplingFieldDouble::normL2(double *res) const { if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !"); _type->normL2(_mesh,getArray(),res); } +/*! + * Returns the \c infinite norm of values of a given component of \a this field: +* \f[ + * \max_{0 \leq i < nbOfEntity}{abs(val[i])} + * \f] + * \param [in] compId - an index of the component of interest. + * \throw If \a compId is not valid. + A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ). + * \throw If the data array is not set. + */ +double MEDCouplingFieldDouble::normMax(int compId) const +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !"); + std::size_t nbComps=getArray()->getNumberOfComponents(); + if(compId<0 || compId>=ToIdType(nbComps)) + { + std::ostringstream oss; oss << "MEDCouplingFieldDouble::normMax : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + INTERP_KERNEL::AutoPtr res=new double[nbComps]; + getArray()->normMaxPerComponent(res); + return res[compId]; +} + +/*! + * Returns the \c infinite norm of values of each component of \a this field: + * \f[ + * \max_{0 \leq i < nbOfEntity}{abs(val[i])} + * \f] + * \param [out] res - pointer to an array of result values, of size at least \a + * this->getNumberOfComponents(), that is to be allocated by the caller. + * \throw If the data array is not set. + * + */ +void MEDCouplingFieldDouble::normMax(double *res) const +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !"); + getArray()->normMaxPerComponent(res); +} + /*! * Computes a sum of values of a given component of \a this field multiplied by * values returned by buildMeasureField(). @@ -1283,13 +893,13 @@ double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const { if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral !"); - int nbComps=getArray()->getNumberOfComponents(); - if(compId<0 || compId>=nbComps) + std::size_t nbComps=getArray()->getNumberOfComponents(); + if(compId<0 || compId>=ToIdType(nbComps)) { std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + throw INTERP_KERNEL::Exception(oss.str()); } INTERP_KERNEL::AutoPtr res=new double[nbComps]; _type->integral(_mesh,getArray(),isWAbs,res); @@ -1314,7 +924,7 @@ void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const { if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral2 !"); _type->integral(_mesh,getArray(),isWAbs,res); } @@ -1334,15 +944,17 @@ void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const * \throw If the mesh is not set. * \throw If the mesh is not a structured one. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_getValueOnPos "Here is a C++ example".
* \ref py_mcfielddouble_getValueOnPos "Here is a Python example". + * \endif */ -void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const +void MEDCouplingFieldDouble::getValueOnPos(mcIdType i, mcIdType j, mcIdType k, double *res) const { - const DataArrayDouble *arr=_time_discr->getArray(); + const DataArrayDouble *arr=timeDiscr()->getArray(); if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !"); _type->getValueOnPos(arr,_mesh,i,j,k,res); } @@ -1356,15 +968,17 @@ void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) con * \throw If the mesh is not set. * \throw If \a spaceLoc is out of the spatial discretization. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_getValueOn "Here is a C++ example".
* \ref py_mcfielddouble_getValueOn "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const { - const DataArrayDouble *arr=_time_discr->getArray(); + const DataArrayDouble *arr=timeDiscr()->getArray(); if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !"); _type->getValueOn(arr,_mesh,spaceLoc,res); } @@ -1376,21 +990,23 @@ void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) con * \param [in] nbOfPoints - number of points of interest. * \return DataArrayDouble * - a new instance of DataArrayDouble holding field * values relating to the input points. This array is of size \a nbOfPoints - * tuples per \a this->getNumberOfComponents() components. The caller is to + * tuples per \a this->getNumberOfComponents() components. The caller is to * delete this array using decrRef() as it is no more needed. * \throw If the spatial discretization of \a this field is NULL. * \throw If the mesh is not set. * \throw If any point in \a spaceLoc is out of the spatial discretization. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_getValueOnMulti "Here is a C++ example".
* \ref py_mcfielddouble_getValueOnMulti "Here is a Python example". + * \endif */ -DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const +DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, mcIdType nbOfPoints) const { - const DataArrayDouble *arr=_time_discr->getArray(); + const DataArrayDouble *arr=timeDiscr()->getArray(); if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnMulti !"); return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints); } @@ -1407,28 +1023,30 @@ DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, * \throw If \a spaceLoc is out of the spatial discretization. * \throw If \a time is not covered by \a this->_time_discr. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_getValueOn_time "Here is a C++ example".
* \ref py_mcfielddouble_getValueOn_time "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const { - std::vector< const DataArrayDouble *> arrs=_time_discr->getArraysForTime(time); + std::vector< const DataArrayDouble *> arrs=timeDiscr()->getArraysForTime(time); if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOn !"); std::vector res2; for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++) { - int sz=(int)res2.size(); + std::size_t sz=res2.size(); res2.resize(sz+(*iter)->getNumberOfComponents()); _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]); } - _time_discr->getValueForTime(time,res2,res); + timeDiscr()->getValueForTime(time,res2,res); } /*! - * Apply a liner function to a given component of \a this field, so that + * Apply a linear function to a given component of \a this field, so that * a component value (x) becomes \f$ a * x + b \f$. * \param [in] a - the first coefficient of the function. * \param [in] b - the second coefficient of the function. @@ -1437,7 +1055,19 @@ void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, dou */ void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId) { - _time_discr->applyLin(a,b,compoId); + timeDiscr()->applyLin(a,b,compoId); +} + +/*! + * Apply a linear function to all components of \a this field, so that + * values (x) becomes \f$ a * x + b \f$. + * \param [in] a - the first coefficient of the function. + * \param [in] b - the second coefficient of the function. + * \throw If the data array(s) is(are) not set. + */ +void MEDCouplingFieldDouble::applyLin(double a, double b) +{ + timeDiscr()->applyLin(a,b); } /*! @@ -1445,14 +1075,14 @@ void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId) * All tuples will have the same value 'value'. * An exception is thrown if no underlying mesh is defined. */ -MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) { if(!_mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform operator = !"); - int nbOfTuple=_type->getNumberOfTuples(_mesh); - _time_discr->setOrCreateUniformValueOnAllComponents(nbOfTuple,value); + mcIdType nbOfTuple=_type->getNumberOfTuples(_mesh); + timeDiscr()->setOrCreateUniformValueOnAllComponents(nbOfTuple,value); return *this; } @@ -1466,16 +1096,18 @@ MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) throw(IN * \throw If \a func returns \c false. * \throw If the spatial discretization of \a this field is NULL. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example". + * \endif */ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) { if(!_mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !"); - MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); - _time_discr->fillFromAnalytic(loc,nbOfComp,func); + MCAuto loc=_type->getLocalizationOfDiscValues(_mesh); + timeDiscr()->fillFromAnalytic(loc,nbOfComp,func); } /*! @@ -1510,17 +1142,19 @@ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate f * \throw If the spatial discretization of \a this field is NULL. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_fillFromAnalytic "Here is a C++ example".
* \ref py_mcfielddouble_fillFromAnalytic "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) { if(!_mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !"); - MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); - _time_discr->fillFromAnalytic(loc,nbOfComp,func); + MCAuto loc=_type->getLocalizationOfDiscValues(_mesh); + timeDiscr()->fillFromAnalytic(loc,nbOfComp,func); } /*! @@ -1528,14 +1162,14 @@ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& f * The function is applied to coordinates of value location points. For example, if * \a this field is on cells, the function is applied to cell barycenters.
* This method differs from - * \ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()" + * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()" * by the way how variable * names, used in the function, are associated with components of coordinates of field * location points; here, a variable name corresponding to a component is retrieved from * a corresponding node coordinates array (where it is set via * DataArrayDouble::setInfoOnComponent()).
* For more info on supported expressions that can be used in the function, see \ref - * MEDCouplingArrayApplyFuncExpr.
+ * MEDCouplingArrayApplyFuncExpr.
* In a general case, a value resulting from the function evaluation is assigned to all * components of a field value. But there is a possibility to have its own expression for * each component within one function. For this purpose, there are predefined variable @@ -1557,17 +1191,19 @@ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& f * \throw If the spatial discretization of \a this field is NULL. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_fillFromAnalytic2 "Here is a C++ example".
* \ref py_mcfielddouble_fillFromAnalytic2 "Here is a Python example". + * \endif */ -void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const std::string& func) +void MEDCouplingFieldDouble::fillFromAnalyticCompo(int nbOfComp, const std::string& func) { if(!_mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic2 !"); - MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); - _time_discr->fillFromAnalytic2(loc,nbOfComp,func); + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !"); + if(_type.isNull()) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticCompo !"); + MCAuto loc=_type->getLocalizationOfDiscValues(_mesh); + timeDiscr()->fillFromAnalyticCompo(loc,nbOfComp,func); } /*! @@ -1575,7 +1211,7 @@ void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const std::string& * The function is applied to coordinates of value location points. For example, if * \a this field is on cells, the function is applied to cell barycenters.
* This method differs from - * \ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()" + * \ref MEDCoupling::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) "fillFromAnalytic()" * by the way how variable * names, used in the function, are associated with components of coordinates of field * location points; here, a component index of a variable is defined by a @@ -1604,17 +1240,19 @@ void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const std::string& * \throw If the spatial discretization of \a this field is NULL. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_fillFromAnalytic3 "Here is a C++ example".
* \ref py_mcfielddouble_fillFromAnalytic3 "Here is a Python example". + * \endif */ -void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector& varsOrder, const std::string& func) +void MEDCouplingFieldDouble::fillFromAnalyticNamedCompo(int nbOfComp, const std::vector& varsOrder, const std::string& func) { if(!_mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic3 !"); - MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); - _time_discr->fillFromAnalytic3(loc,nbOfComp,varsOrder,func); + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalyticCompo : no mesh defined !"); + if(_type.isNull()) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalyticNamedCompo !"); + MCAuto loc=_type->getLocalizationOfDiscValues(_mesh); + timeDiscr()->fillFromAnalyticNamedCompo(loc,nbOfComp,varsOrder,func); } /*! @@ -1625,33 +1263,37 @@ void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vectorapplyFunc(nbOfComp,func); + timeDiscr()->applyFunc(nbOfComp,func); } /*! * Fill \a this field with a given value.
* This method is a specialization of other overloaded methods. When \a nbOfComp == 1 - * this method is equivalent to ParaMEDMEM::MEDCouplingFieldDouble::operator=(). + * this method is equivalent to MEDCoupling::MEDCouplingFieldDouble::operator=(). * \param [in] nbOfComp - the number of components for \a this field to have. * \param [in] val - the value to assign to every atomic value of \a this field. * \throw If the spatial discretization of \a this field is NULL. * \throw If the mesh is not set. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_applyFunc_val "Here is a C++ example".
* \ref py_mcfielddouble_applyFunc_val "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val) { if(!_mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform applyFunc !"); - int nbOfTuple=_type->getNumberOfTuples(_mesh); - _time_discr->setUniformValue(nbOfTuple,nbOfComp,val); + mcIdType nbOfTuple=_type->getNumberOfTuples(_mesh); + timeDiscr()->setUniformValue(nbOfTuple,nbOfComp,val); } /*! @@ -1674,19 +1316,21 @@ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val) * - "2*x + z" produces (5.,5.,5.,5.) * - "2*x + 0*y + z" produces (9.,9.,9.,9.) * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.) - * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,8.,1.) * * \param [in] nbOfComp - the number of components for \a this field to have. * \param [in] func - the function used to compute values of \a this field. * This function is to compute a field value basing on a current field value. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_applyFunc "Here is a C++ example".
* \ref py_mcfielddouble_applyFunc "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) { - _time_discr->applyFunc(nbOfComp,func); + timeDiscr()->applyFunc(nbOfComp,func); } @@ -1696,7 +1340,7 @@ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) * For more info on supported expressions that can be used in the function, see \ref * MEDCouplingArrayApplyFuncExpr.
* This method differs from - * \ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()" + * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()" * by the way how variable * names, used in the function, are associated with components of field values; * here, a variable name corresponding to a component is retrieved from @@ -1712,26 +1356,28 @@ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) * - "2*x + z" produces (5.,5.,5.,5.) * - "2*x + 0*y + z" produces (9.,9.,9.,9.) * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.) - * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,8.,1.) * * \param [in] nbOfComp - the number of components for \a this field to have. * \param [in] func - the function used to compute values of \a this field. * This function is to compute a new field value basing on a current field value. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_applyFunc2 "Here is a C++ example".
* \ref py_mcfielddouble_applyFunc2 "Here is a Python example". + * \endif */ -void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const std::string& func) +void MEDCouplingFieldDouble::applyFuncCompo(int nbOfComp, const std::string& func) { - _time_discr->applyFunc2(nbOfComp,func); + timeDiscr()->applyFuncCompo(nbOfComp,func); } /*! * Modifies values of \a this field by applying a function to each tuple of all * data arrays. * This method differs from - * \ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()" + * \ref MEDCoupling::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) "applyFunc()" * by the way how variable * names, used in the function, are associated with components of field values; * here, a component index of a variable is defined by a @@ -1756,12 +1402,14 @@ void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const std::string& func) * This function is to compute a new field value basing on a current field value. * \throw If computing \a func fails. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_applyFunc3 "Here is a C++ example".
* \ref py_mcfielddouble_applyFunc3 "Here is a Python example". + * \endif */ -void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func) +void MEDCouplingFieldDouble::applyFuncNamedCompo(int nbOfComp, const std::vector& varsOrder, const std::string& func) { - _time_discr->applyFunc3(nbOfComp,varsOrder,func); + timeDiscr()->applyFuncNamedCompo(nbOfComp,varsOrder,func); } /*! @@ -1771,7 +1419,7 @@ void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector * The function can include **only one** arbitrary named variable * (e.g. "x","y" or "va44") to refer to a field atomic value.
- * In a general case, a value resulting from the function evaluation is assigned to + * In a general case, a value resulting from the function evaluation is assigned to * a single field value. But there is a possibility to have its own expression for * each component within one function. For this purpose, there are predefined variable * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to @@ -1786,12 +1434,14 @@ void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector * \ref py_mcfielddouble_applyFunc_same_nb_comp "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::applyFunc(const std::string& func) { - _time_discr->applyFunc(func); + timeDiscr()->applyFunc(func); } /*! @@ -1801,7 +1451,7 @@ void MEDCouplingFieldDouble::applyFunc(const std::string& func) */ void MEDCouplingFieldDouble::applyFuncFast32(const std::string& func) { - _time_discr->applyFuncFast32(func); + timeDiscr()->applyFuncFast32(func); } /*! @@ -1811,16 +1461,16 @@ void MEDCouplingFieldDouble::applyFuncFast32(const std::string& func) */ void MEDCouplingFieldDouble::applyFuncFast64(const std::string& func) { - _time_discr->applyFuncFast64(func); + timeDiscr()->applyFuncFast64(func); } /*! * Returns number of components in the data array. For more info on the data arrays, - * see \ref MEDCouplingArrayPage. + * see \ref arrays. * \return int - the number of components in the data array. * \throw If the data array is not set. */ -int MEDCouplingFieldDouble::getNumberOfComponents() const +std::size_t MEDCouplingFieldDouble::getNumberOfComponents() const { if(getArray()==0) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !"); @@ -1828,40 +1478,46 @@ int MEDCouplingFieldDouble::getNumberOfComponents() const } /*! - * Returns number of tuples in \a this field, that depends on + * Use MEDCouplingField::getNumberOfTuplesExpected instead of this method. This method will be removed soon, because it is + * confusing compared to getNumberOfComponents() and getNumberOfValues() behaviour. + * + * Returns number of tuples in \a this field, that depends on * - the number of entities in the underlying mesh * - \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field (e.g. number - * of Gauss points if \a this->getTypeOfField() == - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT"). + * of Gauss points if \a this->getTypeOfField() == + * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT"). * - * The returned value does **not depend** on the number of tuples in the data array + * The returned value does \b not \b depend on the number of tuples in the data array * (which has to be equal to the returned value), \b contrary to * getNumberOfComponents() and getNumberOfValues() that retrieve information from the - * data array. - * \warning No checkCoherency() is done here. - * For more info on the data arrays, see \ref MEDCouplingArrayPage. + * data array (Sorry, it is confusing !). + * So \b this \b method \b behaves \b exactly \b as MEDCouplingField::getNumberOfTuplesExpected \b method. + * + * \warning No checkConsistencyLight() is done here. + * For more info on the data arrays, see \ref arrays. * \return int - the number of tuples. * \throw If the mesh is not set. * \throw If the spatial discretization of \a this field is NULL. * \throw If the spatial discretization is not fully defined. + * \sa MEDCouplingField::getNumberOfTuplesExpected */ -int MEDCouplingFieldDouble::getNumberOfTuples() const +mcIdType MEDCouplingFieldDouble::getNumberOfTuples() const { if(!_mesh) throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getNumberOfTuples !"); return _type->getNumberOfTuples(_mesh); } /*! * Returns number of atomic double values in the data array of \a this field. - * For more info on the data arrays, see \ref MEDCouplingArrayPage. + * For more info on the data arrays, see \ref arrays. * \return int - (number of tuples) * (number of components) of the * data array. * \throw If the data array is not set. */ -int MEDCouplingFieldDouble::getNumberOfValues() const +mcIdType MEDCouplingFieldDouble::getNumberOfValues() const { if(getArray()==0) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !"); @@ -1875,7 +1531,7 @@ int MEDCouplingFieldDouble::getNumberOfValues() const void MEDCouplingFieldDouble::updateTime() const { MEDCouplingField::updateTime(); - updateTimeWith(*_time_discr); + updateTimeWith(*timeDiscr()); } std::size_t MEDCouplingFieldDouble::getHeapMemorySizeWithoutChildren() const @@ -1883,47 +1539,21 @@ std::size_t MEDCouplingFieldDouble::getHeapMemorySizeWithoutChildren() const return MEDCouplingField::getHeapMemorySizeWithoutChildren(); } -std::vector MEDCouplingFieldDouble::getDirectChildren() const +std::vector MEDCouplingFieldDouble::getDirectChildrenWithNull() const { - std::vector ret(MEDCouplingField::getDirectChildren()); - if(_time_discr) + std::vector ret(MEDCouplingField::getDirectChildrenWithNull()); + if(timeDiscr()) { - std::vector ret2(_time_discr->getDirectChildren()); + std::vector ret2(timeDiscr()->getDirectChildrenWithNull()); ret.insert(ret.end(),ret2.begin(),ret2.end()); } return ret; } -/*! - * Sets \ref NatureOfField. - * \param [in] nat - an item of enum ParaMEDMEM::NatureOfField. - */ -void MEDCouplingFieldDouble::setNature(NatureOfField nat) -{ - MEDCouplingField::setNature(nat); - if(_type) - _type->checkCompatibilityWithNature(nat); -} - -/*! - * This method synchronizes time information (time, iteration, order, time unit) regarding the information in \c this->_mesh. - * \throw If no mesh is set in this. Or if \a this is not compatible with time setting (typically NO_TIME) - */ -void MEDCouplingFieldDouble::synchronizeTimeWithMesh() -{ - if(!_mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::synchronizeTimeWithMesh : no mesh set in this !"); - int it=-1,ordr=-1; - double val=_mesh->getTime(it,ordr); - std::string timeUnit(_mesh->getTimeUnit()); - setTime(val,it,ordr); - setTimeUnit(timeUnit); -} - /*! * Returns a value of \a this field of type either - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" or - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE". + * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or + * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE". * \param [in] cellId - an id of cell of interest. * \param [in] nodeIdInCell - a node index within the cell. * \param [in] compoId - an index of component. @@ -1931,28 +1561,25 @@ void MEDCouplingFieldDouble::synchronizeTimeWithMesh() * \throw If the data array is not set. * \throw If the mesh is not set. * \throw If the spatial discretization of \a this field is NULL. - * \throw If \a this field if of type other than - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" or - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE". + * \throw If \a this field if of type other than + * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" or + * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE". */ -double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const +double MEDCouplingFieldDouble::getIJK(mcIdType cellId, int nodeIdInCell, int compoId) const { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getIJK !"); return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId); } /*! - * Sets the data array. + * Sets the data array. * \param [in] array - the data array holding values of \a this field. It's size * should correspond to the mesh and * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field * (see getNumberOfTuples()), but this size is not checked here. */ -void MEDCouplingFieldDouble::setArray(DataArrayDouble *array) -{ - _time_discr->setArray(array,this); -} +//void MEDCouplingFieldDouble::setArray(DataArrayDouble *array) /*! * Sets the data array holding values corresponding to an end of a time interval @@ -1962,10 +1589,7 @@ void MEDCouplingFieldDouble::setArray(DataArrayDouble *array) * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field * (see getNumberOfTuples()), but this size is not checked here. */ -void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array) -{ - _time_discr->setEndArray(array,this); -} +//void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array) /*! * Sets all data arrays needed to define the field values. @@ -1976,110 +1600,7 @@ void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array) * \throw If number of arrays in \a arrs does not correspond to type of * \ref MEDCouplingTemporalDisc "temporal discretization" of \a this field. */ -void MEDCouplingFieldDouble::setArrays(const std::vector& arrs) -{ - _time_discr->setArrays(arrs,this); -} - -void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - tinyInfo.clear(); - _time_discr->getTinySerializationStrInformation(tinyInfo); - tinyInfo.push_back(_name); - tinyInfo.push_back(_desc); - tinyInfo.push_back(getTimeUnit()); -} - -/*! - * This method retrieves some critical values to resize and prepare remote instance. - * The first two elements returned in tinyInfo correspond to the parameters to give in constructor. - * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny. - */ -void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationIntInformation !"); - tinyInfo.clear(); - tinyInfo.push_back((int)_type->getEnum()); - tinyInfo.push_back((int)_time_discr->getEnum()); - tinyInfo.push_back((int)_nature); - _time_discr->getTinySerializationIntInformation(tinyInfo); - std::vector tinyInfo2; - _type->getTinySerializationIntInformation(tinyInfo2); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.push_back((int)tinyInfo2.size()); -} - -/*! - * This method retrieves some critical values to resize and prepare remote instance. - * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny. - */ -void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationDbleInformation !"); - tinyInfo.clear(); - _time_discr->getTinySerializationDbleInformation(tinyInfo); - std::vector tinyInfo2; - _type->getTinySerializationDbleInformation(tinyInfo2); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.push_back((int)tinyInfo2.size());//very bad, lack of time to improve it -} - -/*! - * This method has to be called to the new instance filled by CORBA, MPI, File... - * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied. - * @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. - * @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. - * No decrRef must be applied to every instances in returned vector. - */ -void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector& tinyInfoI, DataArrayInt *&dataInt, std::vector& arrays) -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !"); - dataInt=0; - std::vector tinyInfoITmp(tinyInfoI); - int sz=tinyInfoITmp.back(); - tinyInfoITmp.pop_back(); - std::vector tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz); - std::vector tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end()); - _time_discr->resizeForUnserialization(tinyInfoI2,arrays); - std::vector tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end()); - _type->resizeForUnserialization(tinyInfoITmp3,dataInt); -} - -void MEDCouplingFieldDouble::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform finishUnserialization !"); - std::vector tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end()); - // - std::vector tmp(tinyInfoD); - int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it - tmp.pop_back(); - std::vector tmp1(tmp.begin(),tmp.end()-sz); - std::vector tmp2(tmp.end()-sz,tmp.end()); - // - _time_discr->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS); - _nature=(NatureOfField)tinyInfoI[2]; - _type->finishUnserialization(tmp2); - int nbOfElemS=(int)tinyInfoS.size(); - _name=tinyInfoS[nbOfElemS-3]; - _desc=tinyInfoS[nbOfElemS-2]; - setTimeUnit(tinyInfoS[nbOfElemS-1]); -} - -/*! - * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller. - * The values returned must be consulted only in readonly mode. - */ -void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector& arrays) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform serialize !"); - _time_discr->getArrays(arrays); - _type->getSerializationIntArray(dataInt); -} +//void MEDCouplingFieldDouble::setArrays(const std::vector& arrs) /*! * Tries to set an \a other mesh as the support of \a this field. An attempt fails, if @@ -2099,37 +1620,39 @@ void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector * \ref py_mcfielddouble_changeUnderlyingMesh "Here is a Python example". + * \endif */ void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps) { if(_mesh==0 || other==0) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !"); - DataArrayInt *cellCor=0,*nodeCor=0; + DataArrayIdType *cellCor=0,*nodeCor=0; other->checkGeoEquivalWith(_mesh,levOfCheck,precOnMesh,cellCor,nodeCor); - MEDCouplingAutoRefCountObjectPtr cellCor2(cellCor),nodeCor2(nodeCor); + MCAuto cellCor2(cellCor),nodeCor2(nodeCor); if(cellCor) renumberCellsWithoutMesh(cellCor->getConstPointer(),false); if(nodeCor) renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps); - setMesh(const_cast(other)); + setMesh(other); } /*! * Subtracts another field from \a this one in case when the two fields have different * supporting meshes. The subtraction is performed provided that the tho meshes can be * considered equal with use of specified equality criteria, else an exception is thrown. - * If the meshes match, the mesh of \a f is set to \a this field (\a this is permuted if + * If the meshes match, the mesh of \a f is set to \a this field (\a this is permuted if * necessary) and field values are subtracted. No interpolation is done here, only an * analysis of two underlying mesh is done to see if the meshes are geometrically * equivalent.
* The job of this method consists in calling * \a this->changeUnderlyingMesh() with \a f->getMesh() as the first parameter, and then * \a this -= \a f.
- * This method requires that \a f and \a this are coherent (checkCoherency()) and that \a f + * This method requires that \a f and \a this are coherent (checkConsistencyLight()) and that \a f * and \a this are coherent for a merge.
* "DM" in the method name stands for "different meshes". * \param [in] f - the field to subtract from this. @@ -2145,18 +1668,20 @@ void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, * \throw If any of the meshes is not set or is not well defined. * \throw If the two meshes do not match. * \throw If the two fields are not coherent for merge. - * \throw If field values at merged nodes (if any) deffer more than \a eps. + * \throw If field values at merged nodes (if any) differ more than \a eps. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".
* \ref py_mcfielddouble_substractInPlaceDM "Here is a Python example". + * \endif * \sa changeUnderlyingMesh(). */ void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps) { - checkCoherency(); + checkConsistencyLight(); if(!f) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : input field is NULL !"); - f->checkCoherency(); + f->checkConsistencyLight(); if(!areCompatibleForMerge(f)) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : Fields are not compatible ; unable to apply mergeFields on them !"); changeUnderlyingMesh(f->getMesh(),levOfCheck,precOnMesh,eps); @@ -2176,23 +1701,23 @@ void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, * \throw If the mesh is not well defined. * \throw If the spatial discretization of \a this field is NULL. * \throw If the data array is not set. - * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals. + * \throw If field values at merged nodes (if any) differ more than \a epsOnVals. */ bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals) { const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); if(!meshC) throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes !"); - MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); + MCAuto meshC2((MEDCouplingPointSet *)meshC->deepCopy()); bool ret; - int ret2; - MEDCouplingAutoRefCountObjectPtr arr=meshC2->mergeNodes(eps,ret,ret2); + mcIdType ret2; + MCAuto arr=meshC2->mergeNodes(eps,ret,ret2); if(!ret)//no nodes have been merged. return ret; std::vector arrays; - _time_discr->getArrays(arrays); + timeDiscr()->getArrays(arrays); for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) if(*iter) _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter); @@ -2215,23 +1740,23 @@ bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals) * \throw If the mesh is not well defined. * \throw If the spatial discretization of \a this field is NULL. * \throw If the data array is not set. - * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals. + * \throw If field values at merged nodes (if any) differ more than \a epsOnVals. */ -bool MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals) +bool MEDCouplingFieldDouble::mergeNodesCenter(double eps, double epsOnVals) { const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); if(!meshC) throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes2 !"); - MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); + if(_type.isNull()) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodesCenter !"); + MCAuto meshC2((MEDCouplingPointSet *)meshC->deepCopy()); bool ret; - int ret2; - MEDCouplingAutoRefCountObjectPtr arr=meshC2->mergeNodes2(eps,ret,ret2); + mcIdType ret2; + MCAuto arr=meshC2->mergeNodesCenter(eps,ret,ret2); if(!ret)//no nodes have been merged. return ret; std::vector arrays; - _time_discr->getArrays(arrays); + timeDiscr()->getArrays(arrays); for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) if(*iter) _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter); @@ -2252,22 +1777,22 @@ bool MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals) * \throw If the mesh is not well defined. * \throw If the spatial discretization of \a this field is NULL. * \throw If the data array is not set. - * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals. + * \throw If field values at merged nodes (if any) differ more than \a epsOnVals. */ bool MEDCouplingFieldDouble::zipCoords(double epsOnVals) { const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); if(!meshC) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipCoords !"); - MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); - int oldNbOfNodes=meshC2->getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr arr=meshC2->zipCoordsTraducer(); + MCAuto meshC2((MEDCouplingPointSet *)meshC->deepCopy()); + mcIdType oldNbOfNodes=meshC2->getNumberOfNodes(); + MCAuto arr=meshC2->zipCoordsTraducer(); if(meshC2->getNumberOfNodes()!=oldNbOfNodes) { std::vector arrays; - _time_discr->getArrays(arrays); + timeDiscr()->getArrays(arrays); for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) if(*iter) _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter); @@ -2293,25 +1818,25 @@ bool MEDCouplingFieldDouble::zipCoords(double epsOnVals) * \throw If the mesh is not well defined. * \throw If the spatial discretization of \a this field is NULL. * \throw If the data array is not set. - * \throw If field values at merged cells (if any) deffer more than \a epsOnVals. + * \throw If field values at merged cells (if any) differ more than \a epsOnVals. */ bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals) { const MEDCouplingUMesh *meshC=dynamic_cast(_mesh); if(!meshC) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipConnectivity : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipConnectivity !"); - MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingUMesh *)meshC->deepCpy()); - int oldNbOfCells=meshC2->getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr arr=meshC2->zipConnectivityTraducer(compType); + MCAuto meshC2((MEDCouplingUMesh *)meshC->deepCopy()); + mcIdType oldNbOfCells(meshC2->getNumberOfCells()); + MCAuto arr=meshC2->zipConnectivityTraducer(compType); if(meshC2->getNumberOfCells()!=oldNbOfCells) { std::vector arrays; - _time_discr->getArrays(arrays); + timeDiscr()->getArrays(arrays); for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) if(*iter) - _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter); + _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),ToIdType(meshC2->getNumberOfCells()),*iter); setMesh(meshC2); return true; } @@ -2321,7 +1846,7 @@ bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals) /*! * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists. * For the moment, this method is implemented for fields on cells. - * + * * \return a newly allocated field double containing the result that the user should deallocate. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const @@ -2331,19 +1856,19 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *ori throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !"); if(getTypeOfField()!=ON_CELLS) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !"); - const MEDCouplingAutoRefCountObjectPtr umesh(mesh->buildUnstructured()); - MEDCouplingAutoRefCountObjectPtr ret=clone(false); + const MCAuto umesh(mesh->buildUnstructured()); + MCAuto ret(clone(false)); ret->setMesh(umesh); - DataArrayInt *cellIds=0; - MEDCouplingAutoRefCountObjectPtr mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds); - MEDCouplingAutoRefCountObjectPtr cellIds2=cellIds; + DataArrayIdType *cellIds=0; + MCAuto mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds); + MCAuto cellIds2=cellIds; ret->setMesh(mesh2); - MEDCouplingAutoRefCountObjectPtr tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end()); + MCAuto tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end()); std::vector arrays; - _time_discr->getArrays(arrays); + timeDiscr()->getArrays(arrays); int i=0; std::vector newArr(arrays.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > newArr2(arrays.size()); + std::vector< MCAuto > newArr2(arrays.size()); for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++) { if(*iter) @@ -2359,12 +1884,12 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *ori /*! * Divides every cell of the underlying mesh into simplices (triangles in 2D and * tetrahedra in 3D). If some cells are divided, the underlying mesh is replaced by a new - * mesh instance containing the simplices.
+ * mesh instance containing the simplices.
* \param [in] policy - specifies a pattern used for splitting. For its description, see * MEDCouplingUMesh::simplexize(). * \return bool - \c true if some cells have been divided and hence \a this field lies * on another mesh. - * \throw If \a policy has an invalid value. For valid values, see the description of + * \throw If \a policy has an invalid value. For valid values, see the description of * MEDCouplingUMesh::simplexize(). * \throw If MEDCouplingMesh::simplexize() is not applicable to the underlying mesh. * \throw If the mesh is not well defined. @@ -2375,29 +1900,179 @@ bool MEDCouplingFieldDouble::simplexize(int policy) { if(!_mesh) throw INTERP_KERNEL::Exception("No underlying mesh on this field to perform simplexize !"); - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform simplexize !"); - int oldNbOfCells=_mesh->getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr meshC2(_mesh->deepCpy()); - MEDCouplingAutoRefCountObjectPtr arr=meshC2->simplexize(policy); - int newNbOfCells=meshC2->getNumberOfCells(); + std::size_t oldNbOfCells=_mesh->getNumberOfCells(); + MCAuto meshC2(_mesh->deepCopy()); + MCAuto arr=meshC2->simplexize(policy); + std::size_t newNbOfCells=meshC2->getNumberOfCells(); if(oldNbOfCells==newNbOfCells) return false; std::vector arrays; - _time_discr->getArrays(arrays); + timeDiscr()->getArrays(arrays); for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) if(*iter) - _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter); + _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),ToIdType(arr->getNbOfElems()),*iter); setMesh(meshC2); return true; } +/*! + * This method makes the hypothesis that \a this is a Gauss field. This method returns a newly created field on cells with same number of tuples than \a this. + * Each Gauss points in \a this is replaced by a polygon or polyhedron cell with associated region following Voronoi algorithm. + */ +MCAuto MEDCouplingFieldDouble::voronoize(double eps) const +{ + checkConsistencyLight(); + const MEDCouplingMesh *mesh(getMesh()); + INTERP_KERNEL::AutoCppPtr vor; + std::size_t meshDim(mesh->getMeshDimension()),spaceDim(mesh->getSpaceDimension()); + if(meshDim==1 && (spaceDim==1 || spaceDim==2 || spaceDim==3)) + vor=new Voronizer1D; + else if(meshDim==2 && (spaceDim==2 || spaceDim==3)) + vor=new Voronizer2D; + else if(meshDim==3 && spaceDim==3) + vor=new Voronizer3D; + else + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize : only 2D, 3D surf, and 3D are supported for the moment !"); + return voronoizeGen(vor,eps); +} + +/*! + * \sa MEDCouplingUMesh::convertQuadraticCellsToLinear + */ +MCAuto MEDCouplingFieldDouble::convertQuadraticCellsToLinear() const +{ + checkConsistencyLight(); + switch(getTypeOfField()) + { + case ON_NODES: + { + const MEDCouplingMesh *mesh(getMesh()); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !"); + MCAuto umesh(mesh->buildUnstructured()); + umesh=umesh->clone(false); + umesh->convertQuadraticCellsToLinear(); + MCAuto o2n(umesh->zipCoordsTraducer()); + MCAuto n2o(o2n->invertArrayO2N2N2O(umesh->getNumberOfNodes())); + MCAuto arr(getArray()->selectByTupleIdSafe(n2o->begin(),n2o->end())); + MCAuto ret(MEDCouplingFieldDouble::New(ON_NODES)); + ret->setArray(arr); + ret->setMesh(umesh); + ret->copyAllTinyAttrFrom(this); + return ret; + } + case ON_CELLS: + { + const MEDCouplingMesh *mesh(getMesh()); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !"); + MCAuto umesh(mesh->buildUnstructured()); + umesh=umesh->clone(false); + umesh->convertQuadraticCellsToLinear(); + umesh->zipCoords(); + MCAuto ret(MEDCouplingFieldDouble::New(ON_CELLS)); + ret->setArray(const_cast(getArray())); + ret->setMesh(umesh); + ret->copyAllTinyAttrFrom(this); + return ret; + } + case ON_GAUSS_PT: + { + const MEDCouplingMesh *mesh(getMesh()); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : null mesh !"); + MCAuto umesh(mesh->buildUnstructured()); + std::set gt(umesh->getAllGeoTypes()); + MCAuto ret(MEDCouplingFieldDouble::New(ON_GAUSS_PT)); + // + const MEDCouplingFieldDiscretization *disc(getDiscretization()); + const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast(disc)); + if(!disc2) + throw INTERP_KERNEL::Exception("convertQuadraticCellsToLinear : Not a ON_GAUSS_PT field"); + std::set gt2(umesh->getAllGeoTypes()); + std::vector< MCAuto > cellIdsV; + std::vector< MCAuto > meshesV; + std::vector< MEDCouplingGaussLocalization > glV; + bool isZipReq(false); + for(std::set::const_iterator it=gt.begin();it!=gt.end();it++) + { + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it)); + MCAuto cellIds(umesh->giveCellsWithType(*it)); + cellIdsV.push_back(cellIds); + MCAuto part(umesh->buildPartOfMySelf(cellIds->begin(),cellIds->end())); + mcIdType id(disc2->getGaussLocalizationIdOfOneType(*it)); + const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(id)); + if(!cm.isQuadratic()) + { + glV.push_back(gl); + } + else + { + isZipReq=true; + part->convertQuadraticCellsToLinear(); + INTERP_KERNEL::GaussInfo gi(*it,gl.getGaussCoords(),gl.getNumberOfGaussPt(),gl.getRefCoords(),gl.getNumberOfPtsInRefCell()); + INTERP_KERNEL::GaussInfo gi2(gi.convertToLinear()); + MEDCouplingGaussLocalization gl2(gi2.getGeoType(),gi2.getRefCoords(),gi2.getGaussCoords(),gl.getWeights()); + glV.push_back(gl2); + } + meshesV.push_back(part); + } + // + { + std::vector< const MEDCouplingUMesh * > meshesPtr(VecAutoToVecOfCstPt(meshesV)); + umesh=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshesPtr); + std::vector< const DataArrayIdType * > zeCellIds(VecAutoToVecOfCstPt(cellIdsV)); + MCAuto zeIds(DataArrayIdType::Aggregate(zeCellIds)); + umesh->renumberCells(zeIds->begin()); + umesh->setName(mesh->getName()); + } + // + if(isZipReq) + umesh->zipCoords(); + ret->setArray(const_cast(getArray())); + ret->setMesh(umesh); + for(std::vector< MEDCouplingGaussLocalization >::const_iterator it=glV.begin();it!=glV.end();it++) + ret->setGaussLocalizationOnType((*it).getType(),(*it).getRefCoords(),(*it).getGaussCoords(),(*it).getWeights()); + ret->copyAllTinyAttrFrom(this); + ret->checkConsistencyLight(); + return ret; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::convertQuadraticCellsToLinear : Only available for fields on nodes and on cells !"); + } +} + +/*! + * This is expected to be a 3 components vector field on nodes (if not an exception will be thrown). \a this is also expected to lie on a MEDCouplingPointSet mesh. + * Finally \a this is also expected to be consistent. + * In these conditions this method returns a newly created field (to be dealed by the caller). + * The returned field will also 3 compo vector field be on nodes lying on the same mesh than \a this. + * + * For each 3 compo tuple \a tup in \a this the returned tuple is the result of the transformation of \a tup in the new referential. This referential is defined by \a Ur, \a Uteta, \a Uz. + * \a Ur is the vector between \a center point and the associated node with \a tuple. \a Uz is \a vect normalized. And Uteta is the cross product of \a Uz with \a Ur. + * + * \sa DataArrayDouble::fromCartToCylGiven + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::computeVectorFieldCyl(const double center[3], const double vect[3]) const +{ + checkConsistencyLight(); + const DataArrayDouble *coo(getMesh()->getDirectAccessOfCoordsArrIfInStructure()); + MEDCouplingTimeDiscretization *td(timeDiscr()->computeVectorFieldCyl(coo,center,vect)); + td->copyTinyAttrFrom(*timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone())); + ret->setMesh(getMesh()); + ret->setName(getName()); + return ret.retn(); +} + /*! * Creates a new MEDCouplingFieldDouble filled with the doubly contracted product of * every tensor of \a this 6-componental field. * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose * each tuple is calculated from the tuple (t) of \a this field as - * follows: \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$. + * follows: \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$. * This new field lies on the same mesh as \a this one. The caller is to delete * this field using decrRef() as it is no more needed. * \throw If \a this->getNumberOfComponents() != 6. @@ -2405,11 +2080,11 @@ bool MEDCouplingFieldDouble::simplexize(int policy) */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform doublyContractedProduct !"); - MEDCouplingTimeDiscretization *td=_time_discr->doublyContractedProduct(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingTimeDiscretization *td(timeDiscr()->doublyContractedProduct()); + td->copyTinyAttrFrom(*timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone())); ret->setName("DoublyContractedProduct"); ret->setMesh(getMesh()); return ret.retn(); @@ -2418,21 +2093,21 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const /*! * Creates a new MEDCouplingFieldDouble filled with the determinant of a square * matrix defined by every tuple of \a this field, having either 4, 6 or 9 components. - * The case of 6 components corresponds to that of the upper triangular matrix. + * The case of 6 components corresponds to that of the upper triangular matrix. * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose - * each tuple is the determinant of matrix of the corresponding tuple of \a this - * field. This new field lies on the same mesh as \a this one. The caller is to + * each tuple is the determinant of matrix of the corresponding tuple of \a this + * field. This new field lies on the same mesh as \a this one. The caller is to * delete this field using decrRef() as it is no more needed. * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. * \throw If the spatial discretization of \a this field is NULL. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform determinant !"); - MEDCouplingTimeDiscretization *td=_time_discr->determinant(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingTimeDiscretization *td(timeDiscr()->determinant()); + td->copyTinyAttrFrom(*timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone())); ret->setName("Determinant"); ret->setMesh(getMesh()); return ret.retn(); @@ -2442,21 +2117,21 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const /*! * Creates a new MEDCouplingFieldDouble with 3 components filled with 3 eigenvalues of * an upper triangular matrix defined by every tuple of \a this 6-componental field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, * having 3 components, whose each tuple contains the eigenvalues of the matrix of * corresponding tuple of \a this field. This new field lies on the same mesh as * \a this one. The caller is to delete this field using decrRef() as it is no - * more needed. + * more needed. * \throw If \a this->getNumberOfComponents() != 6. * \throw If the spatial discretization of \a this field is NULL. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenValues !"); - MEDCouplingTimeDiscretization *td=_time_discr->eigenValues(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingTimeDiscretization *td(timeDiscr()->eigenValues()); + td->copyTinyAttrFrom(*timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone())); ret->setName("EigenValues"); ret->setMesh(getMesh()); return ret.retn(); @@ -2465,21 +2140,21 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const /*! * Creates a new MEDCouplingFieldDouble with 9 components filled with 3 eigenvectors of * an upper triangular matrix defined by every tuple of \a this 6-componental field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, * having 9 components, whose each tuple contains the eigenvectors of the matrix of * corresponding tuple of \a this field. This new field lies on the same mesh as * \a this one. The caller is to delete this field using decrRef() as it is no - * more needed. + * more needed. * \throw If \a this->getNumberOfComponents() != 6. * \throw If the spatial discretization of \a this field is NULL. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenVectors !"); - MEDCouplingTimeDiscretization *td=_time_discr->eigenVectors(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingTimeDiscretization *td(timeDiscr()->eigenVectors()); + td->copyTinyAttrFrom(*timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone())); ret->setName("EigenVectors"); ret->setMesh(getMesh()); return ret.retn(); @@ -2490,21 +2165,21 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const * a matrix defined by every tuple of \a this field having either 4, 6 or 9 * components. The case of 6 components corresponds to that of the upper triangular * matrix. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, * having the same number of components as \a this one, whose each tuple * contains the inverse matrix of the matrix of corresponding tuple of \a this * field. This new field lies on the same mesh as \a this one. The caller is to - * delete this field using decrRef() as it is no more needed. + * delete this field using decrRef() as it is no more needed. * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. * \throw If the spatial discretization of \a this field is NULL. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform inverse !"); - MEDCouplingTimeDiscretization *td=_time_discr->inverse(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingTimeDiscretization *td(timeDiscr()->inverse()); + td->copyTinyAttrFrom(*timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone())); ret->setName("Inversion"); ret->setMesh(getMesh()); return ret.retn(); @@ -2515,21 +2190,21 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const * a matrix defined by every tuple of \a this field having either 4, 6 or 9 * components. The case of 6 components corresponds to that of the upper triangular * matrix. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, * having 1 component, whose each tuple is the trace of the matrix of * corresponding tuple of \a this field. * This new field lies on the same mesh as \a this one. The caller is to - * delete this field using decrRef() as it is no more needed. + * delete this field using decrRef() as it is no more needed. * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. * \throw If the spatial discretization of \a this field is NULL. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform trace !"); - MEDCouplingTimeDiscretization *td=_time_discr->trace(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingTimeDiscretization *td(timeDiscr()->trace()); + td->copyTinyAttrFrom(*timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone())); ret->setName("Trace"); ret->setMesh(getMesh()); return ret.retn(); @@ -2538,22 +2213,22 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const /*! * Creates a new MEDCouplingFieldDouble filled with the stress deviator tensor of * a stress tensor defined by every tuple of \a this 6-componental field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, * having same number of components and tuples as \a this field, * whose each tuple contains the stress deviator tensor of the stress tensor of * corresponding tuple of \a this field. This new field lies on the same mesh as * \a this one. The caller is to delete this field using decrRef() as it is no - * more needed. + * more needed. * \throw If \a this->getNumberOfComponents() != 6. * \throw If the spatial discretization of \a this field is NULL. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform deviator !"); - MEDCouplingTimeDiscretization *td=_time_discr->deviator(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingTimeDiscretization *td(timeDiscr()->deviator()); + td->copyTinyAttrFrom(*timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone())); ret->setName("Deviator"); ret->setMesh(getMesh()); return ret.retn(); @@ -2562,20 +2237,20 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const /*! * Creates a new MEDCouplingFieldDouble filled with the magnitude of * every vector of \a this field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, * having one component, whose each tuple is the magnitude of the vector * of corresponding tuple of \a this field. This new field lies on the * same mesh as \a this one. The caller is to - * delete this field using decrRef() as it is no more needed. + * delete this field using decrRef() as it is no more needed. * \throw If the spatial discretization of \a this field is NULL. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform magnitude !"); - MEDCouplingTimeDiscretization *td=_time_discr->magnitude(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingTimeDiscretization *td(timeDiscr()->magnitude()); + td->copyTinyAttrFrom(*timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone())); ret->setName("Magnitude"); ret->setMesh(getMesh()); return ret.retn(); @@ -2586,16 +2261,16 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const * values of every tuple of \a this field. * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. * This new field lies on the same mesh as \a this one. The caller is to - * delete this field using decrRef() as it is no more needed. + * delete this field using decrRef() as it is no more needed. * \throw If the spatial discretization of \a this field is NULL. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform maxPerTuple !"); - MEDCouplingTimeDiscretization *td=_time_discr->maxPerTuple(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingTimeDiscretization *td(timeDiscr()->maxPerTuple()); + td->copyTinyAttrFrom(*timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone())); std::ostringstream oss; oss << "Max_" << getName(); ret->setName(oss.str()); @@ -2607,15 +2282,15 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const * Changes number of components in \a this field. If \a newNbOfComp is less * than \a this->getNumberOfComponents() then each tuple * is truncated to have \a newNbOfComp components, keeping first components. If \a - * newNbOfComp is more than \a this->getNumberOfComponents() then - * each tuple is populated with \a dftValue to have \a newNbOfComp components. + * newNbOfComp is more than \a this->getNumberOfComponents() then + * each tuple is populated with \a dftValue to have \a newNbOfComp components. * \param [in] newNbOfComp - number of components for the new field to have. * \param [in] dftValue - value assigned to new values added to \a this field. * \throw If \a this is not allocated. */ -void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue) +void MEDCouplingFieldDouble::changeNbOfComponents(std::size_t newNbOfComp, double dftValue) { - _time_discr->changeNbOfComponents(newNbOfComp,dftValue); + timeDiscr()->changeNbOfComponents(newNbOfComp,dftValue); } /*! @@ -2627,22 +2302,21 @@ void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftVal * into the new field. * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble that the caller * is to delete using decrRef() as it is no more needed. - * \throw If a component index (\a i) is not valid: + * \throw If a component index (\a i) is not valid: * \a i < 0 || \a i >= \a this->getNumberOfComponents(). */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector& compoIds) const +MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector& compoIds) const { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform keepSelectedComponents !"); - MEDCouplingTimeDiscretization *td=_time_discr->keepSelectedComponents(compoIds); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingTimeDiscretization *td(timeDiscr()->keepSelectedComponents(compoIds)); + td->copyTinyAttrFrom(*timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone())); ret->setName(getName()); ret->setMesh(getMesh()); return ret.retn(); } - /*! * Copy all components in a specified order from another field. * The number of tuples in \a this and the other field can be different. @@ -2654,9 +2328,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std * \throw If \a compoIds.size() != \a a->getNumberOfComponents(). * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). */ -void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector& compoIds) +void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector& compoIds) { - _time_discr->setSelectedComponents(f->_time_discr,compoIds); + timeDiscr()->setSelectedComponents(f->timeDiscr(),compoIds); } /*! @@ -2667,7 +2341,7 @@ void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble */ void MEDCouplingFieldDouble::sortPerTuple(bool asc) { - _time_discr->sortPerTuple(asc); + timeDiscr()->sortPerTuple(asc); } /*! @@ -2677,84 +2351,80 @@ void MEDCouplingFieldDouble::sortPerTuple(bool asc) * \param [in] f1 - the first field. * \param [in] f2 - the second field. * \return MEDCouplingFieldDouble * - the result field. It is a new instance of - * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() + * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() * as it is no more needed. * \throw If the fields are not compatible for the merge. * \throw If the spatial discretization of \a f1 is NULL. * \throw If the time discretization of \a f1 is NULL. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".
* \ref py_mcfielddouble_MergeFields "Here is a Python example". + * \endif */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) { - if(!f1->areCompatibleForMerge(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !"); - const MEDCouplingMesh *m1(f1->getMesh()),*m2(f2->getMesh()); - if(!f1->_time_discr) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no time discr of f1 !"); - if(!f1->_type) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no spatial discr of f1 !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); - ret->setName(f1->getName()); - ret->setDescription(f1->getDescription()); - if(m1) - { - MEDCouplingAutoRefCountObjectPtr m=m1->mergeMyselfWith(m2); - ret->setMesh(m); - } - return ret.retn(); + std::vector a(2); + a[0]=f1; a[1]=f2; + return MergeFields(a); } /*! * Creates a new MEDCouplingFieldDouble by concatenating all given fields. * Values of the *i*-th field precede values of the (*i*+1)-th field within the result. * If there is only one field in \a a, a deepCopy() (except time information of mesh and - * field) of the field is returned. + * field) of the field is returned. * Generally speaking the first field in \a a is used to assign tiny attributes of the - * returned field. + * returned field. * \param [in] a - a vector of fields (MEDCouplingFieldDouble) to concatenate. * \return MEDCouplingFieldDouble * - the result field. It is a new instance of - * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() + * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() * as it is no more needed. * \throw If \a a is empty. * \throw If the fields are not compatible for the merge. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".
* \ref py_mcfielddouble_MergeFields "Here is a Python example". + * \endif */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector& a) { - if(a.size()<1) - throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > ms(a.size()); + if(a.empty()) + throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : input array is empty !"); + std::vector< MCAuto > ms(a.size()); std::vector< const MEDCouplingUMesh *> ms2(a.size()); std::vector< const MEDCouplingTimeDiscretization *> tds(a.size()); - std::vector::const_iterator it=a.begin(); - const MEDCouplingFieldDouble *ref=(*it++); + std::vector< const MEDCouplingFieldDouble *>::const_iterator it=a.begin(); + std::vector fds(a.size()); + const MEDCouplingFieldDouble *ref((*it++)); if(!ref) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of NULL instance in first place of input vector !"); + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of nullptr instance in first place of input vector !"); + if(!ref->getDiscretization()) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : nullptr spatial discretization !"); for(;it!=a.end();it++) if(!ref->areCompatibleForMerge(*it)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !"); - for(int i=0;i<(int)a.size();i++) + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them! Check support mesh, field nature, and spatial and time discretisation."); + for(std::size_t i=0;igetMesh()) { ms[i]=a[i]->getMesh()->buildUnstructured(); ms2[i]=ms[i]; } else { ms[i]=0; ms2[i]=0; } - tds[i]=a[i]->_time_discr; + tds[i]=a[i]->timeDiscr(); + fds[i]=a[i]->getDiscretization(); } - MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds); - td->copyTinyAttrFrom(*(a[0]->_time_discr)); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()); + MEDCouplingTimeDiscretization *td(tds[0]->aggregate(tds)); + MCAuto fda(fds[0]->aggregate(fds)); + td->copyTinyAttrFrom(*(a[0]->timeDiscr())); + MCAuto ret(new MEDCouplingFieldDouble(a[0]->getNature(),td,fda.retn())); ret->setName(a[0]->getName()); ret->setDescription(a[0]->getDescription()); if(ms2[0]) { - MEDCouplingAutoRefCountObjectPtr m=MEDCouplingUMesh::MergeUMeshes(ms2); + MCAuto m(MEDCouplingUMesh::MergeUMeshes(ms2)); m->copyTinyInfoFrom(ms2[0]); ret->setMesh(m); } @@ -2778,19 +2448,21 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vectorareCompatibleForMeld(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MeldFields on them !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->meld(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td(f1->timeDiscr()->meld(f2->timeDiscr())); + td->copyTinyAttrFrom(*f1->timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone())); ret->setMesh(f1->getMesh()); return ret.retn(); } /*! - * Returns a new MEDCouplingFieldDouble containing a dot product of two given fields, + * Returns a new MEDCouplingFieldDouble containing a dot product of two given fields, * so that the i-th tuple of the result field is a sum of products of j-th components of - * i-th tuples of given fields (\f$ f_i = \sum_{j=1}^n f1_j * f2_j \f$). + * i-th tuples of given fields (\f$ f_i = \sum_{j=1}^n f1_j * f2_j \f$). * Number of tuples and components in the given fields must be the same. * \param [in] f1 - a given field. * \param [in] f2 - another given field. @@ -2805,17 +2477,17 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingField { if(!f1) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !"); - if(!f1->areStrictlyCompatible(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DotFields on them !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + if(!f1->areStrictlyCompatibleForMulDiv(f2)) + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them! Check support mesh, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td(f1->timeDiscr()->dot(f2->timeDiscr())); + td->copyTinyAttrFrom(*f1->timeDiscr()); + MEDCouplingFieldDouble *ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone())); ret->setMesh(f1->getMesh()); return ret; } /*! - * Returns a new MEDCouplingFieldDouble containing a cross product of two given fields, + * Returns a new MEDCouplingFieldDouble containing a cross product of two given fields, * so that * the i-th tuple of the result field is a 3D vector which is a cross * product of two vectors defined by the i-th tuples of given fields. @@ -2836,11 +2508,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCoup { if(!f1) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !"); - if(!f1->areStrictlyCompatible(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply CrossProductFields on them !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + if(!f1->areStrictlyCompatibleForMulDiv(f2)) + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td(f1->timeDiscr()->crossProduct(f2->timeDiscr())); + td->copyTinyAttrFrom(*f1->timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone())); ret->setMesh(f1->getMesh()); return ret.retn(); } @@ -2857,18 +2529,20 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCoup * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they * differ not only in values. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".
* \ref py_mcfielddouble_MaxFields "Here is a Python example". + * \endif */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) { if(!f1) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MaxFields : input field is NULL !"); if(!f1->areStrictlyCompatible(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MaxFields on them !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->max(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MaxFields on them! Check support mesh, field nature, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td(f1->timeDiscr()->max(f2->timeDiscr())); + td->copyTinyAttrFrom(*f1->timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone())); ret->setMesh(f1->getMesh()); return ret.retn(); } @@ -2885,18 +2559,20 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingField * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they * differ not only in values. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".
* \ref py_mcfielddouble_MaxFields "Here is a Python example". + * \endif */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) { if(!f1) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MinFields : input field is NULL !"); if(!f1->areStrictlyCompatible(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MinFields on them !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->min(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MinFields on them! Check support mesh, field nature, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td(f1->timeDiscr()->min(f2->timeDiscr())); + td->copyTinyAttrFrom(*f1->timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone())); ret->setMesh(f1->getMesh()); return ret.retn(); } @@ -2904,19 +2580,19 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingField /*! * Returns a copy of \a this field in which sign of all values is reversed. * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble - * containing the same number of tuples and components as \a this field. + * containing the same number of tuples and components as \a this field. * The caller is to delete this result field using decrRef() as it is no more - * needed. + * needed. * \throw If the spatial discretization of \a this field is NULL. * \throw If a data array is not allocated. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::negate() const { - if(!((const MEDCouplingFieldDiscretization *)_type)) + if(_type.isNull()) throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform negate !"); - MEDCouplingTimeDiscretization *td=_time_discr->negate(); - td->copyTinyAttrFrom(*_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingTimeDiscretization *td(timeDiscr()->negate()); + td->copyTinyAttrFrom(*timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(getNature(),td,_type->clone())); ret->setMesh(getMesh()); return ret.retn(); } @@ -2939,10 +2615,10 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingField if(!f1) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::AddFields : input field is NULL !"); if(!f1->areStrictlyCompatible(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply AddFields on them !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply AddFields on them! Check support mesh, field nature, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td(f1->timeDiscr()->add(f2->timeDiscr())); + td->copyTinyAttrFrom(*f1->timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone())); ret->setMesh(f1->getMesh()); return ret.retn(); } @@ -2957,11 +2633,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingField * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they * differ not only in values. */ -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) { if(!areStrictlyCompatible(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply += on them !"); - _time_discr->addEqual(other._time_discr); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply += on them! Check support mesh, field nature, and spatial and time discretisation."); + timeDiscr()->addEqual(other.timeDiscr()); return *this; } @@ -2983,10 +2659,10 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplin if(!f1) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::SubstractFields : input field is NULL !"); if(!f1->areStrictlyCompatible(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply SubstractFields on them !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply SubstractFields on them! Check support mesh, field nature, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td(f1->timeDiscr()->substract(f2->timeDiscr())); + td->copyTinyAttrFrom(*f1->timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone())); ret->setMesh(f1->getMesh()); return ret.retn(); } @@ -3001,11 +2677,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplin * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they * differ not only in values. */ -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) { if(!areStrictlyCompatible(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply -= on them !"); - _time_discr->substractEqual(other._time_discr); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply -= on them! Check support mesh, field nature, and spatial and time discretisation."); + timeDiscr()->substractEqual(other.timeDiscr()); return *this; } @@ -3022,11 +2698,11 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCoupli * The two fields must have same number of tuples and same underlying mesh. * \param [in] f1 - a factor field. * \param [in] f2 - another factor field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set. * The caller is to delete this result field using decrRef() as it is no more * needed. * \throw If either \a f1 or \a f2 is NULL. - * \throw If the fields are not compatible for production (areCompatibleForMul()), + * \throw If the fields are not compatible for multiplication (areCompatibleForMul()), * i.e. they differ not only in values and possibly number of components. */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) @@ -3034,10 +2710,10 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCoupling if(!f1) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MultiplyFields : input field is NULL !"); if(!f1->areCompatibleForMul(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MultiplyFields on them !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MultiplyFields on them! Check support mesh, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td(f1->timeDiscr()->multiply(f2->timeDiscr())); + td->copyTinyAttrFrom(*f1->timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone())); ret->setMesh(f1->getMesh()); return ret.retn(); } @@ -3055,19 +2731,20 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCoupling * * The two fields must have same number of tuples and same underlying mesh. * \param [in] other - an field to multiply to \a this one. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set. * The caller is to delete this result field using decrRef() as it is no more * needed. * \throw If \a other is NULL. - * \throw If the fields are not strictly compatible for production + * \throw If the fields are not strictly compatible for multiplication * (areCompatibleForMul()), * i.e. they differ not only in values and possibly in number of components. */ -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) { if(!areCompatibleForMul(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply *= on them !"); - _time_discr->multiplyEqual(other._time_discr); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply *= on them! Check support mesh, and spatial and time discretisation."); + timeDiscr()->multiplyEqual(other.timeDiscr()); + _nature = NoNature; return *this; } @@ -3082,7 +2759,7 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCoupli * * \param [in] f1 - a numerator field. * \param [in] f2 - a denominator field. - * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set. * The caller is to delete this result field using decrRef() as it is no more * needed. * \throw If either \a f1 or \a f2 is NULL. @@ -3094,10 +2771,10 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFi if(!f1) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DivideFields : input field is NULL !"); if(!f1->areCompatibleForDiv(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DivideFields on them !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DivideFields on them! Check support mesh, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td(f1->timeDiscr()->divide(f2->timeDiscr())); + td->copyTinyAttrFrom(*f1->timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone())); ret->setMesh(f1->getMesh()); return ret.retn(); } @@ -3119,17 +2796,18 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFi * \throw If the fields are not compatible for division (areCompatibleForDiv()), * i.e. they differ not only in values and possibly in number of components. */ -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) { if(!areCompatibleForDiv(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !"); - _time_discr->divideEqual(other._time_discr); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply /= on them! Check support mesh, and spatial and time discretisation."); + timeDiscr()->divideEqual(other.timeDiscr()); + _nature = NoNature; return *this; } /*! * Directly called by MEDCouplingFieldDouble::operator^. - * + * * \sa MEDCouplingFieldDouble::operator^ */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) @@ -3137,29 +2815,30 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingField if(!f1) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::PowFields : input field is NULL !"); if(!f1->areCompatibleForMul(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply PowFields on them !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->pow(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply PowFields on them! Check support mesh, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td(f1->timeDiscr()->pow(f2->timeDiscr())); + td->copyTinyAttrFrom(*f1->timeDiscr()); + MCAuto ret(new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone())); ret->setMesh(f1->getMesh()); return ret.retn(); } /*! * Directly call MEDCouplingFieldDouble::PowFields static method. - * + * * \sa MEDCouplingFieldDouble::PowFields */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const { return PowFields(this,&other); } -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other) { if(!areCompatibleForDiv(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !"); - _time_discr->powEqual(other._time_discr); + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply ^= on them! Check support mesh, and spatial and time discretisation."); + timeDiscr()->powEqual(other.timeDiscr()); + _nature = NoNature; return *this; } @@ -3176,13 +2855,15 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCoupli * \throw If the mesh is not set. * \throw If any of the fields has no name. * + * \if ENABLE_EXAMPLES * \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".
* \ref py_mcfielddouble_WriteVTK "Here is a Python example". + * \endif */ -void MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector& fs, bool isBinary) +std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector& fs, bool isBinary) { if(fs.empty()) - return; + return std::string(); std::size_t nfs=fs.size(); if(!fs[0]) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field is NULL !"); @@ -3194,7 +2875,8 @@ void MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::ve 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."); if(!m) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !"); - MEDCouplingAutoRefCountObjectPtr byteArr; + std::string ret(m->getVTKFileNameOf(fileName)); + MCAuto byteArr; if(isBinary) { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); } std::ostringstream coss,noss; @@ -3205,7 +2887,7 @@ void MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::ve if(name.empty()) { std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + throw INTERP_KERNEL::Exception(oss.str()); } TypeOfField typ=cur->getTypeOfField(); if(typ==ON_CELLS) @@ -3215,46 +2897,100 @@ void MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::ve else throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : only node and cell fields supported for the moment !"); } - m->writeVTKAdvanced(fileName,coss.str(),noss.str(),byteArr); + m->writeVTKAdvanced(ret,coss.str(),noss.str(),byteArr); + return ret; } -void MEDCouplingFieldDouble::reprQuickOverview(std::ostream& stream) const +MCAuto MEDCouplingFieldDouble::voronoizeGen(const Voronizer *vor, double eps) const { - stream << "MEDCouplingFieldDouble C++ instance at " << this << ". Name : \"" << _name << "\"." << std::endl; - const char *nat=0; - try - { - nat=MEDCouplingNatureOfField::GetRepr(_nature); - stream << "Nature of field : " << nat << ".\n"; - } - catch(INTERP_KERNEL::Exception& /*e*/) - { } - const MEDCouplingFieldDiscretization *fd(_type); - if(!fd) - stream << "No spatial discretization set !"; - else - fd->reprQuickOverview(stream); - stream << std::endl; - if(!_mesh) - stream << "\nNo mesh support defined !"; + checkConsistencyLight(); + if(!vor) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoizeGen : null pointer !"); + MCAuto fieldToWO; + const MEDCouplingMesh *inpMeshBase(getMesh()); + MCAuto inpMesh(inpMeshBase->buildUnstructured()); + std::string meshName(inpMesh->getName()); + if(!inpMesh->isPresenceOfQuadratic()) + fieldToWO=clone(false); else { - std::ostringstream oss; - _mesh->reprQuickOverview(oss); - std::string tmp(oss.str()); - stream << "\nMesh info : " << tmp.substr(0,tmp.find('\n')); + fieldToWO=convertQuadraticCellsToLinear(); + inpMeshBase=fieldToWO->getMesh(); + inpMesh=inpMeshBase->buildUnstructured(); } - if(_time_discr) + mcIdType nbCells(inpMesh->getNumberOfCells()); + const MEDCouplingFieldDiscretization *disc(fieldToWO->getDiscretization()); + const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast(disc)); + if(!disc2) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : Not a ON_GAUSS_PT field"); + mcIdType nbLocs(disc2->getNbOfGaussLocalization()); + std::vector< MCAuto > cells(nbCells); + for(mcIdType i=0;igetArray(); - if(arr) - { - stream << "\n\nArray info : "; - arr->reprQuickOverview(stream); - } - else + const MEDCouplingGaussLocalization& gl(disc2->getGaussLocalization(i)); + if(gl.getDimension()!=vor->getDimension()) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::voronoize2D : not a 2D one !"); + MCAuto mesh(gl.buildRefCell()); + const std::vector& coo(gl.getGaussCoords()); + MCAuto coo2(DataArrayDouble::NewFromStdVector(coo)); + coo2->rearrange(vor->getDimension()); + // + MCAuto coo3(MEDCouplingUMesh::Build0DMeshFromCoords(coo2)); + // + MCAuto vorCellsForCurDisc(vor->doIt(mesh,coo2,eps)); + std::vector ids; + MCAuto ptsInReal; + disc2->getCellIdsHavingGaussLocalization(i,ids); + { + MCAuto subMesh(inpMesh->buildPartOfMySelf(&ids[0],&ids[0]+ids.size())); + ptsInReal=gl.localizePtsInRefCooForEachCell(vorCellsForCurDisc->getCoords(),subMesh); + } + mcIdType nbPtsPerCell(vorCellsForCurDisc->getNumberOfNodes()); + for(mcIdType j=0;j elt(vorCellsForCurDisc->clone(false)); + MCAuto coo4(ptsInReal->selectByTupleIdSafeSlice(j*nbPtsPerCell,(j+1)*nbPtsPerCell,1)); + elt->setCoords(coo4); + cells[ids[j]]=elt; } } + std::vector< const MEDCouplingUMesh * > cellsPtr(VecAutoToVecOfCstPt(cells)); + MCAuto outMesh(MEDCouplingUMesh::MergeUMeshes(cellsPtr)); + outMesh->setName(meshName); + MCAuto onCells(MEDCouplingFieldDouble::New(ON_CELLS)); + onCells->setMesh(outMesh); + { + MCAuto arr(fieldToWO->getArray()->deepCopy()); + onCells->setArray(arr); + } + onCells->setTimeUnit(getTimeUnit()); + { + int b,c; + double a(getTime(b,c)); + onCells->setTime(a,b,c); + } + onCells->setName(getName()); + return onCells; +} + +MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr() +{ + MEDCouplingTimeDiscretizationTemplate *ret(_time_discr); + if(!ret) + return 0; + MEDCouplingTimeDiscretization *retc(dynamic_cast(ret)); + if(!retc) + throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !"); + return retc; +} + +const MEDCouplingTimeDiscretization *MEDCouplingFieldDouble::timeDiscr() const +{ + const MEDCouplingTimeDiscretizationTemplate *ret(_time_discr); + if(!ret) + return 0; + const MEDCouplingTimeDiscretization *retc(dynamic_cast(ret)); + if(!retc) + throw INTERP_KERNEL::Exception("Field Double Null invalid type of time discr !"); + return retc; }