-// Copyright (C) 2007-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2007-2019 CEA/DEN, EDF R&D
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// Author : Anthony Geay (CEA/DEN)
#include "MEDFileMesh.hxx"
-#include "MEDFileUtilities.hxx"
#include "MEDFileFieldOverView.hxx"
#include "MEDFileField.hxx"
#include "MEDLoader.hxx"
+#include "MEDLoaderNS.hxx"
#include "MEDFileSafeCaller.txx"
#include "MEDLoaderBase.hxx"
#include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingMappedExtrudedMesh.hxx"
#include "InterpKernelAutoPtr.hxx"
#include <limits>
#include <cmath>
+extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
+extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
extern med_geometry_type typmai3[34];
using namespace MEDCoupling;
const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
+const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
+
MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
{
}
*/
MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
{
- std::vector<std::string> ms=MEDCoupling::GetMeshNames(fileName);
+ MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+ return New(fid,mrs);
+}
+
+MEDFileMesh *MEDFileMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+ std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
if(ms.empty())
{
- std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
+ std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
- MEDFileUtilities::CheckFileForRead(fileName);
MEDCoupling::MEDCouplingMeshType meshType;
- MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
int dt,it;
std::string dummy2;
MEDCoupling::MEDCouplingAxisType dummy3;
*/
MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
{
- MEDFileUtilities::CheckFileForRead(fileName);
+ MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+ return New(fid,mName,dt,it,mrs,joints);
+}
+
+MEDFileMesh *MEDFileMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
+{
MEDCoupling::MEDCouplingMeshType meshType;
- MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
int dummy0,dummy1;
std::string dummy2;
MEDCoupling::MEDCouplingAxisType dummy3;
* \throw If the file is open for reading only.
* \throw If the writing mode == 1 and the same data is present in an existing file.
*/
-void MEDFileMesh::write(med_idt fid) const
+void MEDFileMesh::writeLL(med_idt fid) const
{
if(!existsFamily(0))
const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
if(_name.empty())
throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
- writeLL(fid);
+ writeMeshLL(fid);
writeJoints(fid);
const MEDFileEquivalences *eqs(_equiv);
if(eqs)
- eqs->write(fid);
-}
-
-/*!
- * Writes \a this mesh into a MED file specified by its name.
- * \param [in] fileName - the MED file name.
- * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
- * - 2 - erase; an existing file is removed.
- * - 1 - append; same data should not be present in an existing file.
- * - 0 - overwrite; same data present in an existing file is overwritten.
- * \throw If the mesh name is not set.
- * \throw If \a mode == 1 and the same data is present in an existing file.
- */
-void MEDFileMesh::write(const std::string& fileName, int mode) const
-{
- med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
- MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
- std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
- MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
- write(fid);
+ eqs->writeLL(fid);
}
/*!
* Returns names of all families of \a this mesh but like they would be in file.
* This method is here only for MED file families gurus. If you are a kind user forget this method :-)
* This method is only useful for aggressive users that want to have in their file a same family lying both on cells and on nodes. This is not a good idea for lisibility !
- * For your information internaly in memory such families are renamed to have a nicer API.
+ * For your information internally in memory such families are renamed to have a nicer API.
*/
std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
{
return ret;
}
+void MEDFileMesh::removeGroupAtLevel(int meshDimRelToMaxExt, const std::string& name)
+{
+ std::map<std::string, std::vector<std::string> >::iterator it(_groups.find(name));
+ std::vector<std::string> grps(getGroupsNames());
+ if(it==_groups.end())
+ {
+ std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
+ std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ const std::vector<std::string> &famsOnGrp((*it).second);
+ std::vector<int> famIds(getFamiliesIdsOnGroup(name));
+ const DataArrayInt *famArr(getFamilyFieldAtLevel(meshDimRelToMaxExt));
+ if(!famArr)
+ return ;
+ MCAuto<DataArrayInt> vals(famArr->getDifferentValues());
+ MCAuto<DataArrayInt> famIds2(DataArrayInt::NewFromStdVector(famIds));
+ MCAuto<DataArrayInt> idsToKill(famIds2->buildIntersection(vals));
+ if(idsToKill->empty())
+ return ;
+ std::vector<std::string> newFamsOnGrp;
+ for(std::vector<std::string>::const_iterator it=famsOnGrp.begin();it!=famsOnGrp.end();it++)
+ {
+ if(!idsToKill->presenceOfValue(getFamilyId(*it)))
+ newFamsOnGrp.push_back(*it);
+ }
+ (*it).second=newFamsOnGrp;
+}
+
/*!
* Removes a group from \a this mesh.
* \param [in] name - the name of the group to remove.
*/
void MEDFileMesh::removeGroup(const std::string& name)
{
- std::string oname(name);
- std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
- std::vector<std::string> grps=getGroupsNames();
+ std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(name);
+ std::vector<std::string> grps(getGroupsNames());
if(it==_groups.end())
{
std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
* family field whatever its level. Groups are updated in consequence, that is to say all groups lying on orphan family, will see their families list modified.
*
* \return - The list of removed families names.
- * \sa MEDFileMesh::removeOrphanGroups.
+ * \sa MEDFileMesh::removeOrphanGroups , MEDFileMesh::removeFamiliesReferedByNoGroups
*/
std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
{
* this family is orphan or not.
*
* \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
+ * \sa MEDFileMesh::removeOrphanFamilies
*/
void MEDFileMesh::removeFamiliesReferedByNoGroups()
{
}
/*!
- * This method has no impact on groups. This method only works on families. This method firstly removes families not refered by any groups in \a this, then all unused entities
+ * This method has no impact on groups. This method only works on families. This method firstly removes families not referred by any groups in \a this, then all unused entities
* are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
* This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
+ *
+ * This method also raises an exception if a family belonging to a group has also id 0 (which is not right in MED file format). You should never encounter this case using addGroup method.
*
- * \sa MEDFileMesh::removeOrphanFamilies
+ * \sa MEDFileMesh::removeOrphanFamilies, MEDFileMesh::zipFamilies
*/
void MEDFileMesh::rearrangeFamilies()
{
std::vector<int> levels(getNonEmptyLevelsExt());
std::set<int> idsRefed;
for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
- idsRefed.insert((*it).second);
+ {
+ idsRefed.insert((*it).second);
+ if((*it).second==0)
+ {
+ if(!getGroupsOnFamily((*it).first).empty())
+ {
+ std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Not orphan family \"" << (*it).first << "\" has id 0 ! This method may alterate groups in this for such a case !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ }
+ }
for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
{
const DataArrayInt *fams(0);
removeOrphanFamilies();
}
+/*!
+ * This method has no impact on existing groups. This method has only impact on families behind the groups.
+ * This method is especially useful for MED file structures having used too much families to define their groups and that need to be merged without modification of their groups.
+ * To zip families, firstly this method first removes families refered by no groups (see MEDFileMesh::removeFamiliesReferedByNoGroups), then this method puts together families lying on a same set of groups. If the set of families having same groups has a length higher than 1, the families are merged into a single family
+ * having the name of the first family appearing in family definition and with the corresponding family ID.
+ */
+void MEDFileMesh::zipFamilies()
+{
+ checkOrphanFamilyZero();
+ removeFamiliesReferedByNoGroups();
+ std::map< std::set<std::string> , std::vector<std::string> > setOfFamilies;
+ // firstly, store in setOfFamilies as key the common set of groups, and as value the families having such same set of groups
+ for(auto fam : _families)
+ {
+ std::vector<std::string> grps( this->getGroupsOnFamily( fam.first ) );
+ std::set<std::string> sgrps(grps.begin(),grps.end());
+ setOfFamilies[sgrps].push_back(fam.first);
+ }
+ //
+ std::map<std::string, std::vector<std::string> > newGroups(_groups);
+ std::map<std::string,int> newFams(_families);
+ std::vector<int> levels(getNonEmptyLevelsExt());
+ std::map<int, std::vector<int> > famIdsToSubstitute;
+ // iterate on all different set of groups
+ std::set<std::string> familiesToKill;
+ for(auto setOfCommonGrp : setOfFamilies)
+ {
+ if( setOfCommonGrp.second.size()<=1 )
+ continue;
+ for(auto fam=setOfCommonGrp.second.begin()+1 ; fam != setOfCommonGrp.second.end() ; fam++)
+ familiesToKill.insert(*fam);
+ }
+ // iterate on all different set of groups
+ for(auto setOfCommonGrp : setOfFamilies)
+ {
+ if( setOfCommonGrp.second.size()<=1 )
+ continue;
+ std::string newFamName(setOfCommonGrp.second[0]);
+ auto newFamID(_families[newFamName]);
+ for(auto grpToBeModified : setOfCommonGrp.first)
+ {
+ std::vector<std::string> newFamiliesForCurGrp(1,newFamName);
+ const std::vector<std::string>& familiesOnCurGrp(_groups[grpToBeModified]);
+ const std::vector<std::string>& familiesToZip(setOfCommonGrp.second);
+ std::for_each(familiesToZip.begin(),familiesToZip.end(),[&famIdsToSubstitute,this,newFamID](const std::string& elt) { famIdsToSubstitute[newFamID].push_back(this->getFamilyId(elt)); });
+ // for each family shared by the current group only keep those not sharing setOfCommonGrp.second
+ std::for_each(familiesOnCurGrp.begin(),familiesOnCurGrp.end(),[&familiesToKill,&newFamiliesForCurGrp](const std::string& elt)
+ { if( familiesToKill.find(elt) == familiesToKill.end() ) { newFamiliesForCurGrp.push_back(elt); } });
+ newGroups[grpToBeModified] = newFamiliesForCurGrp;
+ }
+ for(auto familyToKill = setOfCommonGrp.second.begin()+1 ; familyToKill != setOfCommonGrp.second.end(); ++familyToKill)
+ {
+ newFams.erase( newFams.find(*familyToKill) );
+ }
+
+ }
+ // apply modifications in datastructure
+ for(auto famIdsSubstSession : famIdsToSubstitute)
+ {
+ for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
+ {
+ DataArrayInt *fams(nullptr);
+ try
+ {
+ fams=getFamilyFieldAtLevel(*it);
+ }
+ catch(INTERP_KERNEL::Exception& e) { }
+ if(!fams)
+ continue;
+ MCAuto<DataArrayInt> idsToModif(fams->findIdsEqualList(famIdsSubstSession.second.data(),famIdsSubstSession.second.data()+famIdsSubstSession.second.size()));
+ fams->setPartOfValuesSimple3(famIdsSubstSession.first,idsToModif->begin(),idsToModif->end(),0,1,1);
+ }
+ }
+ _groups = newGroups;
+ _families = newFams;
+}
+
/*!
* This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
*/
}
}
+void MEDFileMesh::checkNoGroupClash(const DataArrayInt *famArr, const std::string& grpName) const
+{
+ std::vector<std::string> grpsNames(getGroupsNames());
+ if(std::find(grpsNames.begin(),grpsNames.end(),grpName)==grpsNames.end())
+ return ;
+ std::vector<int> famIds(getFamiliesIdsOnGroup(grpName));
+ if(famArr->presenceOfValue(famIds))
+ {
+ std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists at specified level ! Destroy it before calling this method !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+}
+
/*!
* \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm).
* \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed)
if(grpName.empty())
throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
ids->checkStrictlyMonotonic(true);
- famArr->incrRef(); MCAuto<DataArrayInt> famArrTmp(famArr);
- std::vector<std::string> grpsNames=getGroupsNames();
- if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
- {
- std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
- throw INTERP_KERNEL::Exception(oss.str().c_str());
- }
+ checkNoGroupClash(famArr,grpName);
+ MCAuto<DataArrayInt> famArrTmp; famArrTmp.takeRef(famArr);
std::list< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
bool isFamPresent=false;
for(std::list< MCAuto<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
isFamPresent=(*itl)->presenceOfValue(*famId);
- if(!isFamPresent)
+ if(!isFamPresent && *famId!=0)
{ familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
else
{
famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
}
_families=families;
+ std::map<std::string, std::vector<std::string> >::iterator itt(groups.find(grpName));
+ if(itt!=groups.end())
+ {
+ std::vector<std::string>& famsOnGrp((*itt).second);
+ famsOnGrp.insert(famsOnGrp.end(),fams.begin(),fams.end());
+ }
+ else
+ groups[grpName]=fams;
_groups=groups;
- _groups[grpName]=fams;
}
void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
*/
int MEDFileMesh::getFamilyId(const std::string& name) const
{
- std::string oname(name);
- std::map<std::string, int>::const_iterator it=_families.find(oname);
- std::vector<std::string> fams=getFamiliesNames();
+ std::map<std::string, int>::const_iterator it=_families.find(name);
if(it==_families.end())
{
+ std::vector<std::string> fams(getFamiliesNames());
std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
throw INTERP_KERNEL::Exception(oss.str().c_str());
return ret;
}
+/*!
+ * \sa getAllDistributionOfTypes
+ */
std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
{
MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
*/
MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
{
- MEDFileUtilities::CheckFileForRead(fileName);
- MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
+ MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+ return New(fid,mName,dt,it,mrs);
+}
+
+MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
return new MEDFileUMesh(fid,mName,dt,it,mrs);
}
*/
MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
{
- std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
+ MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+ return New(fid,mrs);
+}
+
+template<class T>
+T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+ std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
if(ms.empty())
{
- std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
+ std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
- MEDFileUtilities::CheckFileForRead(fileName);
- MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
int dt,it;
MEDCoupling::MEDCouplingMeshType meshType;
std::string dummy2;
MEDCoupling::MEDCouplingAxisType dummy3;
MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
- return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
+ return T::New(fid,ms.front(),dt,it,mrs);
+}
+
+MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+ return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
+}
+
+/*!
+ * \b WARNING this implementation is dependent from MEDCouplingMappedExtrudedMesh::buildUnstructured !
+ * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
+ */
+MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
+{
+ if(!mem)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
+ MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+ MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
+ MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
+ m2D->zipCoords();
+ m2D->setCoords(m3D->getCoords());
+ ret->setMeshAtLevel(0,m3D);
+ ret->setMeshAtLevel(-1,m2D);
+ ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<int>::max()-mem->get2DCellIdForExtrusion());
+ return ret.retn();
}
/*!
std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
{
std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
- ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>));
+ ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
return ret;
}
ret.push_back((const DataArrayDouble*)_coords);
ret.push_back((const DataArrayInt *)_fam_coords);
ret.push_back((const DataArrayInt *)_num_coords);
+ ret.push_back((const DataArrayInt *)_global_num_coords);
ret.push_back((const DataArrayInt *)_rev_num_coords);
ret.push_back((const DataArrayAsciiChar *)_name_coords);
ret.push_back((const PartDefinition *)_part_coords);
for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
ret.push_back((const MEDFileUMeshSplitL1*) *it);
+ for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
+ ret.push_back((const MEDFileEltStruct4Mesh *)*it);
return ret;
}
-MEDFileMesh *MEDFileUMesh::shallowCpy() const
+MEDFileUMesh *MEDFileUMesh::shallowCpy() const
{
MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
return ret.retn();
return new MEDFileUMesh;
}
-MEDFileMesh *MEDFileUMesh::deepCopy() const
+MEDFileUMesh *MEDFileUMesh::deepCopy() const
{
MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
ret->deepCpyEquivalences(*this);
- if((const DataArrayDouble*)_coords)
+ if(_coords.isNotNull())
ret->_coords=_coords->deepCopy();
- if((const DataArrayInt*)_fam_coords)
+ if(_fam_coords.isNotNull())
ret->_fam_coords=_fam_coords->deepCopy();
- if((const DataArrayInt*)_num_coords)
+ if(_num_coords.isNotNull())
ret->_num_coords=_num_coords->deepCopy();
- if((const DataArrayInt*)_rev_num_coords)
+ if(_global_num_coords.isNotNull())
+ ret->_global_num_coords=_global_num_coords->deepCopy();
+ if(_rev_num_coords.isNotNull())
ret->_rev_num_coords=_rev_num_coords->deepCopy();
- if((const DataArrayAsciiChar*)_name_coords)
+ if(_name_coords.isNotNull())
ret->_name_coords=_name_coords->deepCopy();
std::size_t i=0;
for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
return false;
}
}
- const DataArrayInt *famc1=_fam_coords;
- const DataArrayInt *famc2=otherC->_fam_coords;
- if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
- {
- what="Mismatch of families arr on nodes ! One is defined and not other !";
- return false;
- }
- if(famc1)
- {
- bool ret=famc1->isEqual(*famc2);
- if(!ret)
- {
- what="Families arr on node differ !";
- return false;
- }
- }
- const DataArrayInt *numc1=_num_coords;
- const DataArrayInt *numc2=otherC->_num_coords;
- if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
- {
- what="Mismatch of numbering arr on nodes ! One is defined and not other !";
- return false;
- }
- if(numc1)
- {
- bool ret=numc1->isEqual(*numc2);
- if(!ret)
- {
- what="Numbering arr on node differ !";
- return false;
- }
- }
- const DataArrayAsciiChar *namec1=_name_coords;
- const DataArrayAsciiChar *namec2=otherC->_name_coords;
- if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
- {
- what="Mismatch of naming arr on nodes ! One is defined and not other !";
- return false;
- }
- if(namec1)
- {
- bool ret=namec1->isEqual(*namec2);
- if(!ret)
- {
- what="Names arr on node differ !";
- return false;
- }
- }
+ {
+ const DataArrayInt *famc1(_fam_coords),*famc2(otherC->_fam_coords);
+ if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
+ {
+ what="Mismatch of families arr on nodes ! One is defined and not other !";
+ return false;
+ }
+ if(famc1)
+ {
+ bool ret=famc1->isEqual(*famc2);
+ if(!ret)
+ {
+ what="Families arr on node differ !";
+ return false;
+ }
+ }
+ }
+ {
+ const DataArrayInt *numc1(_num_coords),*numc2(otherC->_num_coords);
+ if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
+ {
+ what="Mismatch of numbering arr on nodes ! One is defined and not other !";
+ return false;
+ }
+ if(numc1)
+ {
+ bool ret=numc1->isEqual(*numc2);
+ if(!ret)
+ {
+ what="Numbering arr on node differ !";
+ return false;
+ }
+ }
+ }
+ {
+ const DataArrayInt *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
+ if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
+ {
+ what="Mismatch of numbering arr on nodes ! One is defined and not other !";
+ return false;
+ }
+ if(gnumc1)
+ {
+ bool ret=gnumc1->isEqual(*gnumc2);
+ if(!ret)
+ {
+ what="Global numbering arr on node differ !";
+ return false;
+ }
+ }
+ }
+ {
+ const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
+ if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
+ {
+ what="Mismatch of naming arr on nodes ! One is defined and not other !";
+ return false;
+ }
+ if(namec1)
+ {
+ bool ret=namec1->isEqual(*namec2);
+ if(!ret)
+ {
+ what="Names arr on node differ !";
+ return false;
+ }
+ }
+ }
if(_ms.size()!=otherC->_ms.size())
{
what="Number of levels differs !";
return pd0->isEqual(pd1,what);
}
+/*!
+ * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
+ * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
+ * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
+ * \throw if internal family array is inconsistent
+ * \sa checkSMESHConsistency()
+ */
+void MEDFileUMesh::checkConsistency() const
+{
+ if(!_coords || !_coords->isAllocated())
+ {
+ if(!_ms.size())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
+ if (!_fam_coords)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
+ if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
+ }
+ else
+ {
+ int nbCoo = _coords->getNumberOfTuples();
+ if (_fam_coords.isNotNull())
+ _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
+ if (_num_coords.isNotNull())
+ {
+ _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
+ int pos;
+ int maxValue=_num_coords->getMaxValue(pos);
+ if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
+ }
+ if (_global_num_coords.isNotNull())
+ {
+ _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
+ }
+ if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
+ if (_num_coords && !_num_coords->hasUniqueValues())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
+ if (_name_coords)
+ _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
+ // Now sub part check:
+ for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
+ it != _ms.end(); it++)
+ (*it)->checkConsistency();
+ }
+}
+
+/**
+ * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
+ * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
+ * entities as it likes), or non overlapping between all sub-levels.
+ * \throw if the condition above is not respected
+ */
+void MEDFileUMesh::checkSMESHConsistency() const
+{
+ checkConsistency();
+ // For all sub-levels, numbering is either always null or with void intersection:
+ if (_ms.size())
+ {
+ std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
+ std::vector< const DataArrayInt * > v;
+ bool voidOrNot = ((*it)->_num == 0);
+ for (it++; it != _ms.end(); it++)
+ if( ((*it)->_num == 0) != voidOrNot )
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
+ else if (!voidOrNot)
+ v.push_back((*it)->_num);
+ if (!voidOrNot)
+ {
+ // don't forget the 1st one:
+ v.push_back(_ms[0]->_num);
+ MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
+ if (inter->getNumberOfTuples())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
+ }
+ }
+}
+
+/**
+ * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
+ * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
+ */
+void MEDFileUMesh::clearNodeAndCellNumbers()
+{
+ _num_coords.nullify();
+ _rev_num_coords.nullify();
+ _global_num_coords.nullify();
+ for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
+ {
+ (*it)->_num.nullify();
+ (*it)->_rev_num.nullify();
+ (*it)->_global_num.nullify();
+ }
+}
+
/*!
* Clears redundant attributes of incorporated data arrays.
*/
void MEDFileUMesh::clearNonDiscrAttributes() const
{
MEDFileMesh::clearNonDiscrAttributes();
- const DataArrayDouble *coo1=_coords;
- if(coo1)
- (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
- const DataArrayInt *famc1=_fam_coords;
- if(famc1)
- (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
- const DataArrayInt *numc1=_num_coords;
- if(numc1)
- (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
- const DataArrayAsciiChar *namc1=_name_coords;
- if(namc1)
- (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
+ if(_coords.isNotNull())
+ _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
+ if(_fam_coords.isNotNull())
+ _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
+ if(_num_coords.isNotNull())
+ _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
+ if(_name_coords.isNotNull())
+ _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
{
- const MEDFileUMeshSplitL1 *tmp=(*it);
- if(tmp)
- tmp->clearNonDiscrAttributes();
+ if((*it).isNotNull())
+ (*it)->clearNonDiscrAttributes();
}
}
void MEDFileUMesh::setName(const std::string& name)
{
for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
- if((MEDFileUMeshSplitL1 *)(*it)!=0)
+ if((*it).isNotNull())
(*it)->setName(name);
MEDFileMesh::setName(name);
}
int dummy0,dummy1;
std::string dummy2;
MEDCoupling::MEDCouplingAxisType dummy3;
- int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
+ INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
if(meshType!=UNSTRUCTURED)
{
std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
*/
void MEDFileMesh::writeJoints(med_idt fid) const
{
- if ( (const MEDFileJoints*) _joints )
- _joints->write(fid);
+ if ( _joints.isNotNull() )
+ _joints->writeLL(fid);
}
/*!
if(getAxisType()!=AX_CART)
{
std::ostringstream oss; oss << "MEDFileMesh::checkCartesian : request for method that is dedicated to a cartesian convention ! But you are not in cartesian convention (" << DataArray::GetAxisTypeRepr(getAxisType()) << ").";
- oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
+ oss << std::endl << "To perform operation you have two possibilities :" << std::endl;
oss << " - call setAxisType(AX_CART)" << std::endl;
oss << " - call cartesianize()";
throw INTERP_KERNEL::Exception(oss.str().c_str());
int dummy0,dummy1;
std::string dummy2;
MEDCoupling::MEDCouplingAxisType axType;
- int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
+ INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
setAxisType(axType);
if(meshType!=UNSTRUCTURED)
{
}
loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
dispatchLoadedPart(fid,loaderl2,mName,mrs);
+ // Structure element part...
+ int nModels(-1);
+ {
+ med_bool chgt=MED_FALSE,trsf=MED_FALSE;
+ nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
+ }
+ if(nModels<=0)
+ return ;
+ _elt_str.resize(nModels);
+ for(int i=0;i<nModels;i++)
+ _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
}
void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
_num_coords=loaderl2.getCoordsNum();
if(!mrs || mrs->isNodeNameFieldReading())
_name_coords=loaderl2.getCoordsName();
+ if(!mrs || mrs->isGlobalNodeNumFieldReading())
+ _global_num_coords=loaderl2.getCoordsGlobalNum();
_part_coords=loaderl2.getPartDefOfCoo();
computeRevNum();
}
{
}
-void MEDFileUMesh::writeLL(med_idt fid) const
+void MEDFileUMesh::writeMeshLL(med_idt fid) const
{
const DataArrayDouble *coo=_coords;
INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
std::string info=coo->getInfoOnComponent(i);
std::string c,u;
MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
- MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
- MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
+ MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
+ MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
}
MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
if(_univ_wr_status)
MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
- MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
+ MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords);
for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
if((const MEDFileUMeshSplitL1 *)(*it)!=0)
(*it)->write(fid,meshName,mdim);
std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
{
std::vector<int> ret;
- const DataArrayInt *numCoo(_num_coords);
- if(numCoo)
+ if(_num_coords.isNotNull())
ret.push_back(1);
int lev=0;
for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
return l1->getNameField();
}
+MCAuto<DataArrayInt> MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
+{
+ if(meshDimRelToMaxExt!=1)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
+ return _global_num_coords;
+}
+
/*!
* This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file).
*
}
}
+bool MEDFileUMesh::presenceOfStructureElements() const
+{
+ for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
+ if((*it).isNotNull())
+ return true;
+ return false;
+}
+
+void MEDFileUMesh::killStructureElements()
+{
+ _elt_str.clear();
+}
+
/*!
* Returns the optional numbers of mesh entities of a given dimension transformed using
* DataArrayInt::invertArrayN2O2O2N().
{
if(meshDimRelToMaxExt==1)
{
- if(!((const DataArrayInt *)_num_coords))
+ if(_num_coords.isNull())
throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
return _rev_num_coords;
}
- const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
+ const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
return l1->getRevNumberField();
}
/*!
* This method is for advanced users. There is two storing strategy of mesh in \a this.
* Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
- * When assignement is done the first one is done, which is not optimal in write mode for MED file.
+ * When assignment is done the first one is done, which is not optimal in write mode for MED file.
* This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
*/
void MEDFileUMesh::forceComputationOfParts() const
return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
}
+/*!
+ * This method returns for each geo types in \a this number of cells with this geo type.
+ * This method returns info as a vector of pair. The first element of pair is geo type and the second the number of cells associated.
+ * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
+ *
+ * \sa getDistributionOfTypes
+ */
+std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
+{
+ std::vector< std::pair<int,int> > ret;
+ std::vector<int> nel(getNonEmptyLevels());
+ for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
+ {
+ std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
+ for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
+ {
+ int nbCells(getNumberOfCellsWithType(*it1));
+ ret.push_back(std::pair<int,int>(*it1,nbCells));
+ }
+ }
+ ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
+ return ret;
+}
+
/*!
* Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
* \throw if the reqsuested \a meshDimRelToMax does not exist.
if(coords==(DataArrayDouble *)_coords)
return ;
coords->checkAllocated();
- int nbOfTuples=coords->getNumberOfTuples();
- _coords=coords;
- coords->incrRef();
+ int nbOfTuples(coords->getNumberOfTuples());
+ _coords.takeRef(coords);
_fam_coords=DataArrayInt::New();
_fam_coords->alloc(nbOfTuples,1);
_fam_coords->fillWithZero();
+ _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
+ for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+ if((MEDFileUMeshSplitL1 *)(*it))
+ (*it)->setCoords(coords);
+}
+
+/*!
+ * Change coords without changing anything concerning families and numbering on nodes.
+ */
+void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
+{
+ if(!coords)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
+ if(coords==(DataArrayDouble *)_coords)
+ return ;
+ coords->checkAllocated();
+ int nbOfTuples(coords->getNumberOfTuples());
+ if(_coords.isNull())
+ {
+ _coords=coords;
+ coords->incrRef();
+ }
+ else
+ {
+ int oldNbTuples(_coords->getNumberOfTuples());
+ if(oldNbTuples!=nbOfTuples)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
+ _coords=coords;
+ coords->incrRef();
+ }
for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
if((MEDFileUMeshSplitL1 *)(*it))
(*it)->setCoords(coords);
* The boundary is built according to the following method:
* - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
* coordinates array is extended).
- * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated.
+ * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
+ * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
+ * might not be duplicated at all.
* After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
* other side of the group is no more a neighbor)
* - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
* bordering the newly created boundary use the newly computed nodes.
+ * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
+ * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
*
* \param[in] grpNameM1 name of the (-1)-level group defining the boundary
* \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
* the coord array)
* \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
* \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
+ * \sa clearNodeAndCellNumbers()
*/
void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
{
+ typedef MCAuto<MEDCouplingUMesh> MUMesh;
+ typedef MCAuto<DataArrayInt> DAInt;
+
std::vector<int> levs=getNonEmptyLevels();
if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
- throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
- MCAuto<MEDCouplingUMesh> m0=getMeshAtLevel(0);
- MCAuto<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh defined on level 0 and -1 !");
+ MUMesh m0=getMeshAtLevel(0);
+ MUMesh m1=getMeshAtLevel(-1);
int nbNodes=m0->getNumberOfNodes();
- MCAuto<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
+ MUMesh m11=getGroup(-1,grpNameM1);
DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
- MCAuto<DataArrayInt> nodeIdsToDuplicate(tmp00);
- MCAuto<DataArrayInt> cellsToModifyConn0(tmp11);
- MCAuto<DataArrayInt> cellsToModifyConn1(tmp22);
- MCAuto<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
+ DAInt nodeIdsToDuplicate(tmp00);
+ DAInt cellsToModifyConn0(tmp11);
+ DAInt cellsToModifyConn1(tmp22);
+ MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
// node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
- MCAuto<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
- MCAuto<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
+ DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
+ MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
- MCAuto<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
- MCAuto<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
+ DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
+ MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
DataArrayInt *cellsInM1ToRenumW4Tmp=0;
m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
- MCAuto<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
- MCAuto<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
+ DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
+ DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
- MCAuto<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
- MCAuto<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
- MCAuto<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
+ DAInt grpIds=getGroupArr(-1,grpNameM1);
+ DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
+ MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
// end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
m0->setCoords(tmp0->getCoords());
m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
+ _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
m1->setCoords(m0->getCoords());
_coords=m0->getCoords(); _coords->incrRef();
- // duplication of cells in group 'grpNameM1' on level -1
+ // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
- std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
- MCAuto<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
- MCAuto<DataArrayInt> szOfCellGrpOfSameType(tmp00);
- MCAuto<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
+ DataArrayInt * duplCells;
+ m1->areCellsIncludedIn(m11, 0, duplCells);
+ DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
+ MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
+ std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
+ MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
+ DAInt szOfCellGrpOfSameType(tmp00);
+ DAInt idInMsOfCellGrpOfSameType(tmp11);
//
newm1->setName(getName());
const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
if(!fam)
- throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : internal problem !");
- MCAuto<DataArrayInt> newFam=DataArrayInt::New();
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
+ DAInt newFam=DataArrayInt::New();
newFam->alloc(newm1->getNumberOfCells(),1);
// Get a new family ID: care must be taken if we need a positive ID or a negative one:
// Positive ID for family of nodes, negative for all the rest.
if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
{
end=start+szOfCellGrpOfSameType->getIJ(i,0);
- MCAuto<DataArrayInt> part=fam->selectByTupleIdSafeSlice(start,end,1);
+ DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
start=end;
}
newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
_fam_coords=newFam;
}
+
+ _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
+
+ for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
+ it != _ms.end(); it++)
+ {
+ (*it)->_num = 0;
+ (*it)->_rev_num = 0;
+ }
nodesDuplicated=nodeIdsToDuplicate.retn();
cellsModified=cellsToModifyConn0.retn();
cellsNotModified=cellsToModifyConn1.retn();
}
-/*!
+/*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
+ * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
+ * in this method.
+ *
* \param [out] oldCode retrieves the distribution of types before the call if true is returned
* \param [out] newCode etrieves the distribution of types after the call if true is returned
* \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
/*! \endcond */
/*!
- * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller.
+ * Array returned is the correspondence in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller.
* The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
* The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
* -1 values in returned array means that the corresponding old node is no more used.
*
- * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing
+ * \return newly allocated array containing correspondence in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing
* is modified in \a this.
* \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of
* set coordinates.
MCAuto<DataArrayAsciiChar> newNameCoords;
if((const DataArrayInt *)_fam_coords)
newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
- MCAuto<DataArrayInt> newNumCoords;
- if((const DataArrayInt *)_num_coords)
+ MCAuto<DataArrayInt> newNumCoords,newGlobalNumCoords;
+ if(_num_coords.isNotNull())
newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
- if((const DataArrayAsciiChar *)_name_coords)
+ if(_global_num_coords.isNotNull())
+ newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
+ if(_name_coords.isNotNull())
newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
- _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
+ _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
{
if((MEDFileUMeshSplitL1*)*it)
return ret.retn();
}
+/*!
+ * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
+ * The extraction of \a this is specified by the extractDef \a input map.
+ * This map tells for each level of cells, the cells kept in the extraction.
+ *
+ * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
+ * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
+ */
+DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
+{
+ std::vector<int> levs(getNonEmptyLevels());
+ std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
+ for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
+ {
+ if((*it).first>1)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
+ if((*it).second.isNull())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
+ if((*it).first==1)
+ continue;
+ if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
+ {
+ std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
+ MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
+ mPart->computeNodeIdsAlg(fetchedNodes);
+ }
+ return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
+}
+
+/*!
+ * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
+ *
+ * \return - a new reference of MEDFileUMesh
+ * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
+ */
+MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
+{
+ MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
+ std::vector<int> levs(getNonEmptyLevels());
+ for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
+ {
+ if((*it).first>1)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
+ if((*it).second.isNull())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
+ if((*it).first==1)
+ continue;
+ if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
+ {
+ std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
+ MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
+ ret->setMeshAtLevel((*it).first,mPart);
+ const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
+ if(fam)
+ {
+ MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
+ ret->setFamilyFieldArr((*it).first,famPart);
+ }
+ if(num)
+ {
+ MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
+ ret->setFamilyFieldArr((*it).first,numPart);
+ }
+ }
+ std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
+ if(it2!=extractDef.end())
+ {
+ const DataArrayDouble *coo(ret->getCoords());
+ if(!coo)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
+ MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
+ MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+ ret->setCoords(cooPart);
+ const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
+ if(fam)
+ {
+ MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+ ret->setFamilyFieldArr(1,famPart);
+ }
+ if(num)
+ {
+ MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+ ret->setFamilyFieldArr(1,numPart);
+ }
+ for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
+ {
+ if((*it3).first==1)
+ continue;
+ MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
+ m->renumberNodesInConn(o2nNodes->begin());
+ ret->setMeshAtLevel((*it3).first,m);
+ }
+ }
+ return ret.retn();
+}
+
/*!
* This method performs an extrusion along a path defined by \a m1D.
* \a this is expected to be a mesh with max mesh dimension equal to 2.
return ret.retn();
}
+/*!
+ * Computes the symmetry of \a this.
+ * \return a new object.
+ */
+MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
+{
+ MCAuto<MEDFileUMesh> ret(deepCopy());
+ DataArrayDouble *myCoo(getCoords());
+ if(myCoo)
+ {
+ MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
+ ret->setCoordsForced(newCoo);
+ }
+ return ret;
+}
+
+/*!
+ * Aggregate the given MEDFileUMesh objects into a single mesh. When groups are present, those are
+ * merged in such a way that the final mesh contain all of them.
+ * \return a new object.
+ */
+MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
+{
+ if(meshes.empty())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
+ std::size_t sz(meshes.size()),i(0);
+ std::vector<const DataArrayDouble *> coos(sz);
+ std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
+ for(auto it=meshes.begin();it!=meshes.end();it++,i++)
+ {
+ if(!(*it))
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
+ coos[i]=(*it)->getCoords();
+ fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
+ num_coos[i]=(*it)->getNumberFieldAtLevel(1);
+ }
+ const MEDFileUMesh *ref(meshes[0]);
+ int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
+ std::vector<int> levs(ref->getNonEmptyLevels());
+ std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
+ std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
+ std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
+ std::map<std::string,int> famNumMap;
+ std::map<int, std::string> famNumMap_rev;
+ std::map<std::string, std::vector<std::string> > grpFamMap;
+ std::set< MCAuto<DataArrayInt> > mem_cleanup; // Memory clean-up. At set deletion (end of method), arrays will be deallocated.
+
+ // Identify min family number used:
+ int min_fam_num(0);
+ for(const auto& msh : meshes)
+ {
+ const std::map<std::string,int>& locMap1(msh->getFamilyInfo());
+ for(const auto& it3 : locMap1)
+ if(it3.second < min_fam_num)
+ min_fam_num = it3.second;
+ }
+
+ for(const auto& msh : meshes)
+ {
+ if(msh->getSpaceDimension()!=spaceDim)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
+ if(msh->getMeshDimension()!=meshDim)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
+ if(msh->getNonEmptyLevels()!=levs)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
+
+ const std::map<std::string,int>& locMap1(msh->getFamilyInfo());
+ std::map<std::string, std::string> substitute;
+ std::map<int, int> substituteN;
+ bool fam_conflict(false);
+ for(const auto& it3 : locMap1)
+ {
+ const std::string& famName = it3.first;
+ int famNum = it3.second;
+ if (famNumMap_rev.find(famNum) != famNumMap_rev.end()) // Family number is already used!
+ {
+ // Is it used by a group of the current mesh or a group from a previous mesh?
+ // If not, this is OK (typically -1 familly).
+ bool used = false;
+ // Current mesh
+ const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
+ for(const auto& it4 : locMap2)
+ {
+ const auto& famLst = it4.second;
+ if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
+ { used = true; break; }
+ }
+ // Previous meshes ...
+ if (!used)
+ for(const auto& it4 : grpFamMap)
+ {
+ const auto& famLst = it4.second;
+ if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
+ { used = true; break; }
+ }
+
+ if(used)
+ { // Generate a new family name, and a new family number
+ fam_conflict = true;
+ std::ostringstream oss;
+ oss << "Family_" << --min_fam_num; // New ID
+ std::string new_name(oss.str());
+ substitute[famName] = new_name;
+ substituteN[famNum] = min_fam_num;
+ famNumMap[new_name] = min_fam_num;
+ famNumMap_rev[min_fam_num] = new_name;
+ }
+ }
+ famNumMap[famName] = famNum;
+ famNumMap_rev[famNum] = famName;
+ }
+
+ for(const auto& level : levs)
+ {
+ MCAuto<MEDCouplingUMesh> locMesh(msh->getMeshAtLevel(level));
+ m_mesh[level].push_back(locMesh); m_mesh2[level].push_back(locMesh);
+ m_renum[level].push_back(msh->getNumberFieldAtLevel(level));
+
+ // Family field - substitute new family number if needed:
+ if(fam_conflict)
+ {
+ DataArrayInt* dai(msh->getFamilyFieldAtLevel(level)->deepCopy()); // Need a copy
+ mem_cleanup.insert(MCAuto<DataArrayInt>(dai)); // Make sure array will decrRef() at end of method
+ for (const auto& subN : substituteN)
+ dai->changeValue(subN.first, subN.second);
+ m_fam[level].push_back(dai);
+ }
+ else
+ m_fam[level].push_back(msh->getFamilyFieldAtLevel(level)); // No copy needed
+ }
+
+ const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
+ for(const auto& grpItem : locMap2)
+ {
+ const std::string& grpName = grpItem.first;
+ std::vector<std::string> famLst;
+ // Substitute family name in group description if needed:
+ if (fam_conflict)
+ {
+ famLst = grpItem.second;
+ for (const auto& sub : substitute)
+ std::replace(famLst.begin(), famLst.end(), sub.first, sub.second);
+ }
+ else
+ famLst = grpItem.second;
+
+ // Potentially merge groups (if same name):
+ const auto& it = grpFamMap.find(grpName);
+ if (it != grpFamMap.end())
+ {
+ // Group already exists, merge should be done. Normally we whould never
+ // have twice the same family name in famLstCur and famLst since we dealt with family number
+ // conflict just above ...
+ std::vector<std::string>& famLstCur = (*it).second;
+ famLstCur.insert(famLstCur.end(), famLst.begin(), famLst.end());
+ }
+ else
+ grpFamMap[grpName] = famLst;
+ }
+ }
+ // Easy part : nodes
+ MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+ MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
+ ret->setCoords(coo);
+ if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
+ {
+ MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
+ ret->setFamilyFieldArr(1,fam_coo);
+ }
+ if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
+ {
+ MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
+ ret->setRenumFieldArr(1,num_coo);
+ }
+ // cells
+ for(const auto& level : levs)
+ {
+ auto it2(m_mesh.find(level));
+ if(it2==m_mesh.end())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
+ MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
+ mesh->setCoords(coo); mesh->setName(ref->getName());
+ MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
+ ret->setMeshAtLevel(level,mesh);
+ auto it3(m_fam.find(level)),it4(m_renum.find(level));
+ if(it3==m_fam.end()) // Should never happen (all levels exist for all meshes)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 2!");
+ if(it4==m_renum.end())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 3!");
+ // Set new family field if it was defined for all input meshes
+ const std::vector<const DataArrayInt *>& fams((*it3).second);
+ if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
+ {
+ MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
+ famm->renumberInPlace(renum->begin());
+ ret->setFamilyFieldArr(level,famm);
+ }
+ // Set optional number field if defined for all input meshes:
+ const std::vector<const DataArrayInt *>& renums((*it4).second);
+ if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
+ {
+ MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
+ renumm->renumberInPlace(renum->begin());
+ ret->setRenumFieldArr(level,renumm);
+ }
+ }
+ //
+ ret->setFamilyInfo(famNumMap);
+ ret->setGroupInfo(grpFamMap);
+ ret->setName(ref->getName());
+ return ret;
+}
+
+MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
+{
+ if(getMeshDimension()!=3)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
+ MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
+ if(m3D.isNull() || m2D.isNull())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
+ int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
+ MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
+ return ret.retn();
+}
+
void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
{
clearNonDiscrAttributes();
if(!coords)
throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
int nbOfNodes(coords->getNumberOfTuples());
- if(!((DataArrayInt *)_fam_coords))
+ if(_fam_coords.isNull())
{ _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
//
addGroupUnderground(true,ids,_fam_coords);
*
* \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
* \param [in] renum - the parameter (set to false by default) that tells the beheviour if there is a mesh on \a ms that is not geo type sorted.
- * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
+ * If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false.
*
* \throw If \a there is a null pointer in \a ms.
* \sa MEDFileUMesh::setMeshAtLevel
if(!coo)
throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
- famArr->incrRef();
- _fam_coords=famArr;
+ _fam_coords.takeRef(famArr);
return ;
}
if(meshDimRelToMaxExt>1)
{
if(!renumArr)
{
- _num_coords=0;
- _rev_num_coords=0;
+ _num_coords.nullify();
+ _rev_num_coords.nullify();
return ;
}
- DataArrayDouble *coo(_coords);
- if(!coo)
+ if(_coords.isNull())
throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
- renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
- renumArr->incrRef();
- _num_coords=renumArr;
+ renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
+ _num_coords.takeRef(renumArr);
computeRevNum();
return ;
}
if(!coo)
throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
- nameArr->incrRef();
- _name_coords=nameArr;
+ _name_coords.takeRef(nameArr);
return ;
}
if(meshDimRelToMaxExt>1)
return _ms[traducedRk]->setNameArr(nameArr);
}
+void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayInt *globalNumArr)
+{
+ if(meshDimRelToMaxExt!=1)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
+ if(globalNumArr)
+ globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
+ _global_num_coords.takeRef(globalNumArr);
+}
+
void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
{
for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
void MEDFileUMesh::computeRevNum() const
{
- if((const DataArrayInt *)_num_coords)
+ if(_num_coords.isNotNull())
{
int pos;
int maxValue=_num_coords->getMaxValue(pos);
{
case 0:
{
- int nbCells=mesh->getNumberOfCells();
- famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
+ int nbCells(mesh->getNumberOfCells());
+ if(famArr)
+ famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
_fam_cells=famArr;
break;
}
case 1:
{
- int nbNodes=mesh->getNumberOfNodes();
- famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
+ int nbNodes(mesh->getNumberOfNodes());
+ if(famArr)
+ famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
_fam_nodes=famArr;
break;
}
case -1:
{
- int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
- famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
+ int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
+ if(famArr)
+ famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
_fam_faces=famArr;
break;
}
{
int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
- _names_cells=nameArr;
+ _names_faces=nameArr;
}
default:
throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
nameArr->incrRef();
}
+void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayInt *globalNumArr)
+{
+ throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
+}
+
/*!
* Adds a group of nodes to \a this mesh.
* \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
}
}
+MCAuto<DataArrayInt> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
+{
+ throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
+}
+
/*!
* Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
* \return std::vector<int> - a sequence of the relative dimensions: [0].
}
/*!
- * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
+ * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh).
*
* \return a pointer to cartesian mesh that need to be managed by the caller.
* \warning the returned pointer has to be managed by the caller.
*/
MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
{
- std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
- if(ms.empty())
- {
- std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
- throw INTERP_KERNEL::Exception(oss.str().c_str());
- }
- MEDFileUtilities::CheckFileForRead(fileName);
- MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
- int dt,it;
- MEDCoupling::MEDCouplingMeshType meshType;
- std::string dummy2;
- MEDCoupling::MEDCouplingAxisType dummy3;
- MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
- return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
+ MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+ return New(fid,mrs);
+}
+
+MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+ return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
}
/*!
*/
MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
{
- MEDFileUtilities::CheckFileForRead(fileName);
- MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
+ MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+ return New(fid,mName,dt,it,mrs);
+}
+
+MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
return new MEDFileCMesh(fid,mName,dt,it,mrs);
}
return simpleRepr();
}
-MEDFileMesh *MEDFileCMesh::shallowCpy() const
+MEDFileCMesh *MEDFileCMesh::shallowCpy() const
{
MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
return ret.retn();
return new MEDFileCMesh;
}
-MEDFileMesh *MEDFileCMesh::deepCopy() const
+MEDFileCMesh *MEDFileCMesh::deepCopy() const
{
MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
ret->deepCpyEquivalences(*this);
int dummy0,dummy1;
std::string dtunit;
MEDCoupling::MEDCouplingAxisType axType;
- int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
+ INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
if(meshType!=CARTESIAN)
{
std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
}
}
-void MEDFileCMesh::writeLL(med_idt fid) const
+void MEDFileCMesh::writeMeshLL(med_idt fid) const
{
INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
return new MEDFileCurveLinearMesh;
}
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+ return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
+}
+
MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
{
- std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
- if(ms.empty())
- {
- std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
- throw INTERP_KERNEL::Exception(oss.str().c_str());
- }
- MEDFileUtilities::CheckFileForRead(fileName);
- MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
- int dt,it;
- MEDCoupling::MEDCouplingMeshType meshType;
- MEDCoupling::MEDCouplingAxisType dummy3;
- std::string dummy2;
- MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
- return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
+ MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+ return New(fid,mrs);
}
MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
{
- MEDFileUtilities::CheckFileForRead(fileName);
- MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
+ MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+ return New(fid,mName,dt,it,mrs);
+}
+
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
}
return ret;
}
-MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
{
MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
return ret.retn();
return new MEDFileCurveLinearMesh;
}
-MEDFileMesh *MEDFileCurveLinearMesh::deepCopy() const
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
{
MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
ret->deepCpyEquivalences(*this);
throw e;
}
-void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
+void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
{
INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
const DataArrayDouble *coords=_clmesh->getCoords();
if(!coords)
- throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
+ throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
for(int i=0;i<spaceDim;i++)
{
std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
int dummy0,dummy1;
std::string dtunit;
MEDCoupling::MEDCouplingAxisType axType;
- int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
+ INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
setAxisType(axType);
if(meshType!=CURVE_LINEAR)
{
return new MEDFileMeshMultiTS;
}
+MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
+{
+ return new MEDFileMeshMultiTS(fid);
+}
+
MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
{
- return new MEDFileMeshMultiTS(fileName);
+ MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+ return New(fid);
+}
+
+MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
+{
+ return new MEDFileMeshMultiTS(fid,mName);
}
MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
{
- return new MEDFileMeshMultiTS(fileName,mName);
+ MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+ return New(fid,mName);
}
MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
{
- MCAuto<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
+ MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
- std::size_t i=0;
+ std::size_t i(0);
for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
if((const MEDFileMesh *)*it)
meshOneTs[i]=(*it)->deepCopy();
}
}
-void MEDFileMeshMultiTS::write(med_idt fid) const
+bool MEDFileMeshMultiTS::presenceOfStructureElements() const
+{
+ for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+ if((*it).isNotNull())
+ if((*it)->presenceOfStructureElements())
+ return true;
+ return false;
+}
+
+void MEDFileMeshMultiTS::killStructureElements()
+{
+ for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+ if((*it).isNotNull())
+ (*it)->killStructureElements();
+}
+
+void MEDFileMeshMultiTS::writeLL(med_idt fid) const
{
MEDFileJoints *joints(getJoints());
bool jointsWritten(false);
jointsWritten = true;
(*it)->copyOptionsFrom(*this);
- (*it)->write(fid);
+ (*it)->writeLL(fid);
}
(const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
}
-void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
+void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
{
- med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
- MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
- std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
- MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
- write(fid);
-}
-
-void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
-{
- MEDFileJoints* joints = 0;
+ MEDFileJoints *joints(0);
if ( !_mesh_one_ts.empty() && getOneTimeStep() )
{
// joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
joints = getOneTimeStep()->getJoints();
}
-
_mesh_one_ts.clear(); //for the moment to be improved
- _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
+ _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
}
MEDFileMeshMultiTS::MEDFileMeshMultiTS()
{
}
-MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
+MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
try
{
- std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
+ std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
if(ms.empty())
{
- std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
+ std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
- MEDFileUtilities::CheckFileForRead(fileName);
- MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
int dt,it;
MEDCoupling::MEDCouplingMeshType meshType;
std::string dummy2;
MEDCoupling::MEDCouplingAxisType dummy3;
MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
- loadFromFile(fileName,ms.front());
+ loadFromFile(fid,ms.front());
}
catch(INTERP_KERNEL::Exception& e)
{
throw e;
}
-MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
+MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
try
{
- loadFromFile(fileName,mName);
+ loadFromFile(fid,mName);
}
catch(INTERP_KERNEL::Exception& e)
{
return new MEDFileMeshes;
}
+MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
+{
+ return new MEDFileMeshes(fid);
+}
+
MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
{
- return new MEDFileMeshes(fileName);
+ MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+ return New(fid);
}
-void MEDFileMeshes::write(med_idt fid) const
+void MEDFileMeshes::writeLL(med_idt fid) const
{
checkConsistencyLight();
for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
{
(*it)->copyOptionsFrom(*this);
- (*it)->write(fid);
+ (*it)->writeLL(fid);
}
}
-void MEDFileMeshes::write(const std::string& fileName, int mode) const
-{
- med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
- MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
- std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
- MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
- checkConsistencyLight();
- write(fid);
-}
+// MEDFileMeshes::writ checkConsistencyLight();
int MEDFileMeshes::getNumberOfMeshes() const
{
_meshes.erase(_meshes.begin()+i);
}
-void MEDFileMeshes::loadFromFile(const std::string& fileName)
+void MEDFileMeshes::loadFromFile(med_idt fid)
{
- std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
+ std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
int i=0;
_meshes.resize(ms.size());
for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
- _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
+ _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
}
MEDFileMeshes::MEDFileMeshes()
{
}
-MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
+MEDFileMeshes::MEDFileMeshes(med_idt fid)
try
{
- loadFromFile(fileName);
+ loadFromFile(fid);
}
catch(INTERP_KERNEL::Exception& /*e*/)
{
for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
if((const MEDFileMeshMultiTS *)*it)
meshes[i]=(*it)->deepCopy();
- MCAuto<MEDFileMeshes> ret=MEDFileMeshes::New();
+ MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
ret->_meshes=meshes;
return ret.retn();
}
}
}
+bool MEDFileMeshes::presenceOfStructureElements() const
+{
+ for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
+ if((*it).isNotNull())
+ if((*it)->presenceOfStructureElements())
+ return true;
+ return false;
+}
+
+void MEDFileMeshes::killStructureElements()
+{
+ for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
+ if((*it).isNotNull())
+ (*it)->killStructureElements();
+}
+
MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
{
if(ms)
else
return 0;
}
+
+INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
+{
+ med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
+ if(pos==typmai+MED_N_CELL_FIXED_GEO)
+ {
+ if(geoType==MED_NO_GEOTYPE)
+ return INTERP_KERNEL::NORM_ERROR;
+ std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ return typmai2[std::distance(typmai,pos)];
+}
+
+TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
+{
+ switch(etype)
+ {
+ case MED_NODE:
+ return ON_NODES;
+ case MED_CELL:
+ return ON_CELLS;
+ default:
+ {
+ std::ostringstream oss; oss << "EDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ }
+}
+
+