From 756129563a496d52ef4938c45ed484da52aa03e3 Mon Sep 17 00:00:00 2001 From: ageay Date: Tue, 24 Aug 2010 09:31:52 +0000 Subject: [PATCH] Multi mesh with different mesh dim management in writing. --- src/MEDLoader/MEDLoader.cxx | 403 +++++++++++++++++-------- src/MEDLoader/MEDLoader.hxx | 4 +- src/MEDLoader/Swig/MEDLoaderTest.py | 38 ++- src/MEDLoader/Swig/libMEDLoader_Swig.i | 12 +- src/MEDLoader/Test/MEDLoaderTest.cxx | 52 +++- src/MEDLoader/Test/MEDLoaderTest.hxx | 2 + 6 files changed, 373 insertions(+), 138 deletions(-) diff --git a/src/MEDLoader/MEDLoader.cxx b/src/MEDLoader/MEDLoader.cxx index 6738e30fe..1fb93b7fd 100644 --- a/src/MEDLoader/MEDLoader.cxx +++ b/src/MEDLoader/MEDLoader.cxx @@ -150,7 +150,7 @@ namespace MEDLoaderNS 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, DataArrayDouble *&coords, std::list& conn); - int buildMEDSubConnectivityOfOneType(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, INTERP_KERNEL::NormalizedCellType type, + int buildMEDSubConnectivityOfOneType(const std::vector& conn, const std::vector& connIndex, const std::vector& families, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, std::vector& fam4MEDFile, std::vector& renumber); MEDCouplingUMesh *readUMeshFromFileLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& ids, @@ -162,12 +162,12 @@ namespace MEDLoaderNS int *&cellRenum); ParaMEDMEM::DataArrayDouble *buildArrayFromRawData(const std::list& fieldPerType, const std::vector& infos); - int buildMEDSubConnectivityOfOneTypesPolyg(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, + int buildMEDSubConnectivityOfOneTypesPolyg(const std::vector& conn, const std::vector& connIndex, const std::vector& families, std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& fam4MEDFile, std::vector& renumber); - int buildMEDSubConnectivityOfOneTypesPolyh(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, std::vector& conn4MEDFile, - std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, + int buildMEDSubConnectivityOfOneTypesPolyh(const std::vector&conn, const std::vector& connIndex, const std::vector& families, + std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, std::vector& fam4MEDFile, std::vector& renumber); - int buildMEDSubConnectivityOfOneTypeStaticTypes(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, + int buildMEDSubConnectivityOfOneTypeStaticTypes(const std::vector& conn, const std::vector& connIndex, const std::vector& families, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, std::vector& fam4MEDFile, std::vector& renumber); ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField); @@ -180,8 +180,8 @@ namespace MEDLoaderNS void appendCellProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIds); void prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *cellIds, std::list& split); void fillGaussDataOnField(const char *fileName, const std::list& data, MEDCouplingFieldDouble *f); - void writeUMeshDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, const DataArrayInt *families, bool forceFromScratch, bool &isRenumbering); - void writeUMeshesDirectly(const char *fileName, const char *meshName, const std::vector& meshes, bool forceFromScratch); + void writeUMeshesDirectly(const char *fileName, const std::vector& mesh, const std::vector& families, bool forceFromScratch, bool &isRenumbering); + void writeUMeshesPartitionDirectly(const char *fileName, const char *meshName, const std::vector& meshes, bool forceFromScratch); void writeFieldAndMeshDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch); void writeFieldTryingToFitExistingMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f); } @@ -298,8 +298,50 @@ void MEDLoaderNS::fillGaussDataOnField(const char *fileName, const std::list MEDLoader::GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); std::vector ret=MEDLoaderNS::getMeshNamesFid(fid); MEDfermer(fid); @@ -308,6 +350,7 @@ std::vector MEDLoader::GetMeshNames(const char *fileName) throw(INT std::vector MEDLoader::GetMeshFamilyNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); med_int nfam=MEDnFam(fid,(char *)meshName); std::vector ret(nfam); @@ -335,6 +378,7 @@ std::vector MEDLoader::GetMeshFamilyNames(const char *fileName, con std::vector MEDLoader::GetMeshGroupsNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); med_int nfam=MEDnFam(fid,(char *)meshName); std::vector ret; @@ -366,6 +410,7 @@ std::vector MEDLoader::GetMeshGroupsNames(const char *fileName, con std::vector MEDLoader::GetCellFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); std::vector ret; med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); med_int nbFields=MEDnChamp(fid,0); @@ -416,6 +461,7 @@ std::vector MEDLoader::GetCellFieldNamesOnMesh(const char *fileName std::vector MEDLoader::GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); std::vector ret; med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); med_int nbFields=MEDnChamp(fid,0); @@ -460,6 +506,7 @@ std::vector MEDLoader::GetNodeFieldNamesOnMesh(const char *fileName std::vector< std::pair > MEDLoader::GetFieldIterations(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); switch(type) { case ON_CELLS: @@ -473,6 +520,7 @@ std::vector< std::pair > MEDLoader::GetFieldIterations(ParaMEDMEM::Type std::vector< std::pair > MEDLoader::GetCellFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); std::string meshNameCpp(meshName); std::vector< std::pair > ret; med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); @@ -524,6 +572,7 @@ std::vector< std::pair > MEDLoader::GetCellFieldIterations(const char * std::vector< std::pair > MEDLoader::GetNodeFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); std::string meshNameCpp(meshName); std::vector< std::pair > ret; med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); @@ -1137,10 +1186,10 @@ 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. + * This method builds a sub set of connectivity for a given type 'type'. \b WARNING connV,connVIndex and familiesV must have same size ! + * @param connV input containing connectivity with MEDCoupling format. + * @param connVIndex input containing connectivity index in MEDCoupling format. + * @param familiesV 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). @@ -1148,102 +1197,129 @@ namespace MEDLoaderNS * @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, const DataArrayInt *families, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, - std::vector& fam4MEDFile, std::vector& renumber) +int MEDLoaderNS::buildMEDSubConnectivityOfOneTypeStaticTypes(const std::vector& connV, const std::vector& connVIndex, const std::vector& familiesV, + INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, std::vector& fam4MEDFile, std::vector& renumber) { 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;igetNbOfElems()-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(),1)); return ret; } -int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyg(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, - std::vector& fam4MEDFile, std::vector& renumber) +int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyg(const std::vector&connV, const std::vector& connVIndex, const std::vector& familiesV, + std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& fam4MEDFile, std::vector& renumber) { int ret=0; - int nbOfElem=connIndex->getNbOfElems()-1; - const int *connPtr=conn->getConstPointer(); - const int *connIdxPtr=connIndex->getConstPointer(); + int nbOfMeshes=connV.size(); connIndex4MEDFile.push_back(1); - const int *famPtr=0; - if(families) - famPtr=families->getConstPointer(); - for(int i=0;igetNbOfElems()-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(),1)); return ret; } -int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyh(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, +int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyh(const std::vector& connV, const std::vector& connVIndex, const std::vector& familiesV, std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, std::vector& fam4MEDFile, std::vector& renumber) { int ret=0; - int nbOfElem=connIndex->getNbOfElems()-1; - const int *connPtr=conn->getConstPointer(); - const int *connIdxPtr=connIndex->getConstPointer(); + int nbOfMeshes=connV.size(); connIndexRk24MEDFile.push_back(1); connIndex4MEDFile.push_back(1); - const int *famPtr=0; - if(families) - famPtr=families->getConstPointer(); - for(int i=0;igetNbOfElems()-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(),1)); return ret; @@ -1261,7 +1337,7 @@ int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyh(const DataArrayInt *conn * @param fam4MEDFile output containing families id of cells whose type is 'type'. * @return nb of elements extracted. */ -int MEDLoaderNS::buildMEDSubConnectivityOfOneType(const DataArrayInt *conn, const DataArrayInt *connIndex, const DataArrayInt *families, +int MEDLoaderNS::buildMEDSubConnectivityOfOneType(const std::vector& conn, const std::vector& connIndex, const std::vector& families, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, std::vector& fam4MEDFile, std::vector& renumber) { @@ -1395,6 +1471,7 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev1(const char MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); std::vector familiesToKeep; std::vector typesToKeep; unsigned meshDim; @@ -1410,6 +1487,7 @@ MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, const char ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); std::vector familiesToKeep; std::vector typesToKeep; unsigned meshDim; @@ -1425,12 +1503,14 @@ ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, int MEDLoader::ReadUMeshDimFromFile(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); 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) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); std::vector familiesToKeep=MEDLoaderNS::getIdsFromFamilies(fileName,meshName,fams); std::vector typesToKeep; unsigned meshDim; @@ -1448,6 +1528,7 @@ ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFamilies(const char *fileN ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& grps) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); std::vector familiesToKeep=MEDLoaderNS::getIdsFromGroups(fileName,meshName,grps); std::vector typesToKeep; unsigned meshDim; @@ -1465,6 +1546,7 @@ ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const char *fileNam ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDouble(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); switch(type) { case ON_CELLS: @@ -1483,6 +1565,7 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDouble(ParaMEDMEM::TypeO std::vector MEDLoader::ReadFieldsDoubleOnSameMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, const std::vector >& its) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); std::vector ret(its.size()); if(its.empty()) return ret; @@ -1572,62 +1655,75 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDoubleGaussNE(const char * @param families input parameter that specifies the field on int on each cells of 'mesh'. * @param isRenumbering output parameter that specifies if a renumbering of mesh has been needed. */ -void MEDLoaderNS::writeUMeshDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, const DataArrayInt *families, bool forceFromScratch, bool &isRenumbering) +void MEDLoaderNS::writeUMeshesDirectly(const char *fileName, const std::vector& mesh, const std::vector& families, bool forceFromScratch, bool &isRenumbering) { med_idt fid=MEDouvrir((char *)fileName,forceFromScratch?MED_CREATION:MED_LECTURE_ECRITURE); - std::string meshName(mesh->getName()); + std::string meshName(mesh[0]->getName()); if(meshName=="") { MEDfermer(fid); throw INTERP_KERNEL::Exception("MEDCouplingMesh must have a not null name !"); } - isRenumbering=!mesh->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2); + isRenumbering=false; + bool isFamilies=true; + std::vector conn; + std::vector connIndex; + std::set allTypes; + for(std::vector::const_iterator iter=mesh.begin();iter!=mesh.end();iter++) + { + isRenumbering|=!(*iter)->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2); + isFamilies&=(families[std::distance(mesh.begin(),iter)]!=0); + conn.push_back((*iter)->getNodalConnectivity()); + connIndex.push_back((*iter)->getNodalConnectivityIndex()); + const std::set& curTypes=(*iter)->getAllTypes(); + allTypes.insert(curTypes.begin(),curTypes.end()); + } char *maa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); char *desc=MEDLoaderBase::buildEmptyString(MED_TAILLE_DESC); MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_TAILLE_NOM,maa,MEDLoader::_TOO_LONG_STR); MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_TAILLE_DESC,desc,MEDLoader::_TOO_LONG_STR); - const int spaceDim=mesh->getSpaceDimension(); + const int spaceDim=mesh[0]->getSpaceDimension(); MEDmaaCr(fid,maa,spaceDim,MED_NON_STRUCTURE,desc); MEDdimEspaceCr(fid,maa,spaceDim); - std::set allTypes(mesh->getAllTypes()); - const DataArrayInt *conn=mesh->getNodalConnectivity(); - const DataArrayInt *connIndex=mesh->getNodalConnectivityIndex(); - char familyName[MED_TAILLE_NOM+1]; - std::fill(familyName,familyName+MED_TAILLE_NOM+1,'\0'); - const char DftFamilyName[]="DftFamily"; - std::copy(DftFamilyName,DftFamilyName+sizeof(DftFamilyName),familyName); - for(int i=0;i::const_iterator iter=mesh.begin();iter!=mesh.end();iter++) { - med_geometrie_element curMedType=typmai[i]; - INTERP_KERNEL::NormalizedCellType curType=typmai2[i]; - if(allTypes.find(curType)!=allTypes.end()) + for(int i=0;i medConn; - std::vector medConnIndex; - std::vector medConnIndex2; - std::vector fam; - std::vector renumber; - int nbOfElt=MEDLoaderNS::buildMEDSubConnectivityOfOneType(conn,connIndex,families,curType,medConn,medConnIndex,medConnIndex2,fam,renumber); - if(curMedType!=MED_POLYGONE && curMedType!=MED_POLYEDRE) - MEDconnEcr(fid,maa,mesh->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD); - else + med_geometrie_element curMedType=typmai[i]; + INTERP_KERNEL::NormalizedCellType curType=typmai2[i]; + if(allTypes.find(curType)!=allTypes.end()) { - if(curMedType==MED_POLYGONE) - MEDpolygoneConnEcr(fid,maa,&medConnIndex[0],medConnIndex.size(),&medConn[0],MED_MAILLE,MED_NOD); - if(curMedType==MED_POLYEDRE) + std::vector medConn; + std::vector medConnIndex; + std::vector medConnIndex2; + std::vector fam; + std::vector renumber; + int nbOfElt=MEDLoaderNS::buildMEDSubConnectivityOfOneType(conn,connIndex,families,curType,medConn,medConnIndex,medConnIndex2,fam,renumber); + if(curMedType!=MED_POLYGONE && curMedType!=MED_POLYEDRE) + MEDconnEcr(fid,maa,(*iter)->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD); + else { - MEDpolyedreConnEcr(fid,maa,&medConnIndex2[0],medConnIndex2.size(),&medConnIndex[0],medConnIndex.size(), - &medConn[0],MED_NOD); + if(curMedType==MED_POLYGONE) + MEDpolygoneConnEcr(fid,maa,&medConnIndex[0],medConnIndex.size(),&medConn[0],MED_MAILLE,MED_NOD); + if(curMedType==MED_POLYEDRE) + { + MEDpolyedreConnEcr(fid,maa,&medConnIndex2[0],medConnIndex2.size(),&medConnIndex[0],medConnIndex.size(), + &medConn[0],MED_NOD); + } } + if(isFamilies) + MEDfamEcr(fid,maa,&fam[0],nbOfElt,MED_MAILLE,curMedType); + if(isRenumbering) + MEDnumEcr(fid,maa,&renumber[0],nbOfElt,MED_MAILLE,curMedType); } - if(families) - MEDfamEcr(fid,maa,&fam[0],nbOfElt,MED_MAILLE,curMedType); - if(isRenumbering) - MEDnumEcr(fid,maa,&renumber[0],nbOfElt,MED_MAILLE,curMedType); } } + char familyName[MED_TAILLE_NOM+1]; + std::fill(familyName,familyName+MED_TAILLE_NOM+1,'\0'); + const char DftFamilyName[]="DftFamily"; + std::copy(DftFamilyName,DftFamilyName+sizeof(DftFamilyName),familyName); MEDfamCr(fid,maa,familyName,0,0,0,0,0,0,0); - DataArrayDouble *arr=mesh->getCoords(); + DataArrayDouble *arr=mesh[0]->getCoords(); char *comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM); char *unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM); for(int i=0;igetSpaceDimension(),arr->getPointer(),MED_FULL_INTERLACE,mesh->getNumberOfNodes(),MED_CART,comp,unit); + MEDcoordEcr(fid,maa,spaceDim,arr->getPointer(),MED_FULL_INTERLACE,mesh[0]->getNumberOfNodes(),MED_CART,comp,unit); delete [] comp; delete [] unit; delete [] maa; @@ -1650,14 +1746,13 @@ void MEDLoaderNS::writeUMeshDirectly(const char *fileName, const ParaMEDMEM::MED * 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) +void MEDLoaderNS::writeUMeshesPartitionDirectly(const char *fileName, const char *meshName, const std::vector& meshes, bool forceFromScratch) { std::string meshNameCpp(meshName); char *maa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); MEDLoaderBase::safeStrCpy(meshName,MED_TAILLE_NOM,maa,MEDLoader::_TOO_LONG_STR); if(meshName=="") - throw INTERP_KERNEL::Exception("writeUMeshesDirectly : Invalid meshName : Must be different from \"\" !"); - //MEDnumEcr(fid,maa,num,nele,_type_ent,typ_geo); + throw INTERP_KERNEL::Exception("writeUMeshesPartitionDirectly : Invalid meshName : Must be different from \"\" !"); std::vector< DataArrayInt * > corr; MEDCouplingUMesh *m=ParaMEDMEM::MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,0,corr); m->setName(meshName); @@ -1666,7 +1761,9 @@ void MEDLoaderNS::writeUMeshesDirectly(const char *fileName, const char *meshNam for(std::vector< DataArrayInt * >::iterator it=corr.begin();it!=corr.end();it++) (*it)->decrRef(); bool isRenumbering; - writeUMeshDirectly(fileName,m,arr2,forceFromScratch,isRenumbering); + std::vector mv(1); mv[0]=m; + std::vector famv(1); famv[0]=arr2; + writeUMeshesDirectly(fileName,mv,famv,forceFromScratch,isRenumbering); // families creation std::set familyIds; for(std::vector< std::vector >::const_iterator it1=fidsOfGroups.begin();it1!=fidsOfGroups.end();it1++) @@ -1931,7 +2028,9 @@ void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, const ParaMEDM if(mesh) { bool isRenumbering; - writeUMeshDirectly(fileName,mesh,0,forceFromScratch,isRenumbering); + std::vector meshV(1); meshV[0]=mesh; + std::vector famV(1); famV[0]=0; + writeUMeshesDirectly(fileName,meshV,famV,forceFromScratch,isRenumbering); if(isRenumbering) { ParaMEDMEM::MEDCouplingFieldDouble *f2=f->clone(true); @@ -1969,8 +2068,9 @@ void MEDLoaderNS::writeFieldTryingToFitExistingMesh(const char *fileName, const MEDCouplingUMesh *m=MEDLoader::ReadUMeshFromFile(fileName,f->getMesh()->getName(),f2); MEDCouplingUMesh *m2=MEDCouplingUMesh::mergeUMeshes(m,(MEDCouplingUMesh *)f->getMesh()); bool areNodesMerged; - DataArrayInt *da=m2->mergeNodes(MEDLoader::_EPS_FOR_NODE_COMP,areNodesMerged); - if(!areNodesMerged || m2->getNumberOfNodes()!=m->getNumberOfNodes()) + int newNbOfNodes; + DataArrayInt *da=m2->mergeNodes(MEDLoader::_EPS_FOR_NODE_COMP,areNodesMerged,newNbOfNodes); + if(!areNodesMerged || newNbOfNodes!=m->getNumberOfNodes()) { da->decrRef(); m2->decrRef(); @@ -2031,21 +2131,23 @@ void MEDLoader::WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUM std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + std::vector meshV(1); meshV[0]=mesh; + std::vector famV(1); famV[0]=0; if(writeFromScratch) { - MEDLoaderNS::writeUMeshDirectly(fileName,mesh,0,true,isRenumbering); + MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering); return ; } if(status==MEDLoaderBase::NOT_EXIST) { - MEDLoaderNS::writeUMeshDirectly(fileName,mesh,0,true,isRenumbering); + MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering); return; } else { std::vector meshNames=GetMeshNames(fileName); if(std::find(meshNames.begin(),meshNames.end(),meshName)==meshNames.end()) - MEDLoaderNS::writeUMeshDirectly(fileName,mesh,0,false,isRenumbering); + MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,false,isRenumbering); else { std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \""; @@ -2055,7 +2157,7 @@ void MEDLoader::WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUM } } -void MEDLoader::WriteUMeshes(const char *fileName, const char *meshNameC, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception) +void MEDLoader::WriteUMeshesPartition(const char *fileName, const char *meshNameC, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception) { std::string meshName(meshNameC); if(meshName.empty()) @@ -2083,19 +2185,19 @@ void MEDLoader::WriteUMeshes(const char *fileName, const char *meshNameC, const tmp.clear(); if(writeFromScratch) { - MEDLoaderNS::writeUMeshesDirectly(fileName,meshNameC,meshes,true); + MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true); return ; } if(status==MEDLoaderBase::NOT_EXIST) { - MEDLoaderNS::writeUMeshesDirectly(fileName,meshNameC,meshes,true); + MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true); return; } else { std::vector meshNames=GetMeshNames(fileName); if(std::find(meshNames.begin(),meshNames.end(),meshName)==meshNames.end()) - MEDLoaderNS::writeUMeshesDirectly(fileName,meshNameC,meshes,false); + MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,false); else { std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \""; @@ -2105,6 +2207,48 @@ void MEDLoader::WriteUMeshes(const char *fileName, const char *meshNameC, const } } +void MEDLoader::WriteUMeshes(const char *fileName, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception) +{ + int status=MEDLoaderBase::getStatusOfFile(fileName); + if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) + { + std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(meshes.empty()) + throw INTERP_KERNEL::Exception("List of meshes must be not empty !"); + DataArrayDouble *coords=meshes.front()->getCoords(); + for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) + if(coords!=(*iter)->getCoords()) + throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !"); + std::set tmp; + for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) + { + if(tmp.find((*iter)->getMeshDimension())==tmp.end()) + tmp.insert((*iter)->getMeshDimension()); + else + throw INTERP_KERNEL::Exception("The mesh dimension of meshes must be different each other !"); + } + tmp.clear(); + bool isRenumbering; + std::vector families(meshes.size()); + if(writeFromScratch) + { + MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,true,isRenumbering); + return ; + } + if(status==MEDLoaderBase::NOT_EXIST) + { + MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,true,isRenumbering); + return; + } + else + { + MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,false,isRenumbering); + return; + } +} + void MEDLoader::WriteField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception) { int status=MEDLoaderBase::getStatusOfFile(fileName); @@ -2131,9 +2275,6 @@ void MEDLoader::WriteField(const char *fileName, const ParaMEDMEM::MEDCouplingFi MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,false); else 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 8ff9cad17..549c29364 100644 --- a/src/MEDLoader/MEDLoader.hxx +++ b/src/MEDLoader/MEDLoader.hxx @@ -85,6 +85,7 @@ class MEDLOADER_EXPORT MEDLoader static void setEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception); static void setCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception); static void setTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception); + static void CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception); static std::vector GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception); static std::vector GetMeshGroupsNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); static std::vector GetMeshFamilyNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); @@ -114,7 +115,8 @@ class MEDLOADER_EXPORT MEDLoader static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleGauss(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleGaussNE(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); static void WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); - static void WriteUMeshes(const char *fileName, const char *meshName, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteUMeshesPartition(const char *fileName, const char *meshName, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteUMeshes(const char *fileName, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception); static void WriteField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception); static void WriteFieldUsingAlreadyWrittenMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception); private: diff --git a/src/MEDLoader/Swig/MEDLoaderTest.py b/src/MEDLoader/Swig/MEDLoaderTest.py index a31dfbbae..ca10477b9 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest.py +++ b/src/MEDLoader/Swig/MEDLoaderTest.py @@ -224,7 +224,7 @@ class MEDLoaderTest(unittest.TestCase): mesh4.setCoords(mesh1.getCoords()); meshes=[mesh1,mesh2,mesh3,mesh4] mnane="3DToto"; - MEDLoader.WriteUMeshes(fileName,mnane,meshes,True); + MEDLoader.WriteUMeshesPartition(fileName,mnane,meshes,True); # mesh5=MEDLoader.ReadUMeshFromFile(fileName,mnane); mesh1.setName(mnane); @@ -262,7 +262,7 @@ class MEDLoaderTest(unittest.TestCase): def testFieldProfilRW1(self): fileName="Pyfile12.med"; mesh1=MEDLoaderDataForTest.build3DMesh_1(); - da,b=mesh1.mergeNodes(1e-12); + da,b,newNbOfNodes=mesh1.mergeNodes(1e-12); MEDLoader.WriteUMesh(fileName,mesh1,True); part1=[1,2,4,13,15] mesh2=mesh1.buildPartOfMySelf(part1,True); @@ -349,6 +349,40 @@ class MEDLoaderTest(unittest.TestCase): self.assertTrue(fs[1].isEqual(f_2,1e-12,1e-12)); self.assertTrue(fs[2].isEqual(f_3,1e-12,1e-12)); pass + + def testWriteUMeshesRW1(self): + fileName="Pyfile18.med"; + m3d=MEDLoaderDataForTest.build3DMesh_2(); + pt=[0.,0.,-0.3] + vec=[0.,0.,1.] + nodes=m3d.findNodesOnPlane(pt,vec,1e-12); + m2d=m3d.buildFacePartOfMySelfNode(nodes,True); + m2d.setName("ExampleOfMultiDimW"); + meshes=[m2d,m3d] + MEDLoader.WriteUMeshes(fileName,meshes,True); + m3d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),0); + self.assertTrue(not m3d_bis.isEqual(m3d,1e-12)); + m3d_bis.setName(m3d.getName()); + self.assertTrue(m3d_bis.isEqual(m3d,1e-12)); + m2d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),-1);#-1 for faces + self.assertTrue(m2d_bis.isEqual(m2d,1e-12)); + # Creation of a field on faces. + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setName("FieldOnFacesShuffle"); + f1.setMesh(m2d); + array=DataArrayDouble.New(); + arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] + array.setValues(arr1,m2d.getNumberOfCells(),2); + array.setInfoOnComponent(0,"plkj (mm)"); + array.setInfoOnComponent(1,"pqqqss (mm)"); + f1.setArray(array); + tmp=array.setValues(arr1,m2d.getNumberOfCells(),2); + f1.setTime(3.14,2,7); + f1.checkCoherency(); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f2=MEDLoader.ReadFieldDoubleCell(fileName,f1.getMesh().getName(),-1,f1.getName(),2,7); + self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); + pass pass unittest.main() diff --git a/src/MEDLoader/Swig/libMEDLoader_Swig.i b/src/MEDLoader/Swig/libMEDLoader_Swig.i index c4aae1cb7..683d3f26c 100644 --- a/src/MEDLoader/Swig/libMEDLoader_Swig.i +++ b/src/MEDLoader/Swig/libMEDLoader_Swig.i @@ -48,6 +48,7 @@ public: static void setEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception); static void setCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception); static void setTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception); + static void CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception); static std::vector GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception); static std::vector GetMeshGroupsNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); static std::vector GetMeshFamilyNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); @@ -105,10 +106,17 @@ public: std::vector res=MEDLoader::ReadFieldsDoubleOnSameMesh(type,fileName,meshName,meshDimRelToMax,fieldName,its); return convertFieldDoubleVecToPy(res); } - static void WriteUMeshes(const char *fileName, const char *meshName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) + static void WriteUMeshesPartition(const char *fileName, const char *meshName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) { std::vector v=convertFieldDoubleVecFromPy(li); - MEDLoader::WriteUMeshes(fileName,meshName,v,writeFromScratch); + MEDLoader::WriteUMeshesPartition(fileName,meshName,v,writeFromScratch); + } + + static void WriteUMeshes(const char *fileName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) + { + std::vector v=convertFieldDoubleVecFromPy(li); + std::vector v2(v.begin(),v.end()); + MEDLoader::WriteUMeshes(fileName,v2,writeFromScratch); } } static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& fams) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDLoader/Test/MEDLoaderTest.cxx b/src/MEDLoader/Test/MEDLoaderTest.cxx index 7814638f5..4abbf0d96 100644 --- a/src/MEDLoader/Test/MEDLoaderTest.cxx +++ b/src/MEDLoader/Test/MEDLoaderTest.cxx @@ -282,7 +282,7 @@ void MEDLoaderTest::testMultiMeshRW1() meshes.push_back(mesh3); meshes.push_back(mesh4); const char mnane[]="3DToto"; - MEDLoader::WriteUMeshes(fileName,mnane,meshes,true); + MEDLoader::WriteUMeshesPartition(fileName,mnane,meshes,true); // MEDCouplingUMesh *mesh5=MEDLoader::ReadUMeshFromFile(fileName,mnane); mesh1->setName(mnane); @@ -335,7 +335,8 @@ void MEDLoaderTest::testFieldProfilRW1() const char fileName[]="file12.med"; MEDCouplingUMesh *mesh1=build3DMesh_1(); bool b; - DataArrayInt *da=mesh1->mergeNodes(1e-12,b); + int newNbOfNodes; + DataArrayInt *da=mesh1->mergeNodes(1e-12,b,newNbOfNodes); da->decrRef(); MEDLoader::WriteUMesh(fileName,mesh1,true); const int part1[5]={1,2,4,13,15}; @@ -492,6 +493,53 @@ void MEDLoaderTest::testMultiFieldShuffleRW1() m->decrRef(); } +void MEDLoaderTest::testWriteUMeshesRW1() +{ + const char fileName[]="file18.med"; + MEDCouplingUMesh *m3d=build3DMesh_2(); + const double pt[3]={0.,0.,-0.3}; + const double vec[3]={0.,0.,1.}; + std::vector nodes; + m3d->findNodesOnPlane(pt,vec,1e-12,nodes); + MEDCouplingUMesh *m2d=(MEDCouplingUMesh *)m3d->buildFacePartOfMySelfNode(&nodes[0],&nodes[0]+nodes.size(),true); + m2d->setName("ExampleOfMultiDimW"); + std::vector meshes; + meshes.push_back(m2d); + meshes.push_back(m3d); + MEDLoader::WriteUMeshes(fileName,meshes,true); + MEDCouplingUMesh *m3d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName(),0); + CPPUNIT_ASSERT(!m3d_bis->isEqual(m3d,1e-12)); + m3d_bis->setName(m3d->getName()); + CPPUNIT_ASSERT(m3d_bis->isEqual(m3d,1e-12)); + MEDCouplingUMesh *m2d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName(),-1);//-1 for faces + CPPUNIT_ASSERT(m2d_bis->isEqual(m2d,1e-12)); + // Creation of a field on faces. + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("FieldOnFacesShuffle"); + f1->setMesh(m2d); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(m2d->getNumberOfCells(),2); + array->setInfoOnComponent(0,"plkj (mm)"); + array->setInfoOnComponent(1,"pqqqss (mm)"); + 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::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldDoubleCell(fileName,f1->getMesh()->getName(),-1,f1->getName(),2,7); + CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); + f1->decrRef(); + f2->decrRef(); + // + m2d_bis->decrRef(); + m3d_bis->decrRef(); + m2d->decrRef(); + m3d->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 d8d50c2dd..fce8a331b 100644 --- a/src/MEDLoader/Test/MEDLoaderTest.hxx +++ b/src/MEDLoader/Test/MEDLoaderTest.hxx @@ -46,6 +46,7 @@ namespace ParaMEDMEM CPPUNIT_TEST( testMesh3DSurfShuffleRW ); CPPUNIT_TEST( testFieldShuffleRW1 ); CPPUNIT_TEST( testMultiFieldShuffleRW1 ); + CPPUNIT_TEST( testWriteUMeshesRW1 ); CPPUNIT_TEST_SUITE_END(); public: void testMesh1DRW(); @@ -64,6 +65,7 @@ namespace ParaMEDMEM void testMesh3DSurfShuffleRW(); void testFieldShuffleRW1(); void testMultiFieldShuffleRW1(); + void testWriteUMeshesRW1(); private: MEDCouplingUMesh *build1DMesh_1(); MEDCouplingUMesh *build2DCurveMesh_1(); -- 2.39.2