From: ageay Date: Mon, 19 Jul 2010 10:36:56 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: V5_1_main_FINAL~88 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=4d8725a34617bcb99b74df491b55fe3597a68906;p=tools%2Fmedcoupling.git *** empty log message *** --- diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index 74ed28ba8..b821fd2c8 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -386,6 +386,7 @@ void MEDCouplingPointSet::changeSpaceDimension(int newSpaceDim) throw(INTERP_KER newCoords->setInfoOnComponent(i,getCoords()->getInfoOnComponent(i).c_str()); setCoords(newCoords); newCoords->decrRef(); + updateTime(); } /*! diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index aa6504ff0..bb38037c7 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -1553,6 +1553,182 @@ void MEDCouplingUMesh::checkButterflyCells(std::vector& cells) const } } +/*! + * This method is \b NOT const because it can modify 'this'. + * 'this' is expected to be an unstructured mesh with meshDim==2 and spaceDim==3. If not an exception will be thrown. + * @param mesh1D is an unstructured mesh with MeshDim==1 and spaceDim==3. If not an exception will be thrown. + * @param policy specifies the type of extrusion chosen. \b 0 for translation (most simple), + * \b 1 for translation and rotation around point of 'mesh1D'. + * @return an unstructured mesh with meshDim==3 and spaceDim==3. The returned mesh has the same coords than 'this'. + */ +MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThis(const MEDCouplingUMesh *mesh1D, int policy) +{ + checkFullyDefined(); + mesh1D->checkFullyDefined(); + if(getMeshDimension()!=2 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid 'this' for buildExtrudedMeshFromThis method : must be meshDim==2 and spaceDim ==3 !"); + if(mesh1D->getMeshDimension()!=1 || mesh1D->getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid 'mesh1D' for buildExtrudedMeshFromThis method : must be meshDim==1 and spaceDim ==3 !"); + bool isQuad=false; + if(isPresenceOfQuadratic()) + { + if(mesh1D->isFullyQuadratic()) + isQuad=true; + else + throw INTERP_KERNEL::Exception("Invalid 2D mesh and 1D mesh because 2D mesh has quadratic cells and 1D is not fully quadratic !"); + } + zipCoords(); + int oldNbOfNodes=getNumberOfNodes(); + DataArrayDouble *newCoords=0; + switch(policy) + { + case 0: + { + newCoords=fillExtCoordsUsingTranslation(mesh1D,isQuad); + break; + } + default: + throw INTERP_KERNEL::Exception("Not implemented extrusion policy : must be in (0) !"); + } + setCoords(newCoords); + newCoords->decrRef(); + MEDCouplingUMesh *ret=buildExtrudedMeshFromThisLowLev(oldNbOfNodes,isQuad); + updateTime(); + return ret; +} + +/*! + * This method incarnates the policy 0 for MEDCouplingUMesh::buildExtrudedMeshFromThis method. + * @param mesh1D is the input 1D mesh used for translation computation. + * @return newCoords new coords filled by this method. + */ +DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const +{ + int oldNbOfNodes=getNumberOfNodes(); + int nbOf1DCells=mesh1D->getNumberOfCells(); + DataArrayDouble *ret=DataArrayDouble::New(); + std::vector isQuads; + int nbOfLevsInVec=isQuad?2*nbOf1DCells+1:nbOf1DCells+1; + ret->alloc(oldNbOfNodes*nbOfLevsInVec,3); + double *retPtr=ret->getPointer(); + const double *coords=getCoords()->getConstPointer(); + double *work=std::copy(coords,coords+3*oldNbOfNodes,retPtr); + std::vector v; + std::vector c; + double vec[3]; + v.reserve(3); + c.reserve(6); + for(int i=0;igetNodeIdsOfCell(i,v); + c.resize(0); + mesh1D->getCoordinatesOfNode(v[isQuad?2:1],c); + mesh1D->getCoordinatesOfNode(v[0],c); + std::transform(c.begin(),c.begin()+3,c.begin()+3,vec,std::minus()); + for(int j=0;j()); + if(isQuad) + { + c.resize(0); + mesh1D->getCoordinatesOfNode(v[1],c); + mesh1D->getCoordinatesOfNode(v[0],c); + std::transform(c.begin(),c.begin()+3,c.begin()+3,vec,std::minus()); + for(int j=0;j()); + } + } + return ret; +} + +/*! + * This method is private because not easy to use for end user. This method is const contrary to + * MEDCouplingUMesh::buildExtrudedMeshFromThis method because this->_coords are expected to contain + * the coords sorted slice by slice. + * @param isQuad specifies presence of quadratic cells. + */ +MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const +{ + int nbOf1DCells=getNumberOfNodes()/nbOfNodesOf1Lev-1; + int nbOf2DCells=getNumberOfCells(); + int nbOf3DCells=nbOf2DCells*nbOf1DCells; + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("Extruded",3); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + DataArrayInt *newConn=DataArrayInt::New(); + DataArrayInt *newConnI=DataArrayInt::New(); + newConnI->alloc(nbOf3DCells+1,1); + int *newConnIPtr=newConnI->getPointer(); + *newConnIPtr++=0; + std::vector newc; + for(int j=0;jalloc(newc.size()*nbOf1DCells,1); + int *newConnPtr=newConn->getPointer(); + int deltaPerLev=isQuad?2*nbOfNodesOf1Lev:nbOfNodesOf1Lev; + newConnIPtr=newConnI->getPointer(); + for(int iz=0;iz(),newConnIPtr[iz*nbOf2DCells])); + for(std::vector::const_iterator iter=newc.begin();iter!=newc.end();iter++,newConnPtr++) + { + int icell=iter-newc.begin(); + if(std::find(newConnIPtr,newConnIPtr+nbOf2DCells,icell)==newConnIPtr+nbOf2DCells) + { + if(*iter!=-1) + *newConnPtr=(*iter)+iz*deltaPerLev; + else + *newConnPtr=-1; + } + else + *newConnPtr=(*iter); + } + } + ret->setConnectivity(newConn,newConnI,true); + newConn->decrRef(); + newConnI->decrRef(); + ret->setCoords(getCoords()); + return ret; +} + +/*! + *This method returns if 'this' is constituted by only quadratic cells. + */ +bool MEDCouplingUMesh::isFullyQuadratic() const +{ + checkFullyDefined(); + bool ret=true; + int nbOfCells=getNumberOfCells(); + for(int i=0;idecrRef(); return ret; } + +/*! + * This method takes in input a cell defined by its MEDcouplingUMesh connectivity [connBg,connEnd) and returns its extruded cell by inserting the result at the end of ret. + * @param nbOfNodesPerLev in parameter that specifies the number of nodes of one slice of global dataset + * @param isQuad specifies the policy of connectivity. + * @ret in/out parameter in which the result will be append + */ +void MEDCouplingUMesh::appendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector& ret) +{ + INTERP_KERNEL::NormalizedCellType flatType=(INTERP_KERNEL::NormalizedCellType)connBg[0]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(flatType); + ret.push_back(cm.getExtrudedType()); + int deltaz=isQuad?2*nbOfNodesPerLev:nbOfNodesPerLev; + switch(flatType) + { + case INTERP_KERNEL::NORM_POINT0: + { + ret.push_back(connBg[1]); + ret.push_back(connBg[1]+nbOfNodesPerLev); + break; + } + case INTERP_KERNEL::NORM_SEG2: + { + int conn[4]={connBg[1],connBg[2],connBg[2]+deltaz,connBg[1]+deltaz}; + ret.insert(ret.end(),conn,conn+4); + break; + } + case INTERP_KERNEL::NORM_SEG3: + { + int conn[8]={connBg[1],connBg[3],connBg[3]+deltaz,connBg[1]+deltaz,connBg[2],connBg[3]+nbOfNodesPerLev,connBg[2]+deltaz,connBg[1]+nbOfNodesPerLev}; + ret.insert(ret.end(),conn,conn+8); + break; + } + case INTERP_KERNEL::NORM_QUAD4: + { + int conn[8]={connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz}; + ret.insert(ret.end(),conn,conn+8); + break; + } + case INTERP_KERNEL::NORM_TRI3: + { + int conn[6]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz}; + ret.insert(ret.end(),conn,conn+6); + break; + } + case INTERP_KERNEL::NORM_TRI6: + { + int conn[15]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4],connBg[5],connBg[6],connBg[4]+deltaz,connBg[5]+deltaz,connBg[6]+deltaz, + connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev}; + ret.insert(ret.end(),conn,conn+15); + break; + } + case INTERP_KERNEL::NORM_QUAD8: + { + int conn[20]={ + connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz, + connBg[5],connBg[6],connBg[7],connBg[8],connBg[5]+deltaz,connBg[6]+deltaz,connBg[7]+deltaz,connBg[8]+deltaz, + connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev,connBg[4]+nbOfNodesPerLev + }; + ret.insert(ret.end(),conn,conn+20); + break; + } + case INTERP_KERNEL::NORM_POLYGON: + { + std::back_insert_iterator< std::vector > ii(ret); + std::copy(connBg+1,connEnd,ii); + *ii++=-1; + std::transform(connBg+1,connEnd,ii,std::bind2nd(std::plus(),deltaz)); + int nbOfRadFaces=std::distance(connBg+1,connEnd); + for(int i=0;i& elts, std::vector& eltsIndex) const; MEDCOUPLING_EXPORT void checkButterflyCells(std::vector& cells) const; MEDCOUPLING_EXPORT void getBoundingBoxForBBTree(std::vector& bbox) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildExtrudedMeshFromThis(const MEDCouplingUMesh *mesh1D, int policy); + MEDCOUPLING_EXPORT bool isFullyQuadratic() const; + MEDCOUPLING_EXPORT bool isPresenceOfQuadratic() const; //utilities for MED File RW MEDCOUPLING_EXPORT bool checkConsecutiveCellTypes() const; MEDCOUPLING_EXPORT DataArrayInt *rearrange2ConsecutiveCellTypes(); @@ -106,13 +109,16 @@ namespace ParaMEDMEM void computeTypes(); void checkFullyDefined() const throw(INTERP_KERNEL::Exception); //tools + MEDCouplingUMesh *buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const; + DataArrayDouble *fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; template void findCommonCellsBase(int compType, std::vector& res, std::vector& resI) const; - MEDCOUPLING_EXPORT bool areCellsEqualsInPool(const std::vector& candidates, int compType, std::vector& result) const; + bool areCellsEqualsInPool(const std::vector& candidates, int compType, std::vector& result) const; MEDCouplingUMesh *buildPartOfMySelfKeepCoords(const int *start, const int *end) const; template void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, double eps, std::vector& elts, std::vector& eltsIndex) const; + static void appendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector& ret); private: //! this iterator stores current position in _nodal_connec array. mutable int _iterator; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx index 629ebf680..7307e3834 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx @@ -54,6 +54,7 @@ namespace ParaMEDMEM CPPUNIT_TEST( testBuildSubMeshData ); CPPUNIT_TEST( testExtrudedMesh1 ); CPPUNIT_TEST( testExtrudedMesh2 ); + CPPUNIT_TEST( testExtrudedMesh3 ); CPPUNIT_TEST( testFindCommonNodes ); CPPUNIT_TEST( testCheckButterflyCells ); CPPUNIT_TEST( testMergeMesh1 ); @@ -163,6 +164,7 @@ namespace ParaMEDMEM void testBuildSubMeshData(); void testExtrudedMesh1(); void testExtrudedMesh2(); + void testExtrudedMesh3(); void testFindCommonNodes(); void testCheckButterflyCells(); void testMergeMesh1(); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx index b707c2416..46e79f9ec 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx @@ -997,6 +997,64 @@ void MEDCouplingBasicsTest::testExtrudedMesh2() mTF->decrRef(); } +/*! + * This test check MEDCouplingUMesh::buildExtrudedMeshFromThis method. + */ +void MEDCouplingBasicsTest::testExtrudedMesh3() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + m1->changeSpaceDimension(3); + MEDCouplingUMesh *m2=buildCU1DMesh_U(); + m2->changeSpaceDimension(3); + double center[3]={0.,0.,0.}; + double vector[3]={0,1,0}; + m2->rotate(center,vector,-M_PI/2.); + MEDCouplingUMesh *m3=m1->buildExtrudedMeshFromThis(m2,0); + // + MEDCouplingExtrudedMesh *m4=MEDCouplingExtrudedMesh::New(m3,m1,0); + CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); + const int *m3DIds=m4->getMesh3DIds()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_EQUAL(i,m3DIds[i]); + m4->decrRef(); + //some random in cells to check that extrusion alg find it correctly + const int expected1[15]={1,3,2,0,6,5,7,10,11,8,12,9,14,13,4}; + m3->renumberCells(expected1,expected1+15,false); + m4=MEDCouplingExtrudedMesh::New(m3,m1,0); + CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); + m3DIds=m4->getMesh3DIds()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],m3DIds[i]); + m4->decrRef(); + m3->decrRef(); + //play with polygons and polyedrons + std::vector cells(2); cells[0]=2; cells[1]=3; + m1->convertToPolyTypes(cells); + m3=m1->buildExtrudedMeshFromThis(m2,0); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_HEXA8,(int)m3->getTypeOfCell(0)); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_PENTA6,(int)m3->getTypeOfCell(1)); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_POLYHED,(int)m3->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_POLYHED,(int)m3->getTypeOfCell(3)); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_HEXA8,(int)m3->getTypeOfCell(4)); + m3->renumberCells(expected1,expected1+15,false); + m4=MEDCouplingExtrudedMesh::New(m3,m1,0); + CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); + m3DIds=m4->getMesh3DIds()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],m3DIds[i]); + m4->decrRef(); + m3->decrRef(); + // + m2->decrRef(); + m1->decrRef(); +} + void MEDCouplingBasicsTest::testFindCommonNodes() { DataArrayInt *comm,*commI; diff --git a/src/MEDLoader/MEDLoader.cxx b/src/MEDLoader/MEDLoader.cxx index 06eb6eff7..fa0724c10 100644 --- a/src/MEDLoader/MEDLoader.cxx +++ b/src/MEDLoader/MEDLoader.cxx @@ -140,6 +140,7 @@ namespace MEDLoaderNS std::vector getIdsFromGroups(const char *fileName, const char *meshName, const std::vector& grps); med_int getIdFromMeshName(med_idt fid, const char *meshName, std::string& trueMeshName) throw(INTERP_KERNEL::Exception); void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entite_maillage& whichEntity); + int readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector& possibilities); void readUMeshDataInMedFile(med_idt fid, med_int meshId, double *&coords, int& nCoords, int& spaceDim, std::list& conn); int buildMEDSubConnectivityOfOneType(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, @@ -165,6 +166,7 @@ namespace MEDLoaderNS void writeUMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, const DataArrayInt *families, bool forceFromScratch); void writeUMeshesDirectly(const char *fileName, const char *meshName, const std::vector& meshes, bool forceFromScratch); void writeFieldAndMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch); + void writeFieldTryingToFitExistingMesh(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f); } const char WHITE_SPACES[]=" \n"; @@ -685,6 +687,51 @@ void MEDLoaderNS::dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfEle } } +/*! + * This method returns a first quick overview of mesh with name 'meshName' into the file 'fileName'. + * @param possibilities the relativeToMeshDim authorized to returned maxdim. This vector is systematically cleared at the begin of this method. + * @return the maximal mesh dimension of specified mesh. If nothing found -1 is returned. + */ +int MEDLoaderNS::readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector& possibilities) +{ + possibilities.clear(); + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + int ret; + std::set poss; + char nommaa[MED_TAILLE_NOM+1]; + char maillage_description[MED_TAILLE_DESC+1]; + med_maillage type_maillage; + med_int Mdim; + std::string trueMeshName; + med_int meshId=getIdFromMeshName(fid,meshName,trueMeshName); + MEDmaaInfo(fid,meshId,nommaa,&Mdim,&type_maillage,maillage_description); + for(int i=0;i0) + { + INTERP_KERNEL::NormalizedCellType type=typmai2[i]; + int curDim=(int)INTERP_KERNEL::CellModel::getCellModel(type).getDimension(); + poss.insert(curDim); + } + } + MEDfermer(fid); + if(!poss.empty()) + { + ret=*poss.rbegin(); + for(std::set::const_reverse_iterator it=poss.rbegin();it!=poss.rend();it++) + possibilities.push_back(*it-ret); + } + else + ret=-2; + return ret; +} + void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, double *&coords, int& nCoords, int& spaceDim, std::list& conn) { char nommaa[MED_TAILLE_NOM+1]; @@ -940,7 +987,7 @@ void MEDLoaderNS::tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list(),1)); else - tmpConnPtr=std::transform(sourceConn,sourceConn+sourceIndex[i+1]-sourceIndex[i],connPtr,std::bind2nd(std::minus(),1)); + tmpConnPtr=std::transform((*iter).getArray()+sourceIndex[i]-1,(*iter).getArray()+sourceIndex[i+1]-1,connPtr,std::bind2nd(std::minus(),1)); connIdxPtr++; nbOfNodesIn1Cell=tmpConnPtr-connPtr; connFillId+=nbOfNodesIn1Cell+1; @@ -1189,12 +1236,21 @@ ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, return MEDLoaderNS::readUMeshFromFileLev1(fileName,0,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim); } +int MEDLoader::ReadUMeshDimFromFile(const char *fileName, const char *meshName) +{ + std::vector poss; + return MEDLoaderNS::readUMeshDimFromFile(fileName,meshName,poss); +} + ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& fams) { std::vector familiesToKeep=MEDLoaderNS::getIdsFromFamilies(fileName,meshName,fams); std::vector typesToKeep; unsigned meshDim; - return MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim); + ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim); + if(fams.size()==1) + ret->setName(fams.back().c_str()); + return ret; } ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& grps) @@ -1202,7 +1258,10 @@ ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const char *fileNam std::vector familiesToKeep=MEDLoaderNS::getIdsFromGroups(fileName,meshName,grps); std::vector typesToKeep; unsigned meshDim; - return MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim); + ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim); + if(grps.size()==1) + ret->setName(grps.back().c_str()); + return ret; } ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDouble(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) @@ -1443,6 +1502,28 @@ void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, ParaMEDMEM::ME appendFieldDirectly(fileName,f); } +/*! + * When called this method expectes that file 'fileName' is already existing and has a mesh with name equal to + * f->getMesh()->getName(). If not the behaviour of this method is not warranted. + * This method reads the corresponding mesh into the file and try to fit it with f->getMesh(). + * If it appears that f->getMesh() equals exactly mesh into the file + */ +void MEDLoaderNS::writeFieldTryingToFitExistingMesh(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f) +{ + std::vector poss; + int mDimInFile=MEDLoaderNS::readUMeshDimFromFile(fileName,f->getMesh()->getName(),poss); + int mdim=f->getMesh()->getMeshDimension(); + int f2=mdim-mDimInFile; + if(std::find(poss.begin(),poss.end(),f2)==poss.end()) + { + std::ostringstream oss; oss << "Trying to fit with the existing \"" << f->getMesh()->getName() << "mesh in file \"" << fileName; + oss << "\" but meshdimension does not match !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingUMesh *m=MEDLoader::ReadUMeshFromFile(fileName,f->getMesh()->getName(),f2); + m->decrRef(); +} + void MEDLoader::WriteUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) { std::string meshName(mesh->getName()); @@ -1553,11 +1634,10 @@ void MEDLoader::WriteField(const char *fileName, ParaMEDMEM::MEDCouplingFieldDou if(std::find(meshNames.begin(),meshNames.end(),fileNameCpp)==meshNames.end()) MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,false); else - { - std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \""; - oss << fileNameCpp << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + MEDLoaderNS::writeFieldTryingToFitExistingMesh(fileName,f); + /*std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \""; + oss << fileNameCpp << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str());*/ } } diff --git a/src/MEDLoader/MEDLoader.hxx b/src/MEDLoader/MEDLoader.hxx index 1c40b79f9..fc7dbde15 100644 --- a/src/MEDLoader/MEDLoader.hxx +++ b/src/MEDLoader/MEDLoader.hxx @@ -88,6 +88,7 @@ public: static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& grps); static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); + static int ReadUMeshDimFromFile(const char *fileName, const char *meshName); static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDouble(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order); static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order); static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order); diff --git a/src/MEDLoader/Test/MEDLoaderTest.cxx b/src/MEDLoader/Test/MEDLoaderTest.cxx index bd663c7fd..1ce22526d 100644 --- a/src/MEDLoader/Test/MEDLoaderTest.cxx +++ b/src/MEDLoader/Test/MEDLoaderTest.cxx @@ -105,29 +105,30 @@ void MEDLoaderTest::testFieldRW1() */ void MEDLoaderTest::testFieldRW2() { + const char fileName[]="file8.med"; static const double VAL1=12345.67890314; static const double VAL2=-1111111111111.; MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); - MEDLoader::WriteField("file8.med",f1,true); + MEDLoader::WriteField(fileName,f1,true); f1->setTime(10.,8,9); double *tmp=f1->getArray()->getPointer(); tmp[0]=VAL1; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file8.med",f1); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); f1->setTime(10.14,18,19); tmp[0]=VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file8.med",f1); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); //retrieving time steps... - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldDoubleCell("file8.med",f1->getMesh()->getName(),0,f1->getName(),8,9); + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldDoubleCell(fileName,f1->getMesh()->getName(),0,f1->getName(),8,9); f1->setTime(10.,8,9); tmp[0]=VAL1; CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); f2->decrRef(); - f2=MEDLoader::ReadFieldDoubleCell("file8.med",f1->getMesh()->getName(),0,f1->getName(),0,1); + f2=MEDLoader::ReadFieldDoubleCell(fileName,f1->getMesh()->getName(),0,f1->getName(),0,1); MEDCouplingFieldDouble *f3=buildVecFieldOnCells_1(); CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); f3->decrRef(); f2->decrRef(); - f2=MEDLoader::ReadFieldDoubleCell("file8.med",f1->getMesh()->getName(),0,f1->getName(),18,19); + f2=MEDLoader::ReadFieldDoubleCell(fileName,f1->getMesh()->getName(),0,f1->getName(),18,19); f1->setTime(10.14,18,19); tmp[0]=VAL2; CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); @@ -135,25 +136,26 @@ void MEDLoaderTest::testFieldRW2() f1->decrRef(); //ON NODES f1=buildVecFieldOnNodes_1(); - MEDLoader::WriteField("file9.med",f1,true); + const char fileName2[]="file9.med"; + MEDLoader::WriteField(fileName2,f1,true); f1->setTime(110.,108,109); tmp=f1->getArray()->getPointer(); tmp[3]=VAL1; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file9.med",f1); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); f1->setTime(210.,208,209); tmp[3]=VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file9.med",f1); - f2=MEDLoader::ReadFieldDoubleNode("file9.med",f1->getMesh()->getName(),0,f1->getName(),108,109); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f2=MEDLoader::ReadFieldDoubleNode(fileName2,f1->getMesh()->getName(),0,f1->getName(),108,109); f1->setTime(110.,108,109); tmp[3]=VAL1; CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); f2->decrRef(); - f2=MEDLoader::ReadFieldDoubleNode("file9.med",f1->getMesh()->getName(),0,f1->getName(),2,3); + f2=MEDLoader::ReadFieldDoubleNode(fileName2,f1->getMesh()->getName(),0,f1->getName(),2,3); f3=buildVecFieldOnNodes_1(); CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); f3->decrRef(); f2->decrRef(); - f2=MEDLoader::ReadFieldDoubleNode("file9.med",f1->getMesh()->getName(),0,f1->getName(),208,209); + f2=MEDLoader::ReadFieldDoubleNode(fileName2,f1->getMesh()->getName(),0,f1->getName(),208,209); f1->setTime(210.,208,209); tmp[3]=VAL2; CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); @@ -166,6 +168,7 @@ void MEDLoaderTest::testFieldRW2() */ void MEDLoaderTest::testFieldRW3() { + const char fileName[]="file11.med"; static const double VAL1=12345.67890314; static const double VAL2=-1111111111111.; const char name1[]="AField"; @@ -177,83 +180,84 @@ void MEDLoaderTest::testFieldRW3() f1->setTime(10.,8,9); double *tmp=f1->getArray()->getPointer(); tmp[0]=VAL1; - MEDLoader::WriteField("file11.med",f1,true); + MEDLoader::WriteField(fileName,f1,true); f1->setTime(10.14,18,19); tmp[0]=VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file11.med",f1); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); ((MEDCouplingMesh *)f1->getMesh())->setName(name2); f1->setTime(10.55,28,29); tmp[0]=3*VAL1; - MEDLoader::WriteField("file11.med",f1,false); + MEDLoader::WriteField(fileName,f1,false); f1->setTime(10.66,38,39); tmp[0]=3*VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file11.med",f1); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); f1->setTime(10.77,48,49); tmp[0]=4*VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file11.med",f1); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); //ON NODES f1->decrRef(); f1=buildVecFieldOnNodes_1(); f1->setName(name1); ((MEDCouplingMesh *)f1->getMesh())->setName(name2); f1->setTime(110.,8,9); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file11.med",f1); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); f1->setTime(110.,108,109); tmp=f1->getArray()->getPointer(); tmp[3]=VAL1; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file11.med",f1); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); f1->setTime(210.,208,209); tmp[3]=VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file11.med",f1); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); // - std::vector< std::pair > it1=MEDLoader::GetCellFieldIterations("file11.med",name3,name1); + std::vector< std::pair > it1=MEDLoader::GetCellFieldIterations(fileName,name3,name1); CPPUNIT_ASSERT_EQUAL(2,(int)it1.size()); CPPUNIT_ASSERT_EQUAL(8,it1[0].first); CPPUNIT_ASSERT_EQUAL(9,it1[0].second); CPPUNIT_ASSERT_EQUAL(18,it1[1].first); CPPUNIT_ASSERT_EQUAL(19,it1[1].second); - std::vector< std::pair > it2=MEDLoader::GetCellFieldIterations("file11.med",name2,name1); + std::vector< std::pair > it2=MEDLoader::GetCellFieldIterations(fileName,name2,name1); CPPUNIT_ASSERT_EQUAL(3,(int)it2.size()); CPPUNIT_ASSERT_EQUAL(28,it2[0].first); CPPUNIT_ASSERT_EQUAL(29,it2[0].second); CPPUNIT_ASSERT_EQUAL(38,it2[1].first); CPPUNIT_ASSERT_EQUAL(39,it2[1].second); CPPUNIT_ASSERT_EQUAL(48,it2[2].first); CPPUNIT_ASSERT_EQUAL(49,it2[2].second); - std::vector< std::pair > it3=MEDLoader::GetNodeFieldIterations("file11.med",name2,name1); + std::vector< std::pair > it3=MEDLoader::GetNodeFieldIterations(fileName,name2,name1); CPPUNIT_ASSERT_EQUAL(3,(int)it3.size()); CPPUNIT_ASSERT_EQUAL(8,it3[0].first); CPPUNIT_ASSERT_EQUAL(9,it3[0].second); CPPUNIT_ASSERT_EQUAL(108,it3[1].first); CPPUNIT_ASSERT_EQUAL(109,it3[1].second); CPPUNIT_ASSERT_EQUAL(208,it3[2].first); CPPUNIT_ASSERT_EQUAL(209,it3[2].second); - std::vector< std::pair > it4=MEDLoader::GetNodeFieldIterations("file11.med",name3,name1); + std::vector< std::pair > it4=MEDLoader::GetNodeFieldIterations(fileName,name3,name1); CPPUNIT_ASSERT(it4.empty()); // f1->decrRef(); // - f1=MEDLoader::ReadFieldDoubleCell("file11.med",name3,0,name1,8,9); + f1=MEDLoader::ReadFieldDoubleCell(fileName,name3,0,name1,8,9); CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[0],1e-13); f1->decrRef(); - f1=MEDLoader::ReadFieldDoubleCell("file11.med",name3,0,name1,18,19); + f1=MEDLoader::ReadFieldDoubleCell(fileName,name3,0,name1,18,19); CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[0],1e-13); f1->decrRef(); - f1=MEDLoader::ReadFieldDoubleCell("file11.med",name2,0,name1,28,29); + f1=MEDLoader::ReadFieldDoubleCell(fileName,name2,0,name1,28,29); CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL1,f1->getArray()->getConstPointer()[0],1e-13); f1->decrRef(); - f1=MEDLoader::ReadFieldDoubleCell("file11.med",name2,0,name1,38,39); + f1=MEDLoader::ReadFieldDoubleCell(fileName,name2,0,name1,38,39); CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL2,f1->getArray()->getConstPointer()[0],1e-13); f1->decrRef(); - f1=MEDLoader::ReadFieldDoubleCell("file11.med",name2,0,name1,48,49); + f1=MEDLoader::ReadFieldDoubleCell(fileName,name2,0,name1,48,49); CPPUNIT_ASSERT_DOUBLES_EQUAL(4*VAL2,f1->getArray()->getConstPointer()[0],1e-13); f1->decrRef(); // - f1=MEDLoader::ReadFieldDoubleNode("file11.med",name2,0,name1,8,9); + f1=MEDLoader::ReadFieldDoubleNode(fileName,name2,0,name1,8,9); CPPUNIT_ASSERT_DOUBLES_EQUAL(71.,f1->getArray()->getConstPointer()[3],1e-13); f1->decrRef(); - f1=MEDLoader::ReadFieldDoubleNode("file11.med",name2,0,name1,108,109); + f1=MEDLoader::ReadFieldDoubleNode(fileName,name2,0,name1,108,109); CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[3],1e-13); f1->decrRef(); - f1=MEDLoader::ReadFieldDoubleNode("file11.med",name2,0,name1,208,209); + f1=MEDLoader::ReadFieldDoubleNode(fileName,name2,0,name1,208,209); CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[3],1e-13); f1->decrRef(); } void MEDLoaderTest::testMultiMeshRW1() { + const char fileName[]="file10.med"; MEDCouplingUMesh *mesh1=build3DMesh_1(); const int part1[5]={1,2,4,13,15}; MEDCouplingUMesh *mesh2=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part1,part1+5,true); @@ -274,13 +278,85 @@ void MEDLoaderTest::testMultiMeshRW1() meshes.push_back(mesh2); meshes.push_back(mesh3); meshes.push_back(mesh4); - MEDLoader::WriteUMeshes("file10.med","3DToto",meshes,true); + const char mnane[]="3DToto"; + MEDLoader::WriteUMeshes(fileName,mnane,meshes,true); + // + MEDCouplingUMesh *mesh5=MEDLoader::ReadUMeshFromFile(fileName,mnane); + mesh1->setName(mnane); + const int part3[18]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}; + MEDCouplingUMesh *mesh6=(MEDCouplingUMesh *)mesh5->buildPartOfMySelf(part3,part3+18,true); + mesh6->setName(mnane); + mesh5->decrRef(); + CPPUNIT_ASSERT(mesh6->isEqual(mesh1,1e-12)); + mesh6->decrRef(); + std::vector grps=MEDLoader::GetMeshGroupsNames(fileName,mnane); + CPPUNIT_ASSERT_EQUAL(4,(int)grps.size()); + CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh2"))!=grps.end()); + CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh3"))!=grps.end()); + CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh4"))!=grps.end()); + CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("3DMesh_1"))!=grps.end()); + // + std::vector vec; + vec.push_back(std::string("mesh2")); + MEDCouplingUMesh *mesh2_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); + CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12)); + mesh2_2->decrRef(); + vec.clear(); vec.push_back(std::string("mesh3")); + MEDCouplingUMesh *mesh3_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); + CPPUNIT_ASSERT(mesh3_2->isEqual(mesh3,1e-12)); + mesh3_2->decrRef(); + vec.clear(); vec.push_back(std::string("mesh4")); + MEDCouplingUMesh *mesh4_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); + CPPUNIT_ASSERT(mesh4_2->isEqual(mesh4,1e-12)); + mesh4_2->decrRef(); + vec.clear(); vec.push_back(std::string("3DMesh_1")); + MEDCouplingUMesh *mesh1_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); + mesh1->setName("3DMesh_1"); + CPPUNIT_ASSERT(mesh1_2->isEqual(mesh1,1e-12)); + mesh1_2->decrRef(); + // + vec.clear(); vec.push_back(std::string("Family_4")); vec.push_back(std::string("Family_2")); + mesh2_2=MEDLoader::ReadUMeshFromFamilies(fileName,mnane,0,vec); + mesh2_2->setName("mesh2"); + CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12)); + mesh2_2->decrRef(); + // mesh4->decrRef(); mesh3->decrRef(); mesh2->decrRef(); mesh1->decrRef(); } +void MEDLoaderTest::testFieldProfilRW1() +{ + const char fileName[]="file12.med"; + MEDCouplingUMesh *mesh1=build3DMesh_1(); + MEDLoader::WriteUMesh(fileName,mesh1,true); + const int part1[5]={1,2,4,13,15}; + MEDCouplingUMesh *mesh2=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part1,part1+5,true); + mesh2->setName(mesh1->getName());//<- important for the test + // + int nbOfCells=mesh2->getNumberOfCells(); + CPPUNIT_ASSERT_EQUAL(5,nbOfCells); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("VectorFieldOnCells"); + f1->setMesh(mesh2); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(nbOfCells,2); + f1->setArray(array); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[10]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.}; + std::copy(arr1,arr1+10,tmp); + f1->setTime(3.14,2,7); + f1->checkCoherency(); + // + MEDLoader::WriteField(fileName,f1,false);//<- false important for the test + f1->decrRef(); + mesh1->decrRef(); + mesh2->decrRef(); +} + MEDCouplingUMesh *MEDLoaderTest::build1DMesh_1() { double coords[6]={ 0.0, 0.3, 0.75, 1.0, 1.4, 1.3 }; diff --git a/src/MEDLoader/Test/MEDLoaderTest.hxx b/src/MEDLoader/Test/MEDLoaderTest.hxx index b1b2184df..7ecfdd82d 100644 --- a/src/MEDLoader/Test/MEDLoaderTest.hxx +++ b/src/MEDLoader/Test/MEDLoaderTest.hxx @@ -39,6 +39,7 @@ namespace ParaMEDMEM CPPUNIT_TEST( testFieldRW2 ); CPPUNIT_TEST( testFieldRW3 ); CPPUNIT_TEST( testMultiMeshRW1 ); + CPPUNIT_TEST( testFieldProfilRW1 ); CPPUNIT_TEST_SUITE_END(); public: void testMesh1DRW(); @@ -50,6 +51,7 @@ namespace ParaMEDMEM void testFieldRW2(); void testFieldRW3(); void testMultiMeshRW1(); + void testFieldProfilRW1(); private: MEDCouplingUMesh *build1DMesh_1(); MEDCouplingUMesh *build2DCurveMesh_1();