-// Copyright (C) 2007-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2007-2016 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
#include "MEDLoaderBase.hxx"
#include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingMappedExtrudedMesh.hxx"
#include "InterpKernelAutoPtr.hxx"
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)
{
}
*/
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));
return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
}
+/*!
+ * \b WARNING this implementation is dependant 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(),mem->get2DCellIdForExtrusion());
+ return ret.retn();
+}
+
/*!
* Returns an empty instance of MEDFileUMesh.
* \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
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);
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 || !_rev_num_coords)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
+ }
+ else
+ {
+ int nbCoo = _coords->getNumberOfTuples();
+ if (_fam_coords)
+ _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
+ if (_num_coords)
+ {
+ _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 ((_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 = 0;
+ _rev_num_coords = 0;
+ for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
+ it != _ms.end(); it++)
+ {
+ (*it)->_num = 0;
+ (*it)->_rev_num = 0;
+ }
+}
+
/*!
* Clears redundant attributes of incorporated data arrays.
*/
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();
+ int nbOfTuples(coords->getNumberOfTuples());
_coords=coords;
coords->incrRef();
_fam_coords=DataArrayInt::New();
_fam_coords->alloc(nbOfTuples,1);
_fam_coords->fillWithZero();
+ _num_coords=0; _rev_num_coords=0; _name_coords=0;
+ 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);
+ 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 = 0;
+ _rev_num_coords = 0;
+ 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.
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;
+}
+
+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(std::vector<const MEDFileUMesh *>::const_iterator 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> map1;
+ std::map<std::string, std::vector<std::string> > map2;
+ for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
+ {
+ if((*it)->getSpaceDimension()!=spaceDim)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
+ if((*it)->getMeshDimension()!=meshDim)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
+ if((*it)->getNonEmptyLevels()!=levs)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
+ for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
+ {
+ MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
+ m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
+ m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
+ m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
+ }
+ const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
+ for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
+ map1[(*it3).first]=(*it3).second;
+ const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
+ for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
+ map2[(*it4).first]=(*it4).second;
+ }
+ // 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(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
+ {
+ std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
+ 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(*it,mesh);
+ std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
+ if(it3!=m_fam.end())
+ {
+ 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(*it,famm);
+ }
+ }
+ if(it4!=m_renum.end())
+ {
+ 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(*it,renumm);
+ }
+ }
+ }
+ //
+ ret->setFamilyInfo(map1);
+ ret->setGroupInfo(map2);
+ 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(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();
{
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;
}
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);
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);