X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingCMesh.cxx;h=b928c5d87e04d424e7c33e035daccf61d74f14cb;hb=0c9d48870957c4a9f6f82fc8e2c569780a5f886b;hp=2e6cab4e9122977e6e905f9134e6594283181d6c;hpb=97e267c35d896c3c401989a4a165087c3bebd708;p=modules%2Fmed.git diff --git a/src/MEDCoupling/MEDCouplingCMesh.cxx b/src/MEDCoupling/MEDCouplingCMesh.cxx index 2e6cab4e9..b928c5d87 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCMesh.cxx @@ -79,7 +79,7 @@ MEDCouplingCMesh *MEDCouplingCMesh::New() return new MEDCouplingCMesh; } -MEDCouplingCMesh *MEDCouplingCMesh::New(const char *meshName) +MEDCouplingCMesh *MEDCouplingCMesh::New(const std::string& meshName) { MEDCouplingCMesh *ret=new MEDCouplingCMesh; ret->setName(meshName); @@ -106,23 +106,28 @@ void MEDCouplingCMesh::updateTime() const updateTimeWith(*_z_array); } -std::size_t MEDCouplingCMesh::getHeapMemorySize() const +std::size_t MEDCouplingCMesh::getHeapMemorySizeWithoutChildren() const { - std::size_t ret=0; - std::set s; - s.insert(_x_array); s.insert(_y_array); s.insert(_z_array); - s.erase(NULL); - for(std::set::const_iterator it=s.begin();it!=s.end();it++) - if(*it) - ret+=(*it)->getHeapMemorySize(); - return MEDCouplingStructuredMesh::getHeapMemorySize()+ret; + return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren(); +} + +std::vector MEDCouplingCMesh::getDirectChildren() const +{ + std::vector ret; + if(_x_array) + ret.push_back(_x_array); + if(_y_array) + ret.push_back(_y_array); + if(_z_array) + ret.push_back(_z_array); + return ret; } /*! * This method copyies all tiny strings from other (name and components name). * @throw if other and this have not same mesh type. */ -void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) +void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) { const MEDCouplingCMesh *otherC=dynamic_cast(other); if(!otherC) @@ -136,7 +141,7 @@ void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(I _z_array->copyStringInfoFrom(*otherC->_z_array); } -bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) +bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const { if(!other) throw INTERP_KERNEL::Exception("MEDCouplingCMesh::isEqualIfNotWhy : input other pointer is null !"); @@ -207,11 +212,12 @@ void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *ot throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : other is NOT a cartesian mesh ! Impossible to check equivalence !"); } -void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) +void MEDCouplingCMesh::checkCoherency() const { const char msg0[]="Invalid "; const char msg1[]=" array ! Must contain more than 1 element."; const char msg2[]=" array ! Must be with only one component."; + getSpaceDimension();// here to check that no holes in arrays ! if(_x_array) { if(_x_array->getNbOfElems()<2) @@ -254,7 +260,7 @@ void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) } } -void MEDCouplingCMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception) +void MEDCouplingCMesh::checkCoherency1(double eps) const { checkCoherency(); if(_x_array) @@ -265,7 +271,7 @@ void MEDCouplingCMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Ex _z_array->checkMonotonic(true, eps); } -void MEDCouplingCMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception) +void MEDCouplingCMesh::checkCoherency2(double eps) const { checkCoherency1(eps); } @@ -296,19 +302,19 @@ int MEDCouplingCMesh::getNumberOfNodes() const void MEDCouplingCMesh::getSplitCellValues(int *res) const { - int spaceDim=getSpaceDimension(); - for(int l=0;lgetNbOfElems()-1; - res[spaceDim-l-1]=val; + res[meshDim-l-1]=val; } } void MEDCouplingCMesh::getSplitNodeValues(int *res) const { - int spaceDim=getSpaceDimension(); + int spaceDim(getSpaceDimension()); for(int l=0;lgetNbOfElems(); } +std::vector MEDCouplingCMesh::getNodeGridStructure() const +{ + std::vector ret(getSpaceDimension()); + getNodeGridStructure(&ret[0]); + return ret; +} + +MEDCouplingStructuredMesh *MEDCouplingCMesh::buildStructuredSubPart(const std::vector< std::pair >& cellPart) const +{ + checkCoherency(); + int dim(getMeshDimension()); + if(dim!=(int)cellPart.size()) + { + std::ostringstream oss; oss << "MEDCouplingCMesh::buildStructuredSubPart : the mesh dimension is " << dim << " and cell part size is " << cellPart.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr ret(dynamic_cast(deepCpy())); + for(int i=0;i tmp(ret->getCoordsAt(i)->selectByTupleId2(cellPart[i].first,cellPart[i].second+1,1)); + ret->setCoordsAt(i,tmp); + } + return ret.retn(); +} + +/*! + * Return the space dimension of \a this. It only considers the arrays along X, Y and Z to deduce that. + * This method throws exceptions if the not null arrays defining this are not contiguouly at the end. For example X!=0,Y==0,Z!=0 will throw. + */ int MEDCouplingCMesh::getSpaceDimension() const { - int ret=0; + static const char MSG[]="MEDCouplingCMesh::getSpaceDimension : mesh is invalid ! null vectors (X, Y or Z) must be put contiguously at the end !"; + int ret(0); + bool isOK(true); if(_x_array) ret++; + else + isOK=false; if(_y_array) - ret++; + { + if(!isOK) + throw INTERP_KERNEL::Exception(MSG); + ret++; + } + else + isOK=false; if(_z_array) - ret++; + { + if(!isOK) + throw INTERP_KERNEL::Exception(MSG); + ret++; + } return ret; } +/*! + * This method returns the mesh dimension of \a this. It can be different from space dimension in case of a not null dimension contains only one node. + */ int MEDCouplingCMesh::getMeshDimension() const { - return getSpaceDimension(); + int ret(getSpaceDimension()); + if(_x_array) + { + if(_x_array->isAllocated()) + if(_x_array->getNumberOfTuples()==1) + ret--; + } + if(_y_array) + { + if(_y_array->isAllocated()) + if(_y_array->getNumberOfTuples()==1) + ret--; + } + if(_z_array) + { + if(_z_array->isAllocated()) + if(_z_array->getNumberOfTuples()==1) + ret--; + } + return ret; } -void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception) +void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const { int tmp[3]; int spaceDim=getSpaceDimension(); @@ -388,7 +459,18 @@ std::string MEDCouplingCMesh::advancedRepr() const return simpleRepr(); } -const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_KERNEL::Exception) +/*! + * Returns a DataArrayDouble holding positions of nodes along a given axis. + * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage. + * \param [in] i - an index of axis, a value from [0,1,2]. + * \return const DataArrayDouble * - a pointer to the data array of node coordinates + * referred by \a this mesh. + * \throw If \a i is not one of [0,1,2]. + * + * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".
+ * \ref py_mccmesh_getCoordsAt "Here is a Python example". + */ +const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const { switch(i) { @@ -403,7 +485,18 @@ const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_K } } -DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) throw(INTERP_KERNEL::Exception) +/*! + * Returns a DataArrayDouble holding positions of nodes along a given axis. + * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage. + * \param [in] i - an index of axis, a value from [0,1,2]. + * \return const DataArrayDouble * - a pointer to the data array of node coordinates + * referred by \a this mesh. + * \throw If \a i is not one of [0,1,2]. + * + * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".
+ * \ref py_mccmesh_getCoordsAt "Here is a Python example". + */ +DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) { switch(i) { @@ -418,7 +511,19 @@ DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) throw(INTERP_KERNEL::Excep } } -void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception) +/*! + * Sets node coordinates along a given axis. For more info on Cartesian meshes, see + * \ref MEDCouplingCMeshPage. + * \param [in] i - an index of axis, a value in range [0,1,2]. + * \param [in] arr - DataArrayDouble holding positions of nodes along the i-th + * axis. It must be an array of one component. + * \throw If \a arr->getNumberOfComponents() != 1. + * \throw If \a i is not one of [0,1,2]. + * + * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".
+ * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". + */ +void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) { if(arr) arr->checkNbOfComps(1,"MEDCouplingCMesh::setCoordsAt"); @@ -436,6 +541,21 @@ void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) throw(INTE } } +/*! + * Sets node coordinates along some of the tree axes. This method updates all the + * three node coordinates arrays at once. For more info on Cartesian meshes, see + * \ref MEDCouplingCMeshPage. + * \param [in] coordsX - DataArrayDouble holding positions of nodes along the X + * axis. It must be an array of one component or \c NULL. + * \param [in] coordsY - DataArrayDouble holding positions of nodes along the Y + * axis. It must be an array of one component or \c NULL. + * \param [in] coordsZ - DataArrayDouble holding positions of nodes along the Z + * axis. It must be an array of one component or \c NULL. + * \throw If \a coords*->getNumberOfComponents() != 1. + * + * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".
+ * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". + */ void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ) { if(coordsX) @@ -480,13 +600,24 @@ void MEDCouplingCMesh::getBoundingBox(double *bbox) const } } +/*! + * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this + * mesh.
+ * For 1D cells, the returned field contains lengths.
+ * For 2D cells, the returned field contains areas.
+ * For 3D cells, the returned field contains volumes. + * \param [in] isAbs - a not used parameter. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells + * and one time . The caller is to delete this field using decrRef() as it is no + * more needed. + */ MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const { std::string name="MeasureOfMesh_"; name+=getName(); int nbelem=getNumberOfCells(); MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - field->setName(name.c_str()); + field->setName(name); DataArrayDouble* array=DataArrayDouble::New(); array->alloc(nbelem,1); double *area_vol=array->getPointer(); @@ -557,6 +688,12 @@ void MEDCouplingCMesh::rotate(const double *center, const double *vector, double throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to StructuredMesh to apply it !"); } +/*! + * Translates all nodes of \a this mesh by a given vector. Actually, it adds each + * component of the \a vector to all node coordinates of a corresponding axis. + * \param [in] vector - the translation vector whose size must be not less than \a + * this->getSpaceDimension(). + */ void MEDCouplingCMesh::translate(const double *vector) { if(_x_array) @@ -570,6 +707,12 @@ void MEDCouplingCMesh::translate(const double *vector) _z_array->getPointer(),std::bind2nd(std::plus(),vector[2])); } +/*! + * Applies scaling transformation to all nodes of \a this mesh. + * \param [in] point - coordinates of a scaling center. This array is to be of + * size \a this->getSpaceDimension() at least. + * \param [in] factor - a scale factor. + */ void MEDCouplingCMesh::scale(const double *point, double factor) { for(int i=0;i<3;i++) @@ -594,6 +737,13 @@ MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other) return 0; } +/*! + * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh. + * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a + * this->getNumberOfNodes() tuples per \a this->getSpaceDimension() + * components. The caller is to delete this array using decrRef() as it is + * no more needed. + */ DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const { DataArrayDouble *ret=DataArrayDouble::New(); @@ -608,7 +758,7 @@ DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const for(int j=0;jgetConstPointer(); - ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0).c_str()); + ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0)); } int tmp2[3]; for(int i=0;igetNumberOfCells() tuples per \a this->getSpaceDimension() + * components. The caller is to delete this array using decrRef() as it is + * no more needed. + */ DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const { DataArrayDouble *ret=DataArrayDouble::New(); @@ -634,7 +792,7 @@ DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const for(int j=0;jgetNbOfElems()-1; - ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0).c_str()); + ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0)); const double *srcPtr=tabs[j]->getConstPointer(); tabsPtr[j].insert(tabsPtr[j].end(),srcPtr,srcPtr+sz); std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),srcPtr+1,tabsPtr[j].begin(),std::plus()); @@ -650,12 +808,12 @@ DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const return ret; } -DataArrayDouble *MEDCouplingCMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception) +DataArrayDouble *MEDCouplingCMesh::computeIsoBarycenterOfNodesPerCell() const { return MEDCouplingCMesh::getBarycenterAndOwner(); } -void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check) { throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !"); } @@ -720,9 +878,9 @@ void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const void MEDCouplingCMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) { - setName(littleStrings[0].c_str()); - setDescription(littleStrings[1].c_str()); - setTimeUnit(littleStrings[2].c_str()); + setName(littleStrings[0]); + setDescription(littleStrings[1]); + setTimeUnit(littleStrings[2]); DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array}; const double *data=a2->getConstPointer(); for(int i=0;i<3;i++) @@ -731,7 +889,7 @@ void MEDCouplingCMesh::unserialization(const std::vector& tinyInfoD, con { (*(thisArr[i]))=DataArrayDouble::New(); (*(thisArr[i]))->alloc(tinyInfo[i],1); - (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3].c_str()); + (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3]); std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer()); data+=tinyInfo[i]; } @@ -739,7 +897,7 @@ void MEDCouplingCMesh::unserialization(const std::vector& tinyInfoD, con setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]); } -void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception) +void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const { std::ostringstream extent; DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; @@ -760,12 +918,12 @@ void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData for(int i=0;i<3;i++) { if(thisArr[i]) - thisArr[i]->writeVTK(ofs,8,"Array"); + thisArr[i]->writeVTK(ofs,8,"Array",byteData); else { MEDCouplingAutoRefCountObjectPtr coo=DataArrayDouble::New(); coo->alloc(1,1); coo->setIJ(0,0,0.); - coo->writeVTK(ofs,8,"Array"); + coo->writeVTK(ofs,8,"Array",byteData); } } ofs << " \n"; @@ -773,12 +931,56 @@ void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData ofs << " \n"; } -void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const { - stream << "MEDCouplingCMesh C++ instance at " << this << "."; + stream << "MEDCouplingCMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; + const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; + std::ostringstream stream2[3]; + bool isDef[3]; + int nbOfCells=1,nbOfNodes=1; + for(int i=0;i<3;i++) + { + isDef[i]=thisArr[i]!=0; + if(isDef[i]) + { + char tmp='X'+i; + stream2[i] << tmp << " positions array "; + if(!thisArr[i]->isAllocated()) + stream2[i] << "set but not allocated."; + else + { + int nbCompo=thisArr[i]->getNumberOfComponents(); + if(nbCompo==1) + { + int nbTuples=thisArr[i]->getNumberOfTuples(); + if(nbTuples<1) + { stream2[i] << "set and allocated - WARNING number of elements < 1 !"; nbOfCells=-1; nbOfNodes=-1; } + else + { + stream2[i] << "(length=" << nbTuples << ")" << ": "; + thisArr[i]->reprQuickOverviewData(stream2[i],200); + if(nbOfCells!=-1) + { nbOfNodes*=nbTuples; nbOfCells*=nbTuples-1; } + } + } + else + { stream2[i] << "set and allocated - WARNING number of components != 1 !"; nbOfCells=-1; nbOfNodes=-1; } + } + } + } + if(!isDef[0] && !isDef[1] && !isDef[2]) + { stream << " No arrays set !"; return; } + if(nbOfCells>=0) + { stream << std::endl << "Number of cells : " << nbOfCells << ". Number of nodes : " << nbOfNodes << "."; } + for(int i=0;i<3;i++) + { + if(isDef[i]) + stream << std::endl << stream2[i].str(); + } + } -std::string MEDCouplingCMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception) +std::string MEDCouplingCMesh::getVTKDataSetType() const { return std::string("RectilinearGrid"); }