From: ageay Date: Fri, 16 Jul 2010 16:43:24 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: V5_1_main_FINAL~89 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=a89f2dedc036eb5edeca32e13ccedcd87b0aff9a;p=tools%2Fmedcoupling.git *** empty log message *** --- diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 760ef3282..aa6504ff0 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -465,8 +465,8 @@ bool MEDCouplingUMesh::areCellsEquals2(int cell1, int cell2) const { const int *conn=getNodalConnectivity()->getConstPointer(); const int *connI=getNodalConnectivityIndex()->getConstPointer(); - std::set s1(conn+connI[cell1],conn+connI[cell1+1]); s1.erase(-1); - std::set s2(conn+connI[cell2],conn+connI[cell2+1]); s1.erase(-1); + std::set s1(conn+connI[cell1],conn+connI[cell1+1]); + std::set s2(conn+connI[cell2],conn+connI[cell2+1]); return s1==s2; } @@ -544,10 +544,12 @@ void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector& res, bb[2*j+1]=std::max(bb[2*j+1],coords[SPACEDIM*(*pt)+j]); } } + std::vector candidates1; + myTree.getIntersectingElems(bb,candidates1); std::vector candidates; - myTree.getIntersectingElems(bb,candidates); - std::vector::iterator it=std::find(candidates.begin(),candidates.end(),k); - candidates.erase(candidates.begin(),it); + for(std::vector::const_iterator iter=candidates1.begin();iter!=candidates1.end();iter++) + if(!isFetched[*iter]) + candidates.push_back(*iter); if(areCellsEqualsInPool(candidates,compType,res)) { int pos=resI.back(); @@ -555,6 +557,7 @@ void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector& res, for(std::vector::const_iterator it=res.begin()+pos;it!=res.end();it++) isFetched[*it]=true; } + isFetched[k]=true; } } } @@ -1603,6 +1606,7 @@ namespace ParaMEDMEMImpl */ bool MEDCouplingUMesh::checkConsecutiveCellTypes() const { + checkFullyDefined(); const int *conn=_nodal_connec->getConstPointer(); const int *connI=_nodal_connec_index->getConstPointer(); int nbOfCells=getNumberOfCells(); @@ -1618,6 +1622,42 @@ bool MEDCouplingUMesh::checkConsecutiveCellTypes() const return true; } +/*! + * This method reorganize the cells of 'this' so that the cells with same geometric types are put together. + * If checkConsecutiveCellTypes() returns true, this method do not change anything of this. + * The number of cells remains unchanged after the call of this method. + * @return the array giving the correspondance old to new. + */ +DataArrayInt *MEDCouplingUMesh::rearrange2ConsecutiveCellTypes() +{ + checkFullyDefined(); + computeTypes(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + std::vector types; + for(const int *i=connI;i!=connI+nbOfCells && (types.size()!=_types.size());) + if(std::find(types.begin(),types.end(),(INTERP_KERNEL::NormalizedCellType)conn[*i])==types.end()) + { + INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; + types.push_back(curType); + for(i++;i!=connI+nbOfCells && (INTERP_KERNEL::NormalizedCellType)conn[*i]==curType;i++); + } + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr=ret->getPointer(); + std::fill(retPtr,retPtr+nbOfCells,-1); + int newCellId=0; + for(std::vector::const_iterator iter=types.begin();iter!=types.end();iter++) + { + for(const int *i=connI;i!=connI+nbOfCells;i++) + if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter)) + retPtr[std::distance(connI,i)]=newCellId++; + } + renumberCells(retPtr,retPtr+nbOfCells,false); + return ret; +} + /*! * This methods split this into as mush as untructured meshes that consecutive set of same type cells. * So this method has typically a sense if MEDCouplingUMesh::checkConsecutiveCellTypes has a sense. @@ -1625,6 +1665,7 @@ bool MEDCouplingUMesh::checkConsecutiveCellTypes() const */ std::vector MEDCouplingUMesh::splitByType() const { + checkFullyDefined(); const int *conn=_nodal_connec->getConstPointer(); const int *connI=_nodal_connec_index->getConstPointer(); int nbOfCells=getNumberOfCells(); @@ -1733,7 +1774,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshes(const MEDCouplingUMesh *mesh1, /*! * Idem mergeUMeshes except that 'meshes' are expected to lyie on the same coords and 'meshes' have the same meshdim. - * 'meshes' must be a non empty vector. 'meshes' have to be with the same mesh dimension. + * 'meshes' must be a non empty vector. */ MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshesOnSameCoords(const std::vector& meshes) { @@ -1784,7 +1825,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshesOnSameCoords(const std::vector& bbox) const; //utilities for MED File RW MEDCOUPLING_EXPORT bool checkConsecutiveCellTypes() const; + MEDCOUPLING_EXPORT DataArrayInt *rearrange2ConsecutiveCellTypes(); MEDCOUPLING_EXPORT std::vector splitByType() const; // MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx index 82fcd1f58..629ebf680 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx @@ -69,8 +69,10 @@ namespace ParaMEDMEM CPPUNIT_TEST( testOperationsOnFields4 ); CPPUNIT_TEST( testMergeNodesOnField ); CPPUNIT_TEST( testCheckConsecutiveCellTypes ); + CPPUNIT_TEST( testRearrange2ConsecutiveCellTypes ); CPPUNIT_TEST( testSplitByType ); CPPUNIT_TEST( testFuseUMeshesOnSameCoords ); + CPPUNIT_TEST( testFuseUMeshesOnSameCoords2 ); CPPUNIT_TEST( testBuildOrthogonalField ); CPPUNIT_TEST( testGetCellsContainingPoint ); CPPUNIT_TEST( testGetValueOn1 ); @@ -137,7 +139,6 @@ namespace ParaMEDMEM CPPUNIT_TEST( test2DCurveInterpP0P1_1 ); CPPUNIT_TEST( test2DCurveInterpP1P0_1 ); CPPUNIT_TEST( test2DCurveInterpP1P1_1 ); - CPPUNIT_TEST_SUITE_END(); public: void testArray(); @@ -177,8 +178,10 @@ namespace ParaMEDMEM void testOperationsOnFields4(); void testMergeNodesOnField(); void testCheckConsecutiveCellTypes(); + void testRearrange2ConsecutiveCellTypes(); void testSplitByType(); void testFuseUMeshesOnSameCoords(); + void testFuseUMeshesOnSameCoords2(); void testBuildOrthogonalField(); void testGetCellsContainingPoint(); void testGetValueOn1(); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx index 18ce4fbdb..b707c2416 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx @@ -1761,6 +1761,37 @@ void MEDCouplingBasicsTest::testCheckConsecutiveCellTypes() sourceMesh->decrRef(); } +void MEDCouplingBasicsTest::testRearrange2ConsecutiveCellTypes() +{ + MEDCouplingUMesh *m1_1=build2DSourceMesh_1(); + MEDCouplingUMesh *m2_1=build2DTargetMesh_1(); + DataArrayInt *arr1=m1_1->rearrange2ConsecutiveCellTypes(); + MEDCouplingUMesh *m1_2=build2DSourceMesh_1(); + CPPUNIT_ASSERT(m1_2->isEqual(m1_1,1e-12)); + const int expected1[2]={0,1}; + CPPUNIT_ASSERT_EQUAL(2,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+2,arr1->getConstPointer())); + arr1->decrRef(); + const int expected2[5]={0,3,4,1,2}; + arr1=m2_1->rearrange2ConsecutiveCellTypes(); + CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+5,arr1->getConstPointer())); + MEDCouplingUMesh *m2_2=build2DTargetMesh_1(); + CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+5,arr1->getConstPointer())); + CPPUNIT_ASSERT(!m2_2->isEqual(m2_1,1e-12)); + m2_2->renumberCells(expected2,expected2+5,false); + CPPUNIT_ASSERT(m2_2->isEqual(m2_1,1e-12)); + arr1->decrRef(); + m1_1->decrRef(); + m1_2->decrRef(); + m2_1->decrRef(); + m2_2->decrRef(); +} + void MEDCouplingBasicsTest::testSplitByType() { MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); @@ -1836,6 +1867,46 @@ void MEDCouplingBasicsTest::testFuseUMeshesOnSameCoords() m5->decrRef(); } +void MEDCouplingBasicsTest::testFuseUMeshesOnSameCoords2() +{ + MEDCouplingUMesh *m2; + MEDCouplingUMesh *m1=build3DExtrudedUMesh_1(m2); + m2->decrRef(); + const int part1[5]={2,3,6,4,10}; + MEDCouplingUMesh *m3=(MEDCouplingUMesh *)m1->buildPartOfMySelf(part1,part1+5,true); + const int part2[4]={5,6,4,7}; + MEDCouplingUMesh *m4=(MEDCouplingUMesh *)m1->buildPartOfMySelf(part2,part2+4,true); + std::vector meshes; + meshes.push_back(m1); + meshes.push_back(m3); + meshes.push_back(m3); + meshes.push_back(m4); + std::vector corr; + MEDCouplingUMesh *m5=MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(18,m5->getNumberOfCells()); + std::vector::iterator it=corr.begin(); + const int exp1[4]={18,5,5,4}; + const int exp2[4][18]={ + {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, + {2,3,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, + {2,3,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, + {5,6,4,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} + }; + int i=0; + for(;it!=corr.end();it++,i++) + { + int sz=(*it)->getNumberOfTuples(); + CPPUNIT_ASSERT_EQUAL(exp1[i],sz); + CPPUNIT_ASSERT(std::equal(exp2[i],exp2[i]+sz,(*it)->getConstPointer())); + } + for(it=corr.begin();it!=corr.end();it++) + (*it)->decrRef(); + m5->decrRef(); + m4->decrRef(); + m3->decrRef(); + m1->decrRef(); +} + void MEDCouplingBasicsTest::testBuildOrthogonalField() { MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); diff --git a/src/MEDLoader/MEDLoader.cxx b/src/MEDLoader/MEDLoader.cxx index abf37e814..06eb6eff7 100644 --- a/src/MEDLoader/MEDLoader.cxx +++ b/src/MEDLoader/MEDLoader.cxx @@ -141,8 +141,9 @@ namespace MEDLoaderNS 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); 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, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, - std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile); + int buildMEDSubConnectivityOfOneType(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, INTERP_KERNEL::NormalizedCellType type, + std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, + std::vector& fam4MEDFile); MEDCouplingUMesh *readUMeshFromFileLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& ids, const std::vector& typesToKeep, unsigned& meshDimExtract) throw(INTERP_KERNEL::Exception); void tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list& medConnFrmt, @@ -150,15 +151,18 @@ namespace MEDLoaderNS DataArrayInt* &connIndex, const std::vector& familiesToKeep); ParaMEDMEM::DataArrayDouble *buildArrayFromRawData(const std::list& fieldPerType); - int buildMEDSubConnectivityOfOneTypesPolyg(const DataArrayInt *conn, const DataArrayInt *connIndex, std::vector& conn4MEDFile, std::vector& connIndex4MEDFile); - int buildMEDSubConnectivityOfOneTypesPolyh(const DataArrayInt *conn, const DataArrayInt *connIndex, std::vector& conn4MEDFile, - std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile); - int buildMEDSubConnectivityOfOneTypeStaticTypes(const DataArrayInt *conn, const DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile); + int buildMEDSubConnectivityOfOneTypesPolyg(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, + std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& fam4MEDFile); + int buildMEDSubConnectivityOfOneTypesPolyh(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, std::vector& conn4MEDFile, + std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, + std::vector& fam4MEDFile); + int buildMEDSubConnectivityOfOneTypeStaticTypes(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, + INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, std::vector& fam4MEDFile); ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField); void appendFieldDirectly(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f); void prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, std::list& split); - void writeUMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool forceFromScratch); + 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); } @@ -963,24 +967,32 @@ namespace MEDLoaderNS * This method builds a sub set of connectivity for a given type 'type'. * @param conn input containing connectivity with MEDCoupling format. * @param connIndex input containing connectivity index in MEDCoupling format. + * @param families input that may be equal to 0. This specifies an array specifying cell family foreach cell. * @param type input specifying which cell types will be extracted in conn4MEDFile. * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called. * @param connIndex4MEDFile output containing index connectivity understandable by MEDFile; only used by polygons and polyhedrons (it is face nodal connec). * @param connIndexRk24MEDFile output containing index of rank 2 understandable by MEDFile; only used by polyhedrons. + * @param fam4MEDFile output containing family number of cells whose type is 'type'. This output is updated only if 'families' is different than 0. * @return nb of elements extracted. */ -int MEDLoaderNS::buildMEDSubConnectivityOfOneTypeStaticTypes(const DataArrayInt *conn, const DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile) +int MEDLoaderNS::buildMEDSubConnectivityOfOneTypeStaticTypes(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, + std::vector& fam4MEDFile) { int ret=0; int nbOfElem=connIndex->getNbOfElems()-1; const int *connPtr=conn->getConstPointer(); const int *connIdxPtr=connIndex->getConstPointer(); + const int *famPtr=0; + if(families) + famPtr=families->getConstPointer(); for(int i=0;i& conn4MEDFile, std::vector& connIndex4MEDFile) +int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyg(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, + std::vector& fam4MEDFile) { int ret=0; int nbOfElem=connIndex->getNbOfElems()-1; const int *connPtr=conn->getConstPointer(); const int *connIdxPtr=connIndex->getConstPointer(); connIndex4MEDFile.push_back(1); + const int *famPtr=0; + if(families) + famPtr=families->getConstPointer(); for(int i=0;i& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile) +int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyh(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, + std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, + std::vector& fam4MEDFile) { int ret=0; int nbOfElem=connIndex->getNbOfElems()-1; @@ -1021,6 +1041,9 @@ int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyh(const DataArrayInt *conn const int *connIdxPtr=connIndex->getConstPointer(); connIndexRk24MEDFile.push_back(1); connIndex4MEDFile.push_back(1); + const int *famPtr=0; + if(families) + famPtr=families->getConstPointer(); for(int i=0;i& conn4MEDFile, - std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile) +int MEDLoaderNS::buildMEDSubConnectivityOfOneType(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, + INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, + std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, std::vector& fam4MEDFile) { const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel(type); if(!cellMod.isDynamic()) - return buildMEDSubConnectivityOfOneTypeStaticTypes(conn,connIndex,type,conn4MEDFile); + return buildMEDSubConnectivityOfOneTypeStaticTypes(conn,connIndex,families,type,conn4MEDFile,fam4MEDFile); else { if(type==INTERP_KERNEL::NORM_POLYGON) - return buildMEDSubConnectivityOfOneTypesPolyg(conn,connIndex,conn4MEDFile,connIndex4MEDFile); + return buildMEDSubConnectivityOfOneTypesPolyg(conn,connIndex,families,conn4MEDFile,connIndex4MEDFile,fam4MEDFile); else - return buildMEDSubConnectivityOfOneTypesPolyh(conn,connIndex,conn4MEDFile,connIndex4MEDFile,connIndexRk24MEDFile); + return buildMEDSubConnectivityOfOneTypesPolyh(conn,connIndex,families,conn4MEDFile,connIndex4MEDFile,connIndexRk24MEDFile,fam4MEDFile); } } @@ -1200,7 +1228,7 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDoubleNode(const char *f return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_NODES); } -void MEDLoaderNS::writeUMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool forceFromScratch) +void MEDLoaderNS::writeUMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, const DataArrayInt *families, bool forceFromScratch) { med_idt fid=MEDouvrir((char *)fileName,forceFromScratch?MED_CREATION:MED_LECTURE_ECRITURE); std::string meshName(mesh->getName()); @@ -1209,9 +1237,11 @@ void MEDLoaderNS::writeUMeshDirectly(const char *fileName, ParaMEDMEM::MEDCoupli MEDfermer(fid); throw INTERP_KERNEL::Exception("MEDCouplingMesh must have a not null name !"); } - char maa[MED_TAILLE_NOM+1]; + char *maa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char *desc=MEDLoaderBase::buildEmptyString(MED_TAILLE_DESC); strcpy(maa,meshName.c_str()); - MEDmaaCr(fid,maa,mesh->getSpaceDimension(),MED_NON_STRUCTURE,maa); + strcpy(desc,meshName.c_str()); + MEDmaaCr(fid,maa,mesh->getSpaceDimension(),MED_NON_STRUCTURE,desc); MEDdimEspaceCr(fid,maa,mesh->getSpaceDimension()); std::set allTypes(mesh->getAllTypes()); DataArrayInt *conn=mesh->getNodalConnectivity(); @@ -1229,7 +1259,8 @@ void MEDLoaderNS::writeUMeshDirectly(const char *fileName, ParaMEDMEM::MEDCoupli std::vector medConn; std::vector medConnIndex; std::vector medConnIndex2; - int nbOfElt=MEDLoaderNS::buildMEDSubConnectivityOfOneType(conn,connIndex,curType,medConn,medConnIndex,medConnIndex2); + std::vector fam; + int nbOfElt=MEDLoaderNS::buildMEDSubConnectivityOfOneType(conn,connIndex,families,curType,medConn,medConnIndex,medConnIndex2,fam); if(curMedType!=MED_POLYGONE && curMedType!=MED_POLYEDRE) MEDconnEcr(fid,maa,mesh->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD); else @@ -1242,6 +1273,8 @@ void MEDLoaderNS::writeUMeshDirectly(const char *fileName, ParaMEDMEM::MEDCoupli &medConn[0],MED_NOD); } } + if(families) + MEDfamEcr(fid,maa,&fam[0],nbOfElt,MED_MAILLE,curMedType); } } MEDfamCr(fid,maa,familyName,0,0,0,0,0,0,0); @@ -1255,20 +1288,66 @@ void MEDLoaderNS::writeUMeshDirectly(const char *fileName, ParaMEDMEM::MEDCoupli *work='X'+i; std::fill(unit,unit+2*MED_TAILLE_PNOM+1,'\0'); MEDcoordEcr(fid,maa,mesh->getSpaceDimension(),arr->getPointer(),MED_FULL_INTERLACE,mesh->getNumberOfNodes(),MED_CART,comp,unit); + delete [] maa; + delete [] desc; MEDfermer(fid); } /*! * In this method meshes are assumed to shared the same coords. + * This method makes the assumption that 'meshes' is not empty, no check on that is done (responsability of the caller) */ void MEDLoaderNS::writeUMeshesDirectly(const char *fileName, const char *meshName, const std::vector& meshes, bool forceFromScratch) { - med_idt fid=MEDouvrir((char *)fileName,forceFromScratch?MED_CREATION:MED_LECTURE_ECRITURE); - char maa[MED_TAILLE_NOM+1]; + std::string meshNameCpp(meshName); + char *maa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); strcpy(maa,meshName); - //MEDmaaCr(fid,maa,mesh->getSpaceDimension(),MED_NON_STRUCTURE,maa); - //MEDdimEspaceCr(fid,maa,mesh->getSpaceDimension()); - MEDfermer(fid); + if(meshName=="") + throw INTERP_KERNEL::Exception("writeUMeshesDirectly : Invalid meshName : Must be different from \"\" !"); + //MEDnumEcr(fid,maa,num,nele,_type_ent,typ_geo); + std::vector< DataArrayInt * > corr; + MEDCouplingUMesh *m=ParaMEDMEM::MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,0,corr); + m->setName(meshName); + std::vector< std::vector > fidsOfGroups; + DataArrayInt *arr2=DataArrayInt::makePartition(corr,m->getNumberOfCells(),fidsOfGroups); + for(std::vector< DataArrayInt * >::iterator it=corr.begin();it!=corr.end();it++) + (*it)->decrRef(); + writeUMeshDirectly(fileName,m,arr2,forceFromScratch); + // families creation + std::set familyIds; + for(std::vector< std::vector >::const_iterator it1=fidsOfGroups.begin();it1!=fidsOfGroups.end();it1++) + for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + familyIds.insert(*it2); + std::vector< std::vector > gidsOfFamilies(familyIds.size()); + int fid=0; + for(std::set::const_iterator it=familyIds.begin();it!=familyIds.end();it++,fid++) + { + int gid=0; + for(std::vector< std::vector >::const_iterator it1=fidsOfGroups.begin();it1!=fidsOfGroups.end();it1++,gid++) + for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + if(*it2==*it) + gidsOfFamilies[fid].push_back(gid); + } + fid=0; + med_idt fid2=MEDouvrir((char *)fileName,MED_LECTURE_ECRITURE); + for(std::set::const_iterator it=familyIds.begin();it!=familyIds.end();it++,fid++) + { + int ngro=gidsOfFamilies[fid].size(); + char *groName=MEDLoaderBase::buildEmptyString(MED_TAILLE_LNOM*ngro); + for(int i=0;igetName()); + std::ostringstream oss; oss << "Family_" << *it; + char *famName=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + strcpy(famName,oss.str().c_str()); + MEDfamCr(fid2,maa,famName,*it,0,0,0,0,groName,ngro); + delete [] famName; + delete [] groName; + } + MEDfermer(fid2); + // end families creation + delete [] maa; + arr2->decrRef(); + m->decrRef(); } void MEDLoaderNS::appendFieldDirectly(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f) @@ -1360,7 +1439,7 @@ void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, ParaMEDMEM::ME if(fieldName.empty()) throw INTERP_KERNEL::Exception("Trying to write a field with no name ! MED file format needs a not empty field name !"); MEDCouplingUMesh *mesh=dynamic_cast((MEDCouplingMesh *)f->getMesh()); - writeUMeshDirectly(fileName,mesh,forceFromScratch); + writeUMeshDirectly(fileName,mesh,0,forceFromScratch); appendFieldDirectly(fileName,f); } @@ -1377,19 +1456,19 @@ void MEDLoader::WriteUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *m } if(writeFromScratch) { - MEDLoaderNS::writeUMeshDirectly(fileName,mesh,true); + MEDLoaderNS::writeUMeshDirectly(fileName,mesh,0,true); return ; } if(status==MEDLoaderBase::NOT_EXIST) { - MEDLoaderNS::writeUMeshDirectly(fileName,mesh,true); + MEDLoaderNS::writeUMeshDirectly(fileName,mesh,0,true); return; } else { std::vector meshNames=GetMeshNames(fileName); if(std::find(meshNames.begin(),meshNames.end(),meshName)==meshNames.end()) - MEDLoaderNS::writeUMeshDirectly(fileName,mesh,false); + MEDLoaderNS::writeUMeshDirectly(fileName,mesh,0,false); else { std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \"";