From 56a83f29521f0945ec665b2b9a487270f56826b0 Mon Sep 17 00:00:00 2001 From: ageay Date: Mon, 6 Dec 2010 16:22:13 +0000 Subject: [PATCH] *** empty log message *** --- src/MEDCoupling/MEDCouplingCMesh.cxx | 2 +- src/MEDCoupling/MEDCouplingCMesh.hxx | 2 +- src/MEDCoupling/MEDCouplingExtrudedMesh.cxx | 5 + src/MEDCoupling/MEDCouplingExtrudedMesh.hxx | 1 + src/MEDCoupling/MEDCouplingFieldDouble.cxx | 111 ++++++++-- src/MEDCoupling/MEDCouplingFieldDouble.hxx | 47 ++-- src/MEDCoupling/MEDCouplingMemArray.cxx | 192 ++++++++++++++++- src/MEDCoupling/MEDCouplingMemArray.hxx | 9 + src/MEDCoupling/MEDCouplingMesh.hxx | 2 + src/MEDCoupling/MEDCouplingPointSet.cxx | 58 ++++- src/MEDCoupling/MEDCouplingPointSet.hxx | 5 +- .../MEDCouplingTimeDiscretization.cxx | 184 +++++++++++++++- .../MEDCouplingTimeDiscretization.hxx | 15 ++ src/MEDCoupling/MEDCouplingUMesh.cxx | 125 ++++++++--- src/MEDCoupling/MEDCouplingUMesh.hxx | 6 +- src/MEDCoupling/MEDCouplingUMeshDesc.cxx | 12 ++ src/MEDCoupling/MEDCouplingUMeshDesc.hxx | 2 + .../Test/MEDCouplingBasicsTest2.cxx | 204 ++++++++++++++++++ 18 files changed, 892 insertions(+), 90 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingCMesh.cxx b/src/MEDCoupling/MEDCouplingCMesh.cxx index 4c49d3b93..7b3141077 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCMesh.cxx @@ -436,7 +436,7 @@ void MEDCouplingCMesh::setCoords(DataArrayDouble *coordsX, DataArrayDouble *coor declareAsNew(); } -MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const +MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) { int spaceDim=getSpaceDimension(); MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),spaceDim); diff --git a/src/MEDCoupling/MEDCouplingCMesh.hxx b/src/MEDCoupling/MEDCouplingCMesh.hxx index c7d9e8792..3d047a6eb 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.hxx +++ b/src/MEDCoupling/MEDCouplingCMesh.hxx @@ -63,7 +63,7 @@ namespace ParaMEDMEM DataArrayDouble *coordsY=0, DataArrayDouble *coordsZ=0); // tools - MEDCouplingUMesh *buildUnstructured() const; + MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); MEDCouplingMesh *buildPart(const int *start, const int *end) const; MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx index 84a9d451c..385977e01 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx @@ -330,6 +330,11 @@ MEDCouplingUMesh *MEDCouplingExtrudedMesh::build3DUnstructuredMesh() const return ret; } +MEDCouplingUMesh *MEDCouplingExtrudedMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) +{ + return build3DUnstructuredMesh(); +} + MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const { std::string name="MeasureOfMesh_"; diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx index 363172410..d5025341e 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx @@ -65,6 +65,7 @@ namespace ParaMEDMEM MEDCouplingUMesh *getMesh1D() const { return _mesh1D; } DataArrayInt *getMesh3DIds() const { return _mesh3D_ids; } MEDCouplingUMesh *build3DUnstructuredMesh() const; + MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getMeasureField(bool) const; MEDCouplingFieldDouble *getMeasureFieldOnNode(bool) const; MEDCouplingFieldDouble *buildOrthogonalField() const; diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index 60b5caab8..f530f2141 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -52,6 +52,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) c return ret; } +MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const +{ + return cloneWithMesh(true); +} + MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const { MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(_time_discr,td,deepCpy); @@ -221,6 +226,21 @@ bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) return true; } +/*! + * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible, + * except that 'this' and other can have different number of components. + */ +bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const +{ + if(!MEDCouplingField::areStrictlyCompatible(other)) + return false; + if(_nature!=other->_nature) + return false; + if(!_time_discr->areCompatibleForMeld(other->_time_discr)) + return false; + return true; +} + /*! * This method performs a clone of mesh and a renumbering of underlying cells of it. The number of cells remains the same. * The values of field are impacted in consequence to have the same geometrical field. @@ -1033,6 +1053,29 @@ bool MEDCouplingFieldDouble::mergeNodes(double eps) throw(INTERP_KERNEL::Excepti return true; } +/*! + * Merge nodes with (barycenter computation) of underlying mesh. In case of some node will be merged the underlying mesh instance will change. + */ +bool MEDCouplingFieldDouble::mergeNodes2(double eps) throw(INTERP_KERNEL::Exception) +{ + 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 !"); + MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); + bool ret; + int ret2; + MEDCouplingAutoRefCountObjectPtr arr=meshC2->mergeNodes2(eps,ret,ret2); + if(!ret)//no nodes have been merged. + return ret; + std::vector arrays; + _time_discr->getArrays(arrays); + for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + if(*iter) + _type->renumberValuesOnNodes(arr->getConstPointer(),*iter); + setMesh(meshC2); + return true; +} + /*! * This method applyies ParaMEDMEM::MEDCouplingPointSet::zipCoords method on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingPointSet. * If some nodes have disappeared true is returned. @@ -1221,7 +1264,7 @@ void MEDCouplingFieldDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Excepti _time_discr->sortPerTuple(asc); } -MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { if(!f1->areCompatibleForMerge(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply mergeFields on them !"); @@ -1229,6 +1272,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const MEDCouplingFie const MEDCouplingMesh *m2=f2->getMesh(); MEDCouplingMesh *m=m1->mergeMyselfWith(m2); MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(m); m->decrRef(); @@ -1237,7 +1281,48 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const MEDCouplingFie return ret; } -MEDCouplingFieldDouble *MEDCouplingFieldDouble::dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const std::vector& a) throw(INTERP_KERNEL::Exception) +{ + if(a.size()<=1) + throw INTERP_KERNEL::Exception("FieldDouble::mergeFields : size of array must be > 1 !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > 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++); + 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++) + { + if(!a[i]->getMesh()) + throw INTERP_KERNEL::Exception("mergeFields : A field as no underlying mesh !"); + ms[i]=a[i]->getMesh()->buildUnstructured(); + ms2[i]=ms[i]; + tds[i]=a[i]->_time_discr; + } + MEDCouplingAutoRefCountObjectPtr m=MEDCouplingUMesh::mergeUMeshes(ms2); + MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds); + td->copyTinyAttrFrom(*(a[0]->_time_discr)); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()); + ret->setMesh(m); + ret->setName(a[0]->getName()); + ret->setDescription(a[0]->getDescription()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::meldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) +{ + if(!f1->areCompatibleForMeld(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); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply dotFields on them !"); @@ -1248,7 +1333,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::dotFields(const MEDCouplingField return ret; } -MEDCouplingFieldDouble *MEDCouplingFieldDouble::crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +MEDCouplingFieldDouble *MEDCouplingFieldDouble::crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply crossProductFields on them !"); @@ -1259,7 +1344,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::crossProductFields(const MEDCoup return ret; } -MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply maxFields on them !"); @@ -1270,7 +1355,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxFields(const MEDCouplingField return ret; } -MEDCouplingFieldDouble *MEDCouplingFieldDouble::minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +MEDCouplingFieldDouble *MEDCouplingFieldDouble::minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply minFields on them !"); @@ -1281,7 +1366,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::minFields(const MEDCouplingField return ret; } -MEDCouplingFieldDouble *MEDCouplingFieldDouble::addFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +MEDCouplingFieldDouble *MEDCouplingFieldDouble::addFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply addFields on them !"); @@ -1292,7 +1377,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::addFields(const MEDCouplingField return ret; } -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) { if(!areStrictlyCompatible(&other)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply += on them !"); @@ -1300,7 +1385,7 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCoupli return *this; } -MEDCouplingFieldDouble *MEDCouplingFieldDouble::substractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +MEDCouplingFieldDouble *MEDCouplingFieldDouble::substractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply substractFields on them !"); @@ -1311,7 +1396,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::substractFields(const MEDCouplin return ret; } -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) { if(!areStrictlyCompatible(&other)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply -= on them !"); @@ -1319,7 +1404,7 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCoupli return *this; } -MEDCouplingFieldDouble *MEDCouplingFieldDouble::multiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +MEDCouplingFieldDouble *MEDCouplingFieldDouble::multiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { if(!f1->areCompatibleForMul(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply multiplyFields on them !"); @@ -1330,7 +1415,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::multiplyFields(const MEDCoupling return ret; } -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) { if(!areCompatibleForMul(&other)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply *= on them !"); @@ -1338,7 +1423,7 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCoupli return *this; } -MEDCouplingFieldDouble *MEDCouplingFieldDouble::divideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +MEDCouplingFieldDouble *MEDCouplingFieldDouble::divideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply divideFields on them !"); @@ -1349,7 +1434,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::divideFields(const MEDCouplingFi return ret; } -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) { if(!areStrictlyCompatible(&other)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !"); diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index 19f804c31..c319fae10 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -41,6 +41,7 @@ namespace ParaMEDMEM bool areCompatibleForMerge(const MEDCouplingField *other) const; bool areStrictlyCompatible(const MEDCouplingField *other) const; bool areCompatibleForMul(const MEDCouplingField *other) const; + bool areCompatibleForMeld(const MEDCouplingFieldDouble *other) const; void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); void renumberCellsWithoutMesh(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); void renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception); @@ -48,6 +49,7 @@ namespace ParaMEDMEM DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *deepCpy() const; MEDCouplingFieldDouble *clone(bool recDeepCpy) const; MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const; @@ -112,6 +114,7 @@ namespace ParaMEDMEM void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception); void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception); bool mergeNodes(double eps) throw(INTERP_KERNEL::Exception); + bool mergeNodes2(double eps) throw(INTERP_KERNEL::Exception); bool zipCoords() throw(INTERP_KERNEL::Exception); bool zipConnectivity(int compType) throw(INTERP_KERNEL::Exception); bool simplexize(int policy) throw(INTERP_KERNEL::Exception); @@ -128,27 +131,29 @@ namespace ParaMEDMEM MEDCouplingFieldDouble *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); void setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - static MEDCouplingFieldDouble *dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const { return dotFields(this,&other); } - static MEDCouplingFieldDouble *crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const { return crossProductFields(this,&other); } - static MEDCouplingFieldDouble *maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const { return maxFields(this,&other); } - static MEDCouplingFieldDouble *minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const { return minFields(this,&other); } - MEDCouplingFieldDouble *operator+(const MEDCouplingFieldDouble& other) const { return addFields(this,&other); } - const MEDCouplingFieldDouble &operator+=(const MEDCouplingFieldDouble& other); - static MEDCouplingFieldDouble *addFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCouplingFieldDouble *operator-(const MEDCouplingFieldDouble& other) const { return substractFields(this,&other); } - const MEDCouplingFieldDouble &operator-=(const MEDCouplingFieldDouble& other); - static MEDCouplingFieldDouble *substractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const { return multiplyFields(this,&other); } - const MEDCouplingFieldDouble &operator*=(const MEDCouplingFieldDouble& other); - static MEDCouplingFieldDouble *multiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const { return divideFields(this,&other); } - const MEDCouplingFieldDouble &operator/=(const MEDCouplingFieldDouble& other); - static MEDCouplingFieldDouble *divideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + static MEDCouplingFieldDouble *mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *mergeFields(const std::vector& a) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *meldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return dotFields(this,&other); } + static MEDCouplingFieldDouble *crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return crossProductFields(this,&other); } + static MEDCouplingFieldDouble *maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return maxFields(this,&other); } + static MEDCouplingFieldDouble *minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return minFields(this,&other); } + MEDCouplingFieldDouble *operator+(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return addFields(this,&other); } + const MEDCouplingFieldDouble &operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *addFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *operator-(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return substractFields(this,&other); } + const MEDCouplingFieldDouble &operator-=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *substractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return multiplyFields(this,&other); } + const MEDCouplingFieldDouble &operator*=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *multiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return divideFields(this,&other); } + const MEDCouplingFieldDouble &operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *divideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); private: MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td); MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCpy); diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 1b4a20b49..3d916ed2e 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -136,6 +136,11 @@ DataArrayDouble *DataArrayDouble::deepCopy() const return new DataArrayDouble(*this); } +DataArrayDouble *DataArrayDouble::deepCpy() const +{ + return new DataArrayDouble(*this); +} + DataArrayDouble *DataArrayDouble::performCpy(bool deepCpy) const { if(deepCpy) @@ -479,6 +484,37 @@ DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector& return ret; } +/*! + * This method melds the components of 'this' with components of 'other'. + * After this call in case of success, 'this' will contain a number of components equal to the sum of 'this' + * before the call and the number of components of 'other'. + * This method expects that 'this' and 'other' have exactly the same number of tuples. If not an exception is thrown. + */ +void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + other->checkAllocated(); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples!=other->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !"); + int nbOfComp1=getNumberOfComponents(); + int nbOfComp2=other->getNumberOfComponents(); + double *newArr=new double[nbOfTuples*(nbOfComp1+nbOfComp2)]; + double *w=newArr; + const double *inp1=getConstPointer(); + const double *inp2=other->getConstPointer(); + for(int i=0;i compIds(nbOfComp2); + for(int i=0;i& compoIds) throw(INTERP_KERNEL::Exception) { copyPartOfStringInfoFrom2(compoIds,*a); @@ -1035,16 +1071,74 @@ DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const thr DataArrayDouble *DataArrayDouble::aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { - int nbOfComp=a1->getNumberOfComponents(); - if(nbOfComp!=a2->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Nb of components mismatch for array aggregation !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); + std::vector tmp(2); + tmp[0]=a1; tmp[1]=a2; + return aggregate(tmp); +} + +DataArrayDouble *DataArrayDouble::aggregate(const std::vector& a) throw(INTERP_KERNEL::Exception) +{ + if(a.empty()) + throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : input list must be NON EMPTY !"); + std::vector::const_iterator it=a.begin(); + int nbOfComp=(*it)->getNumberOfComponents(); + int nbt=(*it++)->getNumberOfTuples(); + for(int i=1;it!=a.end();it++,i++) + { + if((*it)->getNumberOfComponents()!=nbOfComp) + throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : Nb of components mismatch for array aggregation !"); + nbt+=(*it)->getNumberOfTuples(); + } DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1+nbOfTuple2,nbOfComp); - double *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer()); - std::copy(a2->getConstPointer(),a2->getConstPointer()+nbOfTuple2*nbOfComp,pt); - ret->copyStringInfoFrom(*a1); + ret->alloc(nbt,nbOfComp); + double *pt=ret->getPointer(); + for(it=a.begin();it!=a.end();it++) + pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt); + ret->copyStringInfoFrom(*(a[0])); + return ret; +} + +DataArrayDouble *DataArrayDouble::meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) +{ + std::vector arr(2); + arr[0]=a1; arr[1]=a2; + return meld(arr); +} + +DataArrayDouble *DataArrayDouble::meld(const std::vector& a) throw(INTERP_KERNEL::Exception) +{ + if(a.empty()) + throw INTERP_KERNEL::Exception("DataArrayDouble::meld : array must be NON empty !"); + std::vector::const_iterator it; + for(it=a.begin();it!=a.end();it++) + (*it)->checkAllocated(); + it=a.begin(); + int nbOfTuples=(*it)->getNumberOfTuples(); + std::vector nbc(a.size()); + std::vector pts(a.size()); + nbc[0]=(*it)->getNumberOfComponents(); + pts[0]=(*it++)->getConstPointer(); + for(int i=1;it!=a.end();it++,i++) + { + if(nbOfTuples!=(*it)->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("DataArrayDouble::meld : mismatch of number of tuples !"); + nbc[i]=(*it)->getNumberOfComponents(); + pts[i]=(*it)->getConstPointer(); + } + int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(nbOfTuples,totalNbOfComp); + double *retPtr=ret->getPointer(); + for(int i=0;isetInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str()); return ret; } @@ -1316,6 +1410,11 @@ DataArrayInt *DataArrayInt::deepCopy() const return new DataArrayInt(*this); } +DataArrayInt *DataArrayInt::deepCpy() const +{ + return new DataArrayInt(*this); +} + DataArrayInt *DataArrayInt::performCpy(bool deepCpy) const { if(deepCpy) @@ -1705,6 +1804,37 @@ DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector& compo return ret; } +/*! + * This method melds the components of 'this' with components of 'other'. + * After this call in case of success, 'this' will contain a number of components equal to the sum of 'this' + * before the call and the number of components of 'other'. + * This method expects that 'this' and 'other' have exactly the same number of tuples. If not an exception is thrown. + */ +void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + other->checkAllocated(); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples!=other->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !"); + int nbOfComp1=getNumberOfComponents(); + int nbOfComp2=other->getNumberOfComponents(); + int *newArr=new int[nbOfTuples*(nbOfComp1+nbOfComp2)]; + int *w=newArr; + const int *inp1=getConstPointer(); + const int *inp2=other->getConstPointer(); + for(int i=0;i compIds(nbOfComp2); + for(int i=0;i& compoIds) throw(INTERP_KERNEL::Exception) { copyPartOfStringInfoFrom2(compoIds,*a); @@ -1778,6 +1908,50 @@ DataArrayInt *DataArrayInt::aggregate(const DataArrayInt *a1, const DataArrayInt return ret; } +DataArrayInt *DataArrayInt::meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) +{ + std::vector arr(2); + arr[0]=a1; arr[1]=a2; + return meld(arr); +} + +DataArrayInt *DataArrayInt::meld(const std::vector& a) throw(INTERP_KERNEL::Exception) +{ + if(a.empty()) + throw INTERP_KERNEL::Exception("DataArrayInt::meld : array must be NON empty !"); + std::vector::const_iterator it; + for(it=a.begin();it!=a.end();it++) + (*it)->checkAllocated(); + it=a.begin(); + int nbOfTuples=(*it)->getNumberOfTuples(); + std::vector nbc(a.size()); + std::vector pts(a.size()); + nbc[0]=(*it)->getNumberOfComponents(); + pts[0]=(*it++)->getConstPointer(); + for(int i=1;it!=a.end();it++,i++) + { + if(nbOfTuples!=(*it)->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !"); + nbc[i]=(*it)->getNumberOfComponents(); + pts[i]=(*it)->getConstPointer(); + } + int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbOfTuples,totalNbOfComp); + int *retPtr=ret->getPointer(); + for(int i=0;isetInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str()); + return ret; +} + /*! * This method create a minimal partition of groups 'groups' the std::iota array of size 'newNb'. * This method returns an array of size 'newNb' that specifies for each item at which familyId it owns to, and this method returns diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 57d7d8a0a..75d1feef2 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -119,6 +119,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT bool isAllocated() const; MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *deepCopy() const; + MEDCOUPLING_EXPORT DataArrayDouble *deepCpy() const; MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const; MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo); MEDCOUPLING_EXPORT void fillWithZero() throw(INTERP_KERNEL::Exception); @@ -147,6 +148,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayDouble *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getTuple(int tupleId, double *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } @@ -185,6 +187,9 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayDouble *aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayDouble *aggregate(const std::vector& a) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayDouble *meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayDouble *meld(const std::vector& a) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayDouble *dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayDouble *crossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayDouble *max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); @@ -212,6 +217,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT bool isAllocated() const; MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *deepCopy() const; + MEDCOUPLING_EXPORT DataArrayInt *deepCpy() const; MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const; MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo); MEDCOUPLING_EXPORT bool isEqual(const DataArrayInt& other) const; @@ -244,6 +250,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } MEDCOUPLING_EXPORT int getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } @@ -254,6 +261,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *getIdsEqual(int val) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *getIdsEqualList(const std::vector& vals) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2); + MEDCOUPLING_EXPORT static DataArrayInt *meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayInt *meld(const std::vector& a) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *makePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups); MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); MEDCOUPLING_EXPORT void writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } diff --git a/src/MEDCoupling/MEDCouplingMesh.hxx b/src/MEDCoupling/MEDCouplingMesh.hxx index 75ed3f309..d5b828676 100644 --- a/src/MEDCoupling/MEDCouplingMesh.hxx +++ b/src/MEDCoupling/MEDCouplingMesh.hxx @@ -40,6 +40,7 @@ namespace ParaMEDMEM class DataArrayInt; class DataArrayDouble; + class MEDCouplingUMesh; class MEDCouplingFieldDouble; class MEDCOUPLING_EXPORT MEDCouplingMesh : public RefCountObject, public TimeLabel @@ -91,6 +92,7 @@ namespace ParaMEDMEM virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const = 0; virtual MEDCouplingMesh *buildPart(const int *start, const int *end) const = 0; virtual MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const = 0; + virtual MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception) = 0; virtual DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception) = 0; virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const; static MEDCouplingMesh *mergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2); diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index e587b2978..d4812d83a 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -326,6 +326,38 @@ void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNo newCoords->decrRef(); } +/* + * This method renumber 'this' using 'newNodeNumbers' array of size this->getNumberOfNodes. + * newNbOfNodes specifies the *std::max_element(newNodeNumbers,newNodeNumbers+this->getNumberOfNodes()) + * This value is asked because often known by the caller of this method. + * Contrary to ParaMEDMEM::MEDCouplingPointSet::renumberNodes method for merged nodes the barycenter of them is computed here. + * + * @param newNodeNumbers array specifying the new numbering. + * @param newNbOfNodes the new number of nodes. + */ +void MEDCouplingPointSet::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes) +{ + DataArrayDouble *newCoords=DataArrayDouble::New(); + std::vector div(newNbOfNodes); + int spaceDim=getSpaceDimension(); + newCoords->alloc(newNbOfNodes,spaceDim); + newCoords->copyStringInfoFrom(*_coords); + newCoords->fillWithZero(); + int oldNbOfNodes=getNumberOfNodes(); + double *ptToFill=newCoords->getPointer(); + const double *oldCoordsPtr=_coords->getConstPointer(); + for(int i=0;i()); + div[newNodeNumbers[i]]++; + } + for(int i=0;i(),1./(double)div[i])); + setCoords(newCoords); + newCoords->decrRef(); +} + /*! * This method fills bbox params like that : bbox[0]=XMin, bbox[1]=XMax, bbox[2]=YMin... * The returned bounding box is arranged along trihedron. @@ -513,7 +545,7 @@ void MEDCouplingPointSet::findNodesOnPlane(const double *pt, const double *vec, /*! * merge _coords arrays of m1 and m2 and returns the union. The returned instance is newly created with ref count == 1. */ -DataArrayDouble *MEDCouplingPointSet::mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) +DataArrayDouble *MEDCouplingPointSet::mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception) { int spaceDim=m1->getSpaceDimension(); if(spaceDim!=m2->getSpaceDimension()) @@ -521,6 +553,30 @@ DataArrayDouble *MEDCouplingPointSet::mergeNodesArray(const MEDCouplingPointSet return DataArrayDouble::aggregate(m1->getCoords(),m2->getCoords()); } +DataArrayDouble *MEDCouplingPointSet::mergeNodesArray(const std::vector& ms) throw(INTERP_KERNEL::Exception) +{ + if(ms.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::mergeNodesArray : input array must be NON EMPTY !"); + std::vector::const_iterator it=ms.begin(); + std::vector coo(ms.size()); + int spaceDim=(*it)->getSpaceDimension(); + coo[0]=(*it++)->getCoords(); + for(int i=1;it!=ms.end();it++,i++) + { + const DataArrayDouble *tmp=(*it)->getCoords(); + if(tmp) + { + if((*it)->getSpaceDimension()==spaceDim) + coo[i]=tmp; + else + throw INTERP_KERNEL::Exception("Mismatch in SpaceDim during call of mergeNodesArray !"); + } + else + throw INTERP_KERNEL::Exception("Empty coords detected during call of mergeNodesArray !"); + } + return DataArrayDouble::aggregate(coo); +} + /*! * Factory to build new instance of instanciable subclasses of MEDCouplingPointSet. * This method is used during unserialization process. diff --git a/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/MEDCoupling/MEDCouplingPointSet.hxx index 21cb749b4..4a51adf5b 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.hxx +++ b/src/MEDCoupling/MEDCouplingPointSet.hxx @@ -54,6 +54,7 @@ namespace ParaMEDMEM bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const; bool areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const; virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0; + virtual DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0; DataArrayInt *buildPermArrayForMergeNode(int limitNodeId, double precision, bool& areNodesMerged, int& newNbOfNodes) const; std::vector getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception); void getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, std::vector& c, std::vector& cI) const throw(INTERP_KERNEL::Exception); @@ -70,7 +71,8 @@ namespace ParaMEDMEM void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) = 0; void findNodesOnPlane(const double *pt, const double *vec, double eps, std::vector& nodes) const throw(INTERP_KERNEL::Exception); - static DataArrayDouble *mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2); + static DataArrayDouble *mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception); + static DataArrayDouble *mergeNodesArray(const std::vector& ms) throw(INTERP_KERNEL::Exception); static MEDCouplingPointSet *buildInstanceFromMeshType(MEDCouplingMeshType type); static void rotate2DAlg(const double *center, double angle, int nbNodes, double *coords); static void rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords); @@ -82,6 +84,7 @@ namespace ParaMEDMEM virtual void findBoundaryNodes(std::vector& nodes) const = 0; virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const = 0; virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); + virtual void renumberNodes2(const int *newNodeNumbers, int newNbOfNodes); virtual bool isEmptyMesh(const std::vector& tinyInfo) const = 0; //! size of returned tinyInfo must be always the same. void getTinySerializationInformation(std::vector& tinyInfo, std::vector& littleStrings) const; diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx index a150a9cd4..8e43c0e60 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx @@ -115,6 +115,19 @@ bool MEDCouplingTimeDiscretization::areStrictlyCompatible(const MEDCouplingTimeD return true; } +bool MEDCouplingTimeDiscretization::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +{ + if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) + return false; + if(_array==0 && other->_array==0) + return true; + if(_array==0 || other->_array==0) + return false; + if(_array->getNumberOfTuples()!=other->_array->getNumberOfTuples()) + return false; + return true; +} + bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const { if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) @@ -708,6 +721,14 @@ bool MEDCouplingNoTimeLabel::areStrictlyCompatibleForMul(const MEDCouplingTimeDi return otherC!=0; } +bool MEDCouplingNoTimeLabel::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) + return false; + const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); + return otherC!=0; +} + bool MEDCouplingNoTimeLabel::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); @@ -731,6 +752,36 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const MEDCoupli throw INTERP_KERNEL::Exception("NoTimeLabel::aggregation on mismatched time discretization !"); DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray()); MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const std::vector& other) const +{ + std::vector a(other.size()); + int i=0; + for(std::vector::const_iterator it=other.begin();it!=other.end();it++,i++) + { + const MEDCouplingNoTimeLabel *itC=dynamic_cast(*it); + if(!itC) + throw INTERP_KERNEL::Exception("NoTimeLabel::aggregate on mismatched time discretization !"); + a[i]=itC->getArray(); + } + DataArrayDouble *arr=DataArrayDouble::aggregate(a); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::meld(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::meld on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::meld(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; ret->setTimeTolerance(getTimeTolerance()); ret->setArray(arr,0); arr->decrRef(); @@ -986,6 +1037,14 @@ bool MEDCouplingWithTimeStep::areStrictlyCompatibleForMul(const MEDCouplingTimeD return otherC!=0; } +bool MEDCouplingWithTimeStep::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) + return false; + const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); + return otherC!=0; +} + bool MEDCouplingWithTimeStep::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); @@ -1030,12 +1089,38 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCoupl throw INTERP_KERNEL::Exception("WithTimeStep::aggregation on mismatched time discretization !"); DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray()); MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setTimeTolerance(getTimeTolerance()); ret->setArray(arr,0); arr->decrRef(); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const std::vector& other) const +{ + std::vector a(other.size()); + int i=0; + for(std::vector::const_iterator it=other.begin();it!=other.end();it++,i++) + { + const MEDCouplingWithTimeStep *itC=dynamic_cast(*it); + if(!itC) + throw INTERP_KERNEL::Exception("WithTimeStep::aggregate on mismatched time discretization !"); + a[i]=itC->getArray(); + } + DataArrayDouble *arr=DataArrayDouble::aggregate(a); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::meld(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::meld on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::meld(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + arr->decrRef(); return ret; } @@ -1341,6 +1426,14 @@ bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForMul(const MEDCoupli return otherC!=0; } +bool MEDCouplingConstOnTimeInterval::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) + return false; + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); + return otherC!=0; +} + bool MEDCouplingConstOnTimeInterval::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); @@ -1421,19 +1514,44 @@ void MEDCouplingConstOnTimeInterval::checkTimePresence(double time) const throw( MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const MEDCouplingTimeDiscretization *other) const { - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("ConstOnTimeInterval::aggregation on mismatched time discretization !"); DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray()); MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const std::vector& other) const +{ + std::vector a(other.size()); + int i=0; + for(std::vector::const_iterator it=other.begin();it!=other.end();it++,i++) + { + const MEDCouplingConstOnTimeInterval *itC=dynamic_cast(*it); + if(!itC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::aggregate on mismatched time discretization !"); + a[i]=itC->getArray(); + } + DataArrayDouble *arr=DataArrayDouble::aggregate(a); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::meld(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::meld on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::meld(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; ret->setTimeTolerance(getTimeTolerance()); ret->setArray(arr,0); arr->decrRef(); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); - tmp3=getEndTime(tmp1,tmp2); - ret->setEndTime(tmp3,tmp1,tmp2); return ret; } @@ -1878,6 +1996,14 @@ bool MEDCouplingLinearTime::areStrictlyCompatibleForMul(const MEDCouplingTimeDis return otherC!=0; } +bool MEDCouplingLinearTime::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) + return false; + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + return otherC!=0; +} + /*! * vals is expected to be of size 2*_array->getNumberOfTuples()==_array->getNumberOfTuples()+_end_array->getNumberOfTuples() */ @@ -1938,6 +2064,44 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const MEDCouplin DataArrayDouble *arr1=DataArrayDouble::aggregate(getArray(),other->getArray()); DataArrayDouble *arr2=DataArrayDouble::aggregate(getEndArray(),other->getEndArray()); MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + arr1->decrRef(); + ret->setEndArray(arr2,0); + arr2->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const std::vector& other) const +{ + std::vector a(other.size()); + std::vector b(other.size()); + int i=0; + for(std::vector::const_iterator it=other.begin();it!=other.end();it++,i++) + { + const MEDCouplingLinearTime *itC=dynamic_cast(*it); + if(!itC) + throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::aggregate on mismatched time discretization !"); + a[i]=itC->getArray(); + b[i]=itC->getEndArray(); + } + DataArrayDouble *arr=DataArrayDouble::aggregate(a); + DataArrayDouble *arr2=DataArrayDouble::aggregate(b); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr,0); + arr->decrRef(); + ret->setEndArray(arr2,0); + arr2->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::meld(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::meld on mismatched time discretization !"); + DataArrayDouble *arr1=DataArrayDouble::meld(getArray(),other->getArray()); + DataArrayDouble *arr2=DataArrayDouble::meld(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; ret->setTimeTolerance(getTimeTolerance()); ret->setArray(arr1,0); arr1->decrRef(); diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx index e826e12ce..45f8518ba 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx @@ -46,6 +46,7 @@ namespace ParaMEDMEM virtual bool areCompatible(const MEDCouplingTimeDiscretization *other) const; virtual bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; virtual bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + virtual bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; virtual bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; virtual bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(const MEDCouplingTimeDiscretization *other, @@ -53,6 +54,8 @@ namespace ParaMEDMEM virtual std::string getStringRepr() const = 0; virtual TypeOfTimeDiscretization getEnum() const = 0; virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const = 0; + virtual MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const = 0; + virtual MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const = 0; virtual MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const = 0; virtual MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const = 0; virtual MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const = 0; @@ -133,6 +136,8 @@ namespace ParaMEDMEM std::string getStringRepr() const; TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; + MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; @@ -150,6 +155,7 @@ namespace ParaMEDMEM bool areCompatible(const MEDCouplingTimeDiscretization *other) const; bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; void checkNoTimePresence() const throw(INTERP_KERNEL::Exception) { } void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception); @@ -180,6 +186,8 @@ namespace ParaMEDMEM void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; + MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; @@ -197,6 +205,7 @@ namespace ParaMEDMEM bool areCompatible(const MEDCouplingTimeDiscretization *other) const; bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; void getTinySerializationIntInformation(std::vector& tinyInfo) const; void getTinySerializationDbleInformation(std::vector& tinyInfo) const; void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); @@ -236,6 +245,7 @@ namespace ParaMEDMEM bool areCompatible(const MEDCouplingTimeDiscretization *other) const; bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception); @@ -245,6 +255,8 @@ namespace ParaMEDMEM TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } std::string getStringRepr() const; MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; + MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; @@ -331,10 +343,13 @@ namespace ParaMEDMEM bool areCompatible(const MEDCouplingTimeDiscretization *other) const; bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; void getValueForTime(double time, const std::vector& vals, double *res) const; void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; + MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 2fb724a8d..b4b80c5e5 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -907,6 +907,17 @@ DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerge return ret; } +/*! + * Idem ParaMEDMEM::MEDCouplingUMesh::mergeNodes method except that the merged nodes are meld into the barycenter of them. + */ +DataArrayInt *MEDCouplingUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) +{ + DataArrayInt *ret=buildPermArrayForMergeNode(-1,precision,areNodesMerged,newNbOfNodes); + if(areNodesMerged) + renumberNodes2(ret->getConstPointer(),newNbOfNodes); + return ret; +} + /*! * This method tries to use 'other' coords and use it for 'this'. If no exception was thrown after the call of this method : * this->_coords==other->_coords. If not a exception is thrown this remains unchanged. @@ -1101,6 +1112,12 @@ void MEDCouplingUMesh::findBoundaryNodes(std::vector& nodes) const meshDM1->decrRef(); } +MEDCouplingUMesh *MEDCouplingUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) +{ + incrRef(); + return const_cast(this); +} + /* * This method renumber 'this' using 'newNodeNumbers' array of size this->getNumberOfNodes. * newNbOfNodes specifies the *std::max_element(newNodeNumbers,newNodeNumbers+this->getNumberOfNodes()) @@ -1116,6 +1133,22 @@ void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes renumberNodesInConn(newNodeNumbers); } +/* + * This method renumber 'this' using 'newNodeNumbers' array of size this->getNumberOfNodes. + * newNbOfNodes specifies the *std::max_element(newNodeNumbers,newNodeNumbers+this->getNumberOfNodes()) + * This value is asked because often known by the caller of this method. + * This method, contrary to MEDCouplingMesh::renumberCells does NOT conserve the number of nodes before and after. + * The difference with ParaMEDMEM::MEDCouplingUMesh::renumberNodes method is in the fact that the barycenter of merged nodes is computed here. + * + * @param newNodeNumbers array specifying the new numbering. + * @param newNbOfNodes the new number of nodes. + */ +void MEDCouplingUMesh::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes) +{ + MEDCouplingPointSet::renumberNodes2(newNodeNumbers,newNbOfNodes); + renumberNodesInConn(newNodeNumbers); +} + /*! * This method renumbers nodes in connectivity only without any reference with coords. * Use it with care ! @@ -3215,41 +3248,69 @@ DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const * Returns a newly created mesh (with ref count ==1) that contains merge of 'mesh1' and 'other'. * The coords of 'mesh2' are added at the end of coords of 'mesh1'. */ -MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) +MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception) { - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - ret->setName("merge"); - DataArrayDouble *pts=mergeNodesArray(mesh1,mesh2); + std::vector tmp(2); + tmp[0]=mesh1; tmp[1]=mesh2; + return mergeUMeshes(tmp); +} + +MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshes(std::vector& a) throw(INTERP_KERNEL::Exception) +{ + if(a.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeUMeshes : input array must be NON EMPTY !"); + std::vector::const_iterator it=a.begin(); + int meshDim=(*it)->getMeshDimension(); + int nbOfCells=(*it)->getNumberOfCells(); + int meshLgth=(*it++)->getMeshLength(); + for(;it!=a.end();it++) + { + if(meshDim!=(*it)->getMeshDimension()) + throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, mergeMeshes impossible !"); + nbOfCells+=(*it)->getNumberOfCells(); + meshLgth+=(*it)->getMeshLength(); + } + std::vector aps(a.size()); + std::copy(a.begin(),a.end(),aps.begin()); + DataArrayDouble *pts=mergeNodesArray(aps); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New("merge",meshDim); ret->setCoords(pts); pts->decrRef(); - int meshDim=mesh1->getMeshDimension(); - if(meshDim!=mesh2->getMeshDimension()) - throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, mergeMeshes impossible !"); - ret->setMeshDimension(meshDim); - int delta=mesh1->getMeshLength(); - int pos=mesh1->getNumberOfCells(); - int nbOfCells2=mesh2->getNumberOfCells(); - int end=mesh1->getNumberOfCells()+nbOfCells2+1; - DataArrayInt *nodalIndex=DataArrayInt::aggregate(mesh1->getNodalConnectivityIndex(), - mesh2->getNodalConnectivityIndex(),1); - std::transform(nodalIndex->getConstPointer()+pos+1,nodalIndex->getConstPointer()+end, - nodalIndex->getPointer()+pos+1,std::bind2nd(std::plus(),delta)); - DataArrayInt *newNodal2=mesh2->getNodalConnectivity()->deepCopy(); - delta=mesh1->getNumberOfNodes(); - const int *nI2=mesh2->getNodalConnectivityIndex()->getConstPointer(); - int *pt=newNodal2->getPointer(); - for(int i=0;igetNodalConnectivity(),newNodal2,0); - newNodal2->decrRef(); - ret->setConnectivity(nodal,nodalIndex,true); - nodalIndex->decrRef(); - nodal->decrRef(); + DataArrayInt *c=DataArrayInt::New(); + c->alloc(meshLgth,1); + int *cPtr=c->getPointer(); + DataArrayInt *cI=DataArrayInt::New(); + cI->alloc(nbOfCells+1,1); + int *cIPtr=cI->getPointer(); + *cIPtr++=0; + int offset=0; + int offset2=0; + for(it=a.begin();it!=a.end();it++) + { + int curNbOfCell=(*it)->getNumberOfCells(); + const int *curCI=(*it)->_nodal_connec_index->getConstPointer(); + const int *curC=(*it)->_nodal_connec->getConstPointer(); + cIPtr=std::transform(curCI+1,curCI+curNbOfCell+1,cIPtr,std::bind2nd(std::plus(),offset)); + for(int j=0;jgetNumberOfNodes(); + } + // + ret->setConnectivity(c,cI,true); + c->decrRef(); + cI->decrRef(); + ret->incrRef(); return ret; } diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index df4ddd292..0fe13c9fc 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -85,13 +85,16 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); + MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void findBoundaryNodes(std::vector& nodes) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; MEDCOUPLING_EXPORT void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); + MEDCOUPLING_EXPORT void renumberNodes2(const int *newNodeNumbers, int newNbOfNodes); MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const double *bbox, double eps, std::vector& elems); MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector& elems); @@ -134,7 +137,8 @@ namespace ParaMEDMEM // MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshes(std::vector& a) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshesOnSameCoords(const std::vector& meshes); MEDCOUPLING_EXPORT static MEDCouplingUMesh *fuseUMeshesOnSameCoords(const std::vector& meshes, int compType, std::vector& corr); MEDCOUPLING_EXPORT static bool isPolygonWellOriented(const double *vec, const int *begin, const int *end, const double *coords); diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx index e8629b7b8..e0cff180d 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx @@ -338,6 +338,13 @@ DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesM return 0; } +DataArrayInt *MEDCouplingUMeshDesc::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) +{ + //not implemented yet. + areNodesMerged=false; + return 0; +} + void MEDCouplingUMeshDesc::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) { throw INTERP_KERNEL::Exception("Not implemented yet !"); @@ -377,6 +384,11 @@ MEDCouplingPointSet *MEDCouplingUMeshDesc::buildBoundaryMesh(bool keepCoords) co return 0; } +MEDCouplingUMesh *MEDCouplingUMeshDesc::buildUnstructured() const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::buildUnstructured : not implemented yet !"); +} + void MEDCouplingUMeshDesc::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) { throw INTERP_KERNEL::Exception("Available for UMesh desc but not implemented yet !"); diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx index f11fe94a4..1924108e9 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx @@ -62,6 +62,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const double *bbox, double eps, std::vector& elems); MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps, std::vector& elems); MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); + MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; @@ -69,6 +70,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void findBoundaryNodes(std::vector& nodes) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx index 2b2f4de2a..8e1e4fb01 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx @@ -3618,3 +3618,207 @@ void MEDCouplingBasicsTest::testSimplexize2() f1->decrRef(); m->decrRef(); } + +void MEDCouplingBasicsTest::testDAMeld1() +{ + DataArrayDouble *da1=DataArrayDouble::New(); + da1->alloc(7,2); + DataArrayDouble *da2=DataArrayDouble::New(); + da2->alloc(7,1); + // + da1->fillWithValue(7.); + da2->iota(0.); + DataArrayDouble *da3=da2->applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec"); + // + da1->setInfoOnComponent(0,"c0da1"); + da1->setInfoOnComponent(1,"c1da1"); + da3->setInfoOnComponent(0,"c0da3"); + da3->setInfoOnComponent(1,"c1da3"); + da3->setInfoOnComponent(2,"c2da3"); + // + DataArrayDouble *da1C=da1->deepCpy(); + da1->meldWith(da3); + CPPUNIT_ASSERT_EQUAL(5,da1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(7,da1->getNumberOfTuples()); + CPPUNIT_ASSERT(da1->getInfoOnComponent(0)=="c0da1"); + CPPUNIT_ASSERT(da1->getInfoOnComponent(1)=="c1da1"); + CPPUNIT_ASSERT(da1->getInfoOnComponent(2)=="c0da3"); + CPPUNIT_ASSERT(da1->getInfoOnComponent(3)=="c1da3"); + CPPUNIT_ASSERT(da1->getInfoOnComponent(4)=="c2da3"); + // + const double expected1[35]={7.,7.,0.,0.,0., 7.,7.,10.,100.,1000., 7.,7.,20.,200.,2000., 7.,7.,30.,300.,3000., 7.,7.,40.,400.,4000.,7.,7.,50.,500.,5000.,7.,7.,60.,600.,6000.}; + for(int i=0;i<35;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da1->getIJ(0,i),1e-10); + // + DataArrayInt *dai1=da1C->convertToIntArr(); + DataArrayInt *dai3=da3->convertToIntArr(); + dai1->meldWith(dai3); + CPPUNIT_ASSERT_EQUAL(5,dai1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(7,dai1->getNumberOfTuples()); + CPPUNIT_ASSERT(dai1->getInfoOnComponent(0)=="c0da1"); + CPPUNIT_ASSERT(dai1->getInfoOnComponent(1)=="c1da1"); + CPPUNIT_ASSERT(dai1->getInfoOnComponent(2)=="c0da3"); + CPPUNIT_ASSERT(dai1->getInfoOnComponent(3)=="c1da3"); + CPPUNIT_ASSERT(dai1->getInfoOnComponent(4)=="c2da3"); + for(int i=0;i<35;i++) + CPPUNIT_ASSERT_EQUAL((int)expected1[i],dai1->getIJ(0,i)); + // test of static method DataArrayDouble::meld + DataArrayDouble *da4=DataArrayDouble::meld(da1C,da3); + CPPUNIT_ASSERT_EQUAL(5,da4->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(7,da4->getNumberOfTuples()); + CPPUNIT_ASSERT(da4->getInfoOnComponent(0)=="c0da1"); + CPPUNIT_ASSERT(da4->getInfoOnComponent(1)=="c1da1"); + CPPUNIT_ASSERT(da4->getInfoOnComponent(2)=="c0da3"); + CPPUNIT_ASSERT(da4->getInfoOnComponent(3)=="c1da3"); + CPPUNIT_ASSERT(da4->getInfoOnComponent(4)=="c2da3"); + for(int i=0;i<35;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da4->getIJ(0,i),1e-10); + // test of static method DataArrayInt::meld + dai1->decrRef(); + dai1=da1C->convertToIntArr(); + DataArrayInt *dai4=DataArrayInt::meld(dai1,dai3); + CPPUNIT_ASSERT_EQUAL(5,dai4->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(7,dai4->getNumberOfTuples()); + CPPUNIT_ASSERT(dai4->getInfoOnComponent(0)=="c0da1"); + CPPUNIT_ASSERT(dai4->getInfoOnComponent(1)=="c1da1"); + CPPUNIT_ASSERT(dai4->getInfoOnComponent(2)=="c0da3"); + CPPUNIT_ASSERT(dai4->getInfoOnComponent(3)=="c1da3"); + CPPUNIT_ASSERT(dai4->getInfoOnComponent(4)=="c2da3"); + for(int i=0;i<35;i++) + CPPUNIT_ASSERT_EQUAL((int)expected1[i],dai4->getIJ(0,i)); + // + dai4->decrRef(); + da4->decrRef(); + dai3->decrRef(); + dai1->decrRef(); + da1C->decrRef(); + da1->decrRef(); + da2->decrRef(); + da3->decrRef(); +} + +void MEDCouplingBasicsTest::testFieldMeld1() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setMesh(m); + DataArrayDouble *da1=DataArrayDouble::New(); + const double arr1[5]={12.,23.,34.,45.,56.}; + da1->alloc(5,1); + std::copy(arr1,arr1+5,da1->getPointer()); + da1->setInfoOnComponent(0,"aaa"); + f1->setArray(da1); + f1->setTime(3.4,2,1); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->deepCpy(); + f2->setMesh(f1->getMesh()); + f2->checkCoherency(); + f2->changeNbOfComponents(2,5.); + (*f2)=5.; + f2->getArray()->setInfoOnComponent(0,"bbb"); + f2->getArray()->setInfoOnComponent(1,"ccc"); + f2->checkCoherency(); + // + MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::meldFields(f2,f1); + f3->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(5,f3->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,f3->getNumberOfComponents()); + CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(0)=="bbb"); + CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(1)=="ccc"); + CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(2)=="aaa"); + const double expected1[15]={5.,5.,12.,5.,5.,23.,5.,5.,34.,5.,5.,45.,5.,5.,56.}; + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-12); + int dt,it; + double time=f3->getTime(dt,it); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,time,1e-14); + CPPUNIT_ASSERT_EQUAL(2,dt); + CPPUNIT_ASSERT_EQUAL(1,it); + // + MEDCouplingFieldDouble *f4=f2->buildNewTimeReprFromThis(NO_TIME,false); + MEDCouplingFieldDouble *f5=f1->buildNewTimeReprFromThis(NO_TIME,false); + MEDCouplingFieldDouble *f6=MEDCouplingFieldDouble::meldFields(f4,f5); + f6->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(5,f6->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,f6->getNumberOfComponents()); + CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(0)=="bbb"); + CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(1)=="ccc"); + CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(2)=="aaa"); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f6->getIJ(0,i),1e-12); + // + f6->decrRef(); + f4->decrRef(); + f5->decrRef(); + f3->decrRef(); + da1->decrRef(); + f2->decrRef(); + f1->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest::testMergeNodes2() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + const double vec[2]={0.002,0.}; + m2->translate(vec); + // + std::vector tmp(2); + tmp[0]=m1; + tmp[1]=m2; + MEDCouplingUMesh *m3=MEDCouplingUMesh::mergeUMeshes(tmp); + bool b; + int newNbOfNodes; + DataArrayInt *da=m3->mergeNodes2(0.01,b,newNbOfNodes); + CPPUNIT_ASSERT_EQUAL(9,m3->getNumberOfNodes()); + const double expected1[18]={-0.299,-0.3, 0.201,-0.3, 0.701,-0.3, -0.299,0.2, 0.201,0.2, 0.701,0.2, -0.299,0.7, 0.201,0.7, 0.701,0.7}; + for(int i=0;i<18;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],m3->getCoords()->getIJ(0,i),1e-13); + // + da->decrRef(); + m3->decrRef(); + m1->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest::testMergeField2() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setMesh(m); + DataArrayDouble *arr=DataArrayDouble::New(); + arr->alloc(5,2); + arr->fillWithValue(2.); + f1->setArray(arr); + arr->decrRef(); + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f2->setMesh(m); + arr=DataArrayDouble::New(); + arr->alloc(5,2); + arr->fillWithValue(5.); + f2->setArray(arr); + arr->decrRef(); + MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f3->setMesh(m); + arr=DataArrayDouble::New(); + arr->alloc(5,2); + arr->fillWithValue(7.); + f3->setArray(arr); + arr->decrRef(); + // + std::vector tmp(3); + tmp[0]=f1; tmp[1]=f2; tmp[2]=f3; + MEDCouplingFieldDouble *f4=MEDCouplingFieldDouble::mergeFields(tmp); + CPPUNIT_ASSERT_EQUAL(15,f4->getMesh()->getNumberOfCells()); + const double expected1[30]={2.,2.,2.,2.,2.,2.,2.,2.,2.,2., 5.,5.,5.,5.,5.,5.,5.,5.,5.,5., 7.,7.,7.,7.,7.,7.,7.,7.,7.,7.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f4->getIJ(0,i),1.e-13); + // + f4->decrRef(); + f1->decrRef(); + f2->decrRef(); + f3->decrRef(); + m->decrRef(); +} -- 2.39.2