X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingCMesh.cxx;h=d1a1171f02390b05ae6fa85802301cf4e5ff894e;hb=90b7c9c73054965b8085ab0ecd2646a3d59f475a;hp=bd6233b93535f961bc25e89d36b22004632c7673;hpb=293a6104470482e450701aa8061d9b244f2057d5;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingCMesh.cxx b/src/MEDCoupling/MEDCouplingCMesh.cxx old mode 100644 new mode 100755 index bd6233b93..d1a1171f0 --- a/src/MEDCoupling/MEDCouplingCMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCMesh.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2020 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -19,35 +19,37 @@ // Author : Anthony Geay (CEA/DEN) #include "MEDCouplingCMesh.hxx" -#include "MEDCouplingUMesh.hxx" #include "MEDCouplingMemArray.hxx" #include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingCurveLinearMesh.hxx" + +#include "InterpKernelAutoPtr.hxx" #include #include #include #include -using namespace ParaMEDMEM; +using namespace MEDCoupling; MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0) { } -MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingMesh(other) +MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCpy):MEDCouplingStructuredMesh(other,deepCpy) { - if(deepCopy) + if(deepCpy) { if(other._x_array) - _x_array=other._x_array->deepCpy(); + _x_array=other._x_array->deepCopy(); else _x_array=0; if(other._y_array) - _y_array=other._y_array->deepCpy(); + _y_array=other._y_array->deepCopy(); else _y_array=0; if(other._z_array) - _z_array=other._z_array->deepCpy(); + _z_array=other._z_array->deepCopy(); else _z_array=0; } @@ -80,14 +82,14 @@ MEDCouplingCMesh *MEDCouplingCMesh::New() return new MEDCouplingCMesh; } -MEDCouplingCMesh *MEDCouplingCMesh::New(const char *meshName) +MEDCouplingCMesh *MEDCouplingCMesh::New(const std::string& meshName) { - MEDCouplingCMesh *ret=new MEDCouplingCMesh; + MEDCouplingCMesh *ret(new MEDCouplingCMesh); ret->setName(meshName); return ret; } -MEDCouplingMesh *MEDCouplingCMesh::deepCpy() const +MEDCouplingCMesh *MEDCouplingCMesh::deepCopy() const { return clone(true); } @@ -97,6 +99,25 @@ MEDCouplingCMesh *MEDCouplingCMesh::clone(bool recDeepCpy) const return new MEDCouplingCMesh(*this,recDeepCpy); } +const DataArrayDouble *MEDCouplingCMesh::getDirectAccessOfCoordsArrIfInStructure() const +{ + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getDirectAccessOfCoordsArrIfInStructure : MEDCouplingCMesh does not aggregate array of coordinates !"); +} + +MEDCouplingCurveLinearMesh *MEDCouplingCMesh::buildCurveLinear() const +{ + checkConsistencyLight(); + std::size_t dim(getSpaceDimension()); + MCAuto ret(MEDCouplingCurveLinearMesh::New()); + ret->MEDCouplingStructuredMesh::operator=(*this); + INTERP_KERNEL::AutoPtr ngs(new mcIdType[dim]); + getNodeGridStructure(ngs); + ret->setNodeGridStructure(ngs,ngs+dim); + MCAuto coo(getCoordinatesAndOwner()); + ret->setCoords(coo); + return ret.retn(); +} + void MEDCouplingCMesh::updateTime() const { if(_x_array) @@ -107,16 +128,30 @@ void MEDCouplingCMesh::updateTime() const updateTimeWith(*_z_array); } +std::size_t MEDCouplingCMesh::getHeapMemorySizeWithoutChildren() const +{ + return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren(); +} + +std::vector MEDCouplingCMesh::getDirectChildrenWithNull() const +{ + std::vector ret; + ret.push_back(_x_array); + ret.push_back(_y_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) -{ - const MEDCouplingCMesh *otherC=dynamic_cast(other); +void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) +{ + MEDCouplingStructuredMesh::copyTinyStringsFrom(other); + const MEDCouplingCMesh *otherC(dynamic_cast(other)); if(!otherC) throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !"); - MEDCouplingMesh::copyTinyStringsFrom(other); if(_x_array && otherC->_x_array) _x_array->copyStringInfoFrom(*otherC->_x_array); if(_y_array && otherC->_y_array) @@ -125,7 +160,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 !"); @@ -135,7 +170,7 @@ bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec reason="mesh given in input is not castable in MEDCouplingCMesh !"; return false; } - if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason)) + if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason)) return false; const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array}; @@ -178,29 +213,29 @@ bool MEDCouplingCMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other } void MEDCouplingCMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) + DataArrayIdType *&cellCor, DataArrayIdType *&nodeCor) const { if(!isEqualWithoutConsideringStr(other,prec)) throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalWith : Meshes are not the same !"); } /*! - * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingCMesh instance too). - * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingCMesh, 'this' and 'other' are the same ! + * Nothing is done here (except to check that the other is a MEDCoupling::MEDCouplingCMesh instance too). + * The user intend that the nodes are the same, so by construction of MEDCoupling::MEDCouplingCMesh, \a this and \a other are the same ! */ void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) + DataArrayIdType *&cellCor) const { - const MEDCouplingCMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : other is NOT a cartesian mesh ! Impossible to check equivalence !"); + if(!isEqualWithoutConsideringStr(other,prec)) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !"); } -void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) +void MEDCouplingCMesh::checkConsistencyLight() 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) @@ -226,7 +261,6 @@ void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) std::ostringstream os; os << msg0 << 'Y' << msg2; throw INTERP_KERNEL::Exception(os.str().c_str()); } - } if(_z_array) { @@ -243,9 +277,9 @@ void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) } } -void MEDCouplingCMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception) +void MEDCouplingCMesh::checkConsistency(double eps) const { - checkCoherency(); + checkConsistencyLight(); if(_x_array) _x_array->checkMonotonic(true, eps); if(_y_array) @@ -254,200 +288,80 @@ 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::getNodeGridStructure(mcIdType *res) const { - checkCoherency1(eps); -} - -int MEDCouplingCMesh::getNumberOfCells() const -{ - int ret=1; - if(_x_array) - ret*=_x_array->getNbOfElems()-1; - if(_y_array) - ret*=_y_array->getNbOfElems()-1; - if(_z_array) - ret*=_z_array->getNbOfElems()-1; - return ret; + std::vector ret(getNodeGridStructure()); + std::copy(ret.begin(),ret.end(),res); } -int MEDCouplingCMesh::getNumberOfNodes() const +std::vector MEDCouplingCMesh::getNodeGridStructure() const { - int ret=1; + static const char MSG[]="MEDCouplingCMesh::getNodeGridStructure : mesh is invalid ! null vectors (X, Y or Z) must be put contiguously at the end !"; + std::vector ret; + bool isOK(true); if(_x_array) - ret*=_x_array->getNbOfElems(); - if(_y_array) - ret*=_y_array->getNbOfElems(); - if(_z_array) - ret*=_z_array->getNbOfElems(); - return ret; -} - -void MEDCouplingCMesh::getSplitCellValues(int *res) const -{ - int spaceDim=getSpaceDimension(); - for(int l=0;lgetNbOfElems()-1; - res[spaceDim-l-1]=val; - } -} - -void MEDCouplingCMesh::getSplitNodeValues(int *res) const -{ - int spaceDim=getSpaceDimension(); - for(int l=0;lgetNbOfElems(); - res[spaceDim-l-1]=val; + if(!_x_array->isAllocated() || _x_array->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : X array exits but it is not allocated or with nb of components equal to one !"); + ret.push_back(_x_array->getNumberOfTuples()); } -} - -int MEDCouplingCMesh::getCellIdFromPos(int i, int j, int k) const -{ - int tmp[3]={i,j,k}; - int tmp2[3]; - int spaceDim=getSpaceDimension(); - getSplitCellValues(tmp2); - std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies()); - return std::accumulate(tmp,tmp+spaceDim,0); -} - -int MEDCouplingCMesh::getNodeIdFromPos(int i, int j, int k) const -{ - int tmp[3]={i,j,k}; - int tmp2[3]; - int spaceDim=getSpaceDimension(); - getSplitNodeValues(tmp2); - std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies()); - return std::accumulate(tmp,tmp+spaceDim,0); -} - -void MEDCouplingCMesh::GetPosFromId(int nodeId, int spaceDim, const int *split, int *res) -{ - int work=nodeId; - for(int i=spaceDim-1;i>=0;i--) + else + isOK=false; + if(_y_array) { - int pos=work/split[i]; - work=work%split[i]; - res[i]=pos; + if(!_y_array->isAllocated() || _y_array->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Y array exits but it is not allocated or with nb of components equal to one !"); + if(!isOK) + throw INTERP_KERNEL::Exception(MSG); + ret.push_back(_y_array->getNumberOfTuples()); } -} - -int MEDCouplingCMesh::getSpaceDimension() const -{ - int ret=0; - if(_x_array) - ret++; - if(_y_array) - ret++; + else + isOK=false; if(_z_array) - ret++; - return ret; -} - -int MEDCouplingCMesh::getMeshDimension() const -{ - return getSpaceDimension(); -} - -INTERP_KERNEL::NormalizedCellType MEDCouplingCMesh::getTypeOfCell(int cellId) const -{ - switch(getMeshDimension()) { - case 3: - return INTERP_KERNEL::NORM_HEXA8; - case 2: - return INTERP_KERNEL::NORM_QUAD4; - case 1: - return INTERP_KERNEL::NORM_SEG2; - default: - throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !"); + if(!_z_array->isAllocated() || _z_array->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Z array exits but it is not allocated or with nb of components equal to one !"); + if(!isOK) + throw INTERP_KERNEL::Exception(MSG); + ret.push_back(_z_array->getNumberOfTuples()); } + return ret; } -std::set MEDCouplingCMesh::getAllGeoTypes() const +MEDCouplingStructuredMesh *MEDCouplingCMesh::buildStructuredSubPart(const std::vector< std::pair >& cellPart) const { - INTERP_KERNEL::NormalizedCellType ret; - switch(getMeshDimension()) + checkConsistencyLight(); + int dim(getSpaceDimension()); + if(dim!=ToIdType(cellPart.size())) { - case 3: - ret=INTERP_KERNEL::NORM_HEXA8; - break; - case 2: - ret=INTERP_KERNEL::NORM_QUAD4; - break; - case 1: - ret=INTERP_KERNEL::NORM_SEG2; - break; - default: - throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getAllGeoTypes !"); + std::ostringstream oss; oss << "MEDCouplingCMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - std::set ret2; - ret2.insert(ret); - return ret2; -} - -int MEDCouplingCMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - int ret=getNumberOfCells(); - int dim=getMeshDimension(); - switch(type) + MCAuto ret(dynamic_cast(deepCopy())); + for(int i=0;i tmp(ret->getCoordsAt(i)->selectByTupleIdSafeSlice(cellPart[i].first,cellPart[i].second+1,1)); + ret->setCoordsAt(i,tmp); } - return 0; + return ret.retn(); } -void MEDCouplingCMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const +/*! + * 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 contiguously at the end. For example X!=0,Y==0,Z!=0 will throw. + */ +int MEDCouplingCMesh::getSpaceDimension() const { - int spaceDim=getSpaceDimension(); - int tmpCell[3],tmpNode[3]; - getSplitCellValues(tmpCell); - getSplitNodeValues(tmpNode); - int tmp2[3]; - GetPosFromId(cellId,spaceDim,tmpCell,tmp2); - switch(spaceDim) - { - case 1: - conn.push_back(tmp2[0]); conn.push_back(tmp2[0]+1); - break; - case 2: - conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1); - conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]+1); conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]); - break; - case 3: - conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); - conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]); - conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); - conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeIdsOfCell : big problem spacedim must be in 1,2 or 3 !"); - }; + return (int)getNodeGridStructure().size(); } -void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception) +void MEDCouplingCMesh::getCoordinatesOfNode(mcIdType nodeId, std::vector& coo) const { - int tmp[3]; + mcIdType tmp[3]; int spaceDim=getSpaceDimension(); getSplitNodeValues(tmp); const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; - int tmp2[3]; + mcIdType tmp2[3]; GetPosFromId(nodeId,spaceDim,tmp,tmp2); for(int j=0;j + * \ref py_mccmesh_getCoordsAt "Here is a Python example". + * \endif + */ +const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const { switch(i) - { + { case 0: return _x_array; case 1: @@ -499,13 +426,26 @@ const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_K return _z_array; default: throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); - } + } } -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]. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".
+ * \ref py_mccmesh_getCoordsAt "Here is a Python example". + * \endif + */ +DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) { switch(i) - { + { case 0: return _x_array; case 1: @@ -514,11 +454,27 @@ DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) throw(INTERP_KERNEL::Excep return _z_array; default: throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); - } + } } -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]. + * + * \if ENABLE_EXAMPLES + * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".
+ * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". + * \endif + */ +void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) { + if(arr) + arr->checkNbOfComps(1,"MEDCouplingCMesh::setCoordsAt"); DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array}; if(i<0 || i>2) throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); @@ -533,8 +489,31 @@ 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. + * + * \if ENABLE_EXAMPLES + * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".
+ * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". + * \endif + */ void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ) { + if(coordsX) + coordsX->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsX"); + if(coordsY) + coordsY->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsY"); + if(coordsZ) + coordsZ->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsZ"); if(_x_array) _x_array->decrRef(); _x_array=const_cast(coordsX); @@ -553,107 +532,6 @@ void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArray declareAsNew(); } -/*! - * See MEDCouplingUMesh::getDistributionOfTypes for more information - */ -std::vector MEDCouplingCMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception) -{ - //only one type of cell - std::vector ret(3); - ret[0]=getTypeOfCell(0); - ret[1]=getNumberOfCells(); - ret[2]=0; //ret[3*k+2]==0 because it has no sense here - return ret; -} - -/*! - * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information - */ -DataArrayInt *MEDCouplingCMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) -{ - if(code.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code is empty, should not !"); - std::size_t sz=code.size(); - if(sz!=3) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code should be of size 3 exactly !"); - - int nbCells=getNumberOfCellsWithType((INTERP_KERNEL::NormalizedCellType)code[0]); - if(code[2]==-1) - { - if(code[1]==nbCells) - return 0; - else - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : number of cells mismatch !"); - } - else - { - if(code[2]<-1) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]<-1 mismatch !"); - if(code[2]>=(int)idsPerType.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]>size idsPerType !"); - return idsPerType[code[2]]->deepCpy(); - } -} - -/*! - * See MEDCouplingUMesh::splitProfilePerType for more information - */ -void MEDCouplingCMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) -{ - int nbCells=getNumberOfCells(); - code.resize(3); - code[0]=(int)getTypeOfCell(0); - code[1]=nbCells; - code[2]=0; - idsInPflPerType.push_back(profile->deepCpy()); - idsPerType.push_back(profile->deepCpy()); -} - -MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) -{ - int spaceDim=getSpaceDimension(); - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),spaceDim); - DataArrayDouble *coords=getCoordinatesAndOwner(); - ret->setCoords(coords); - coords->decrRef(); - switch(spaceDim) - { - case 1: - fill1DUnstructuredMesh(ret); - break; - case 2: - fill2DUnstructuredMesh(ret); - break; - case 3: - fill3DUnstructuredMesh(ret); - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::buildUnstructured : big problem spacedim must be in 1,2 or 3 !"); - }; - return ret; -} - -MEDCouplingMesh *MEDCouplingCMesh::buildPart(const int *start, const int *end) const -{ - MEDCouplingUMesh *um=buildUnstructured(); - MEDCouplingMesh *ret=um->buildPart(start,end); - um->decrRef(); - return ret; -} - -MEDCouplingMesh *MEDCouplingCMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const -{ - MEDCouplingUMesh *um=buildUnstructured(); - MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr); - um->decrRef(); - return ret; -} - -DataArrayInt *MEDCouplingCMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception) -{ - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::simplexize : not available for Cartesian mesh !"); -} - void MEDCouplingCMesh::getBoundingBox(double *bbox) const { int dim=getSpaceDimension(); @@ -664,7 +542,7 @@ void MEDCouplingCMesh::getBoundingBox(double *bbox) const if(c) { const double *coords=c->getConstPointer(); - int nb=c->getNbOfElems(); + mcIdType nb=ToIdType(c->getNbOfElems()); bbox[2*j]=coords[0]; bbox[2*j+1]=coords[nb-1]; j++; @@ -672,29 +550,41 @@ 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); - field->setName(name.c_str()); + mcIdType nbelem=ToIdType(getNumberOfCells()); + MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + field->setName(name); DataArrayDouble* array=DataArrayDouble::New(); array->alloc(nbelem,1); double *area_vol=array->getPointer(); field->setArray(array) ; array->decrRef(); field->setMesh(const_cast(this)); - int tmp[3]; + field->synchronizeTimeWithMesh(); + mcIdType tmp[3]; getSplitCellValues(tmp); int dim=getSpaceDimension(); const double **thisArr=new const double *[dim]; const DataArrayDouble *thisArr2[3]={_x_array,_y_array,_z_array}; for(int i=0;igetConstPointer(); - for(int icell=0;icellalloc(nbOfCells,3); - double *vals=array->getPointer(); - for(int i=0;isetArray(array); - array->decrRef(); - ret->setMesh(this); - return ret; -} - -int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const +mcIdType MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const { int dim=getSpaceDimension(); - int ret=0; - int coeff=1; + mcIdType ret=0; + mcIdType coeff=1; for(int i=0;igetConstPointer(); - int nbOfNodes=getCoordsAt(i)->getNbOfElems(); + mcIdType nbOfNodes=getCoordsAt(i)->getNbOfElems(); double ref=pos[i]; const double *w=std::find_if(d,d+nbOfNodes,std::bind2nd(std::greater_equal(),ref)); - int w2=(int)std::distance(d,w); + mcIdType w2=ToIdType(std::distance(d,w)); if(w2& elts) const +{ + mcIdType ret(getCellContainingPoint(pos,eps)); + elts.push_back(ret); +} + void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle) { - throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to StructuredMesh to apply it !"); + throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to untructured mesh 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) @@ -778,6 +663,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++) @@ -786,7 +677,7 @@ void MEDCouplingCMesh::scale(const double *point, double factor) if(c) { double *coords=c->getPointer(); - int lgth=c->getNbOfElems(); + mcIdType lgth=ToIdType(c->getNbOfElems()); std::transform(coords,coords+lgth,coords,std::bind2nd(std::minus(),point[i])); std::transform(coords,coords+lgth,coords,std::bind2nd(std::multiplies(),factor)); std::transform(coords,coords+lgth,coords,std::bind2nd(std::plus(),point[i])); @@ -802,53 +693,68 @@ 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(); - int spaceDim=getSpaceDimension(); - int nbNodes=getNumberOfNodes(); + MCAuto ret(DataArrayDouble::New()); + int spaceDim(getSpaceDimension()); + mcIdType nbNodes(getNumberOfNodes()); ret->alloc(nbNodes,spaceDim); - double *pt=ret->getPointer(); - int tmp[3]; + double *pt(ret->getPointer()); + mcIdType tmp[3]; getSplitNodeValues(tmp); const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; const double *tabsPtr[3]; - 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::computeCellCenterOfMass() const { DataArrayDouble *ret=DataArrayDouble::New(); int spaceDim=getSpaceDimension(); - int nbCells=getNumberOfCells(); + mcIdType nbCells=ToIdType(getNumberOfCells()); ret->alloc(nbCells,spaceDim); double *pt=ret->getPointer(); - int tmp[3]; + mcIdType tmp[3]; getSplitCellValues(tmp); const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; std::vector tabsPtr[3]; for(int j=0;jgetNbOfElems()-1; - ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0).c_str()); + mcIdType sz=tabs[j]->getNbOfElems()-1; + 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()); std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),tabsPtr[j].begin(),std::bind2nd(std::multiplies(),0.5)); } - int tmp2[3]; + mcIdType tmp2[3]; for(int i=0;igetNbOfElems()-1; - DataArrayInt *connI=DataArrayInt::New(); - connI->alloc(nbOfCells+1,1); - int *ci=connI->getPointer(); - DataArrayInt *conn=DataArrayInt::New(); - conn->alloc(3*nbOfCells,1); - ci[0]=0; - int *cp=conn->getPointer(); - for(int i=0;isetConnectivity(conn,connI,true); - conn->decrRef(); - connI->decrRef(); + return MEDCouplingCMesh::computeCellCenterOfMass(); } -void MEDCouplingCMesh::fill2DUnstructuredMesh(MEDCouplingUMesh *m) const +void MEDCouplingCMesh::renumberCells(const mcIdType *old2NewBg, bool check) { - const DataArrayDouble *c1=getCoordsAt(0); - const DataArrayDouble *c2=getCoordsAt(1); - int n1=c1->getNbOfElems()-1; - int n2=c2->getNbOfElems()-1; - DataArrayInt *connI=DataArrayInt::New(); - connI->alloc(n1*n2+1,1); - int *ci=connI->getPointer(); - DataArrayInt *conn=DataArrayInt::New(); - conn->alloc(5*n1*n2,1); - ci[0]=0; - int *cp=conn->getPointer(); - int pos=0; - for(int j=0;jsetConnectivity(conn,connI,true); - conn->decrRef(); - connI->decrRef(); + throw INTERP_KERNEL::Exception("Functionality of renumbering cell not available for CMesh !"); } -void MEDCouplingCMesh::fill3DUnstructuredMesh(MEDCouplingUMesh *m) const -{ - const DataArrayDouble *c1=getCoordsAt(0); - const DataArrayDouble *c2=getCoordsAt(1); - const DataArrayDouble *c3=getCoordsAt(2); - int n1=c1->getNbOfElems()-1; - int n2=c2->getNbOfElems()-1; - int n3=c3->getNbOfElems()-1; - DataArrayInt *connI=DataArrayInt::New(); - connI->alloc(n1*n2*n3+1,1); - int *ci=connI->getPointer(); - DataArrayInt *conn=DataArrayInt::New(); - conn->alloc(9*n1*n2*n3,1); - ci[0]=0; - int *cp=conn->getPointer(); - int pos=0; - for(int k=0;ksetConnectivity(conn,connI,true); - conn->decrRef(); - connI->decrRef(); -} - -void MEDCouplingCMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const +void MEDCouplingCMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const { int it,order; double time=getTime(it,order); @@ -965,7 +787,7 @@ void MEDCouplingCMesh::getTinySerializationInformation(std::vector& tiny const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; for(int i=0;i<3;i++) { - int val=-1; + mcIdType val=-1; std::string st; if(thisArr[i]) { @@ -980,22 +802,22 @@ void MEDCouplingCMesh::getTinySerializationInformation(std::vector& tiny tinyInfoD.push_back(time); } -void MEDCouplingCMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const +void MEDCouplingCMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayIdType *a1, DataArrayDouble *a2, std::vector& littleStrings) const { a1->alloc(0,1); - int sum=0; + mcIdType sum=0; for(int i=0;i<3;i++) if(tinyInfo[i]!=-1) sum+=tinyInfo[i]; a2->alloc(sum,1); } -void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const +void MEDCouplingCMesh::serialize(DataArrayIdType *&a1, DataArrayDouble *&a2) const { - a1=DataArrayInt::New(); + a1=DataArrayIdType::New(); a1->alloc(0,1); const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; - int sz=0; + mcIdType sz=0; for(int i=0;i<3;i++) { if(thisArr[i]) @@ -1009,12 +831,12 @@ void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const a2Ptr=std::copy(thisArr[i]->getConstPointer(),thisArr[i]->getConstPointer()+thisArr[i]->getNumberOfTuples(),a2Ptr); } -void MEDCouplingCMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, +void MEDCouplingCMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayIdType *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++) @@ -1023,20 +845,102 @@ 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]; } } - setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]); + setTime(tinyInfoD[0],FromIdType(tinyInfo[3]),FromIdType(tinyInfo[4])); +} + +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}; + for(int i=0;i<3;i++) + { + if(thisArr[i]) + { extent << "0 " << thisArr[i]->getNumberOfTuples()-1 << " "; } + else + { extent << "0 0 "; } + } + ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n"; + ofs << " \n"; + ofs << " \n" << pointData << std::endl; + ofs << " \n"; + ofs << " \n" << cellData << std::endl; + ofs << " \n"; + ofs << " \n"; + for(int i=0;i<3;i++) + { + if(thisArr[i]) + thisArr[i]->writeVTK(ofs,8,"Array",byteData); + else + { + MCAuto coo=DataArrayDouble::New(); coo->alloc(1,1); + coo->setIJ(0,0,0.); + coo->writeVTK(ofs,8,"Array",byteData); + } + } + ofs << " \n"; + ofs << " \n"; + ofs << " \n"; +} + +void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const +{ + 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]; + mcIdType nbOfCells=1,nbOfNodes=1; + for(int i=0;i<3;i++) + { + isDef[i]=thisArr[i]!=0; + if(isDef[i]) + { + char tmp=(char)((int)('X')+i); + stream2[i] << tmp << " positions array "; + if(!thisArr[i]->isAllocated()) + stream2[i] << "set but not allocated."; + else + { + std::size_t nbCompo=thisArr[i]->getNumberOfComponents(); + if(nbCompo==1) + { + mcIdType 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(); + } } -void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception) +std::string MEDCouplingCMesh::getVTKFileExtension() const { - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::writeVTKLL : not implemented yet !"); + return std::string("vtr"); } -std::string MEDCouplingCMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception) +std::string MEDCouplingCMesh::getVTKDataSetType() const { return std::string("RectilinearGrid"); }