return ret;
}
+/*!
+ * \param [in,out] nodeIdsInUse an array of size typically equal to nbOfNodes.
+ * \sa MEDCouplingUMesh::getNodeIdsInUse
+ */
+void MEDCouplingUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
+{
+ int nbOfNodes=(int)nodeIdsInUse.size();
+ int nbOfCells=getNumberOfCells();
+ const int *connIndex=_nodal_connec_index->getConstPointer();
+ const int *conn=_nodal_connec->getConstPointer();
+ for(int i=0;i<nbOfCells;i++)
+ for(int j=connIndex[i]+1;j<connIndex[i+1];j++)
+ if(conn[j]>=0)
+ {
+ if(conn[j]<nbOfNodes)
+ nodeIdsInUse[conn[j]]=true;
+ else
+ {
+ std::ostringstream oss; oss << "MEDCouplingUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
+}
+
/*!
* Array returned is the correspondance in \b old \b to \b new format (that's why 'nbrOfNodesInUse' is returned too).
* The returned array is newly created and should be dealt by the caller.
* -1 values in returned array means that the corresponding node never appear in any nodal connectivity of cells constituting 'this'.
* @param [out] nbrOfNodesInUse out parameter that specifies how many of nodes in 'this' is really used in nodal connectivity.
* @return a newly allocated DataArrayInt that tells for each nodeid in \b this if it is unused (-1) or used (the corresponding new id)
+ * \throw if a cell contains in its nodal connectivity a node id >= nb of nodes an exception will be thrown.
+ * \sa MEDCouplingUMesh::computeNodeIdsAlg
*/
DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
{
nbrOfNodesInUse=-1;
int nbOfNodes=getNumberOfNodes();
- DataArrayInt *ret=DataArrayInt::New();
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
ret->alloc(nbOfNodes,1);
int *traducer=ret->getPointer();
std::fill(traducer,traducer+nbOfNodes,-1);
for(int i=0;i<nbOfCells;i++)
for(int j=connIndex[i]+1;j<connIndex[i+1];j++)
if(conn[j]>=0)
- traducer[conn[j]]=1;
+ {
+ if(conn[j]<nbOfNodes)
+ traducer[conn[j]]=1;
+ else
+ {
+ std::ostringstream oss; oss << "MEDCouplingUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
- return ret;
+ return ret.retn();
}
/*!
MEDCOUPLING_EXPORT std::vector<DataArrayInt *> partitionBySpreadZone() const throw(INTERP_KERNEL::Exception);
MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception);
MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception);
+ MEDCOUPLING_EXPORT void computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception);
MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception);
MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception);
MEDCOUPLING_EXPORT DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception);
return ret;
}
+struct MEDLoaderAccVisit1
+{
+ MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
+ int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
+ int _new_nb_of_nodes;
+};
+
+/*!
+ * 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.
+ * 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 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.
+ */
+DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
+{
+ const DataArrayDouble *coo=getCoords();
+ if(!coo)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
+ int nbOfNodes=coo->getNumberOfTuples();
+ std::vector<bool> nodeIdsInUse(nbOfNodes,false);
+ std::vector<int> neLevs=getNonEmptyLevels();
+ for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
+ {
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
+ m->computeNodeIdsAlg(nodeIdsInUse);
+ }
+ int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
+ if(nbrOfNodesInUse==nbOfNodes)
+ return 0;
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
+ std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleId(ret2->begin(),ret2->end());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
+ if((const DataArrayInt *)_fam_coords)
+ newFamCoords=_fam_coords->selectByTupleId(ret2->begin(),ret2->end());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
+ if((const DataArrayInt *)_num_coords)
+ newNumCoords=_num_coords->selectByTupleId(ret2->begin(),ret2->end());
+ _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords;
+ for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+ {
+ if((MEDFileUMeshSplitL1*)*it)
+ (*it)->renumberNodesInConn(ret->begin());
+ }
+ return ret.retn();
+}
+
void MEDFileUMesh::addNodeGroup(const std::string& name, const std::vector<int>& ids) throw(INTERP_KERNEL::Exception)
{
const DataArrayDouble *coords=_coords;
void duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception);
// tools
bool unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception);
+ DataArrayInt *zipCoords() throw(INTERP_KERNEL::Exception);
private:
void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception);
MEDFileUMesh();
}
}
+void MEDFileUMeshSplitL1::renumberNodesInConn(const int *newNodeNumbersO2N) throw(INTERP_KERNEL::Exception)
+{
+ MEDCouplingUMesh *m(_m_by_types);
+ if(!m)
+ return;
+ m->renumberNodesInConn(newNodeNumbersO2N);
+}
+
void MEDFileUMeshSplitL1::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
{
DataArrayInt *arr=_fam;
void setRenumArr(DataArrayInt *renumArr);
void changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception);
//
+ void renumberNodesInConn(const int *newNodeNumbersO2N) throw(INTERP_KERNEL::Exception);
+ //
static void ClearNonDiscrAttributes(const MEDCouplingMesh *tmp);
static std::vector<int> GetNewFamiliesNumber(int nb, const std::map<std::string,int>& families);
static void TraduceFamilyNumber(const std::vector< std::vector<int> >& fidsGrps, std::map<std::string,int>& familyIds,
%newobject ParaMEDMEM::MEDFileUMesh::getLevelM1Mesh;
%newobject ParaMEDMEM::MEDFileUMesh::getLevelM2Mesh;
%newobject ParaMEDMEM::MEDFileUMesh::getLevelM3Mesh;
+%newobject ParaMEDMEM::MEDFileUMesh::zipCoords;
%newobject ParaMEDMEM::MEDFileCMesh::New;
%newobject ParaMEDMEM::MEDFileMeshMultiTS::New;
%newobject ParaMEDMEM::MEDFileMeshMultiTS::getOneTimeStep;
void setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms) throw(INTERP_KERNEL::Exception);
void setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception);
void optimizeFamilies() throw(INTERP_KERNEL::Exception);
+ DataArrayInt *zipCoords() throw(INTERP_KERNEL::Exception);
%extend
{
MEDFileUMesh(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception)
pfl1_r.setName(pfl1.getName())
self.assertTrue(pfl1_r.isEqual(pfl1))
pass
+
+ def testMEDFileUMeshZipCoords1(self):
+ m=MEDFileUMesh()
+ coo=DataArrayDouble(30) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"])
+ m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) ; m0.insertNextCell(NORM_TRI3,[1,2,3]) ; m0.insertNextCell(NORM_QUAD4,[2,4,3,4]) ; m0.insertNextCell(NORM_POLYGON,[1,6,6,6,2])
+ m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3])
+ m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8])
+ m0.setCoords(coo) ; m.setMeshAtLevel(0,m0)
+ m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1)
+ m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2)
+ numCoo=DataArrayInt(10) ; numCoo.iota(3) ; m.setRenumFieldArr(1,numCoo)
+ famCoo=DataArrayInt(10) ; famCoo.iota(4) ; m.setFamilyFieldArr(1,famCoo)
+ da=DataArrayInt([20,30,40]) ; m.setRenumFieldArr(0,da) ; da=DataArrayInt([200,300,400]) ; m.setFamilyFieldArr(0,da)
+ da=DataArrayInt([50,60]) ; m.setRenumFieldArr(-1,da) ; da=DataArrayInt([500,600]) ; m.setFamilyFieldArr(-1,da)
+ da=DataArrayInt([70,80,90]) ; m.setRenumFieldArr(-2,da) ; da=DataArrayInt([700,800,900]) ; m.setFamilyFieldArr(-2,da)
+ o2n=m.zipCoords()
+ self.assertTrue(o2n.isEqual(DataArrayInt([-1,0,1,2,3,-1,4,5,6,-1])))
+ self.assertTrue(m.getNumberFieldAtLevel(1).isEqual(DataArrayInt([4,5,6,7,9,10,11])))
+ self.assertTrue(m.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([5,6,7,8,10,11,12])))
+ self.assertTrue(m.getMeshAtLevel(0).getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,4,1,3,2,3,5,0,4,4,4,1])))
+ self.assertTrue(m.getMeshAtLevel(0).getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,9,15])))
+ self.assertTrue(m.getMeshAtLevel(-1).getNodalConnectivity().isEqual(DataArrayInt([1,0,4,1,5,2])))
+ self.assertTrue(m.getMeshAtLevel(-1).getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6])))
+ self.assertTrue(m.getMeshAtLevel(-2).getNodalConnectivity().isEqual(DataArrayInt([0,1,0,4,0,6])))
+ self.assertTrue(m.getMeshAtLevel(-2).getNodalConnectivityIndex().isEqual(DataArrayInt([0,2,4,6])))
+ pass
pass
unittest.main()