-class FieldPerTypeAccumulator
-{
-public:
- int operator()(int res, const MEDLoader::MEDFieldDoublePerCellType& elt) { return res+elt.getNbOfTuple(); }
-};
-
-ParaMEDMEM::DataArrayDouble *MEDLoaderNS::buildArrayFromRawData(const std::list<MEDLoader::MEDFieldDoublePerCellType>& fieldPerType,
- const std::vector<std::string>& infos)
-{
- ParaMEDMEM::DataArrayDouble *ret=ParaMEDMEM::DataArrayDouble::New();
- int totalNbOfTuple=std::accumulate(fieldPerType.begin(),fieldPerType.end(),0,FieldPerTypeAccumulator());
- int nbOfComp=(*fieldPerType.begin()).getNbComp();
- double *ptr=new double[nbOfComp*totalNbOfTuple];
- ret->useArray(ptr,true,ParaMEDMEM::CPP_DEALLOC,totalNbOfTuple,nbOfComp);
- std::for_each(fieldPerType.begin(),fieldPerType.end(),FieldPerTypeCopier(ptr));
- for(int i=0;i<nbOfComp;i++)
- ret->setInfoOnComponent(i,infos[i].c_str());
- return ret;
-}
-
-class PolyCounterForFams
-{
-public:
- PolyCounterForFams(int id, const int *index):_id(id),_index(index),_count(0),_sigma(0) { }
- void operator()(int val) { if(val==_id) _sigma+=_index[_count+1]-_index[_count]; _count++; }
- int getSigma() const { return _sigma; }
-private:
- int _id;
- const int *_index;
- int _count;
- int _sigma;
-};
-
-/*!
- * This method fills unstructured connectivity using basic MED file format 'medConnFrmt'.
- * If in each elements of 'medConnFrmt' a renumbering cell array is found the aggregate array 'cellRenum' is returned.
- */
-void MEDLoaderNS::tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDLoader::MEDConnOfOneElemType>& medConnFrmt,
- const std::vector<int>& familiesToKeep,
- DataArrayInt* &conn,
- DataArrayInt* &connIndex,
- int *&cellRenum)
-{
- bool keepAll=familiesToKeep.empty();
- if(medConnFrmt.empty())
- {
- conn=0;
- connIndex=0;
- cellRenum=0;
- return ;
- }
- std::list<MEDLoader::MEDConnOfOneElemType>::const_iterator iter=medConnFrmt.begin();
- int totalNbOfCells=0;
- int totalNbOfMedConn=0;
- bool renumber=true;
- cellRenum=0;
- for(;iter!=medConnFrmt.end();iter++)
- {
- if((*iter).getGlobal()==0)
- renumber=false;
- const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::GetCellModel((*iter).getType());
- if(keepAll)
- totalNbOfCells+=(*iter).getLength();
- else
- for(std::vector<int>::const_iterator iter2=familiesToKeep.begin();iter2!=familiesToKeep.end();iter2++)
- totalNbOfCells+=std::count((*iter).getFam(),(*iter).getFam()+(*iter).getLength(),*iter2);
- if(!cellMod.isDynamic())
- if(keepAll)
- totalNbOfMedConn+=(*iter).getLength()*cellMod.getNumberOfNodes();
- else
- for(std::vector<int>::const_iterator iter2=familiesToKeep.begin();iter2!=familiesToKeep.end();iter2++)
- totalNbOfMedConn+=std::count((*iter).getFam(),(*iter).getFam()+(*iter).getLength(),*iter2)*cellMod.getNumberOfNodes();
- else
- if(keepAll)
- totalNbOfMedConn+=(*iter).getConnLength();
- else
- for(std::vector<int>::const_iterator iter2=familiesToKeep.begin();iter2!=familiesToKeep.end();iter2++)
- {
- PolyCounterForFams res=std::for_each((*iter).getFam(),(*iter).getFam()+(*iter).getLength(),PolyCounterForFams(*iter2,(*iter).getIndex()));
- totalNbOfMedConn+=res.getSigma();
- }
- }
- connIndex=DataArrayInt::New();
- conn=DataArrayInt::New();
- connIndex->alloc(totalNbOfCells+1,1);
- int *connIdxPtr=connIndex->getPointer();
- int connFillId=0;
- conn->alloc(totalNbOfMedConn+totalNbOfCells,1);
- int *connPtr=conn->getPointer();
- if(renumber)
- cellRenum=new int[totalNbOfCells];
- int *renumW=cellRenum;
- for(iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++)
- {
- INTERP_KERNEL::NormalizedCellType type=(*iter).getType();
- const int *sourceConn=(*iter).getArray();
- const int *sourceIndex=(*iter).getIndex();
- const int *globalNum=(*iter).getGlobal();
- const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::GetCellModel(type);
- int nbOfCellsInCurType;
- int nbOfNodesIn1Cell=cellMod.getNumberOfNodes();
- nbOfCellsInCurType=(*iter).getLength();
- bool isDyn=cellMod.isDynamic();
- int *tmpConnPtr;
- for(int i=0;i<nbOfCellsInCurType;i++)
- {
- if(keepAll)
- {//duplication of next 3 lines needed.
- *connIdxPtr=connFillId;
- *connPtr++=type;
- if(renumber)
- *renumW++=globalNum[i];
- if(!isDyn)
- tmpConnPtr=std::transform(sourceConn,sourceConn+nbOfNodesIn1Cell,connPtr,std::bind2nd(std::minus<int>(),1));
- else
- tmpConnPtr=std::transform(sourceConn,sourceConn+sourceIndex[i+1]-sourceIndex[i],connPtr,std::bind2nd(std::minus<int>(),1));
- connIdxPtr++;
- nbOfNodesIn1Cell=tmpConnPtr-connPtr;
- connFillId+=nbOfNodesIn1Cell+1;
- connPtr=tmpConnPtr;
- }
- else if(std::find(familiesToKeep.begin(),familiesToKeep.end(),(*iter).getFam()[i])!=familiesToKeep.end())
- {//duplication of next 3 lines needed.
- *connIdxPtr=connFillId;
- *connPtr++=type;
- if(renumber)
- *renumW++=globalNum[i];
- if(!isDyn)
- tmpConnPtr=std::transform(sourceConn,sourceConn+nbOfNodesIn1Cell,connPtr,std::bind2nd(std::minus<int>(),1));
- else//The duplication of code is motivated by the line underneath.
- tmpConnPtr=std::transform((*iter).getArray()+sourceIndex[i]-1,(*iter).getArray()+sourceIndex[i+1]-1,connPtr,std::bind2nd(std::minus<int>(),1));
- connIdxPtr++;
- nbOfNodesIn1Cell=tmpConnPtr-connPtr;
- connFillId+=nbOfNodesIn1Cell+1;
- connPtr=tmpConnPtr;
- }
- sourceConn+=nbOfNodesIn1Cell;
- }
- *connIdxPtr=connFillId;
- }
-}
-
-namespace MEDLoaderNS
-{
- template<class T>
- void releaseMEDFileCoreFrmt(typename std::list<T>& medConnFrmt)
- {
- for(typename std::list<T>::iterator iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++)
- (*iter).releaseArray();
- medConnFrmt.clear();
- }
-}
-
-/*!
- * This method builds a sub set of connectivity for a given type 'type'. \b WARNING connV,connVIndex and familiesV must have same size !
- * @param connV input containing connectivity with MEDCoupling format.
- * @param connVIndex input containing connectivity index in MEDCoupling format.
- * @param familiesV input that may be equal to 0. This specifies an array specifying cell family foreach cell.
- * @param type input specifying which cell types will be extracted in conn4MEDFile.
- * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called.
- * @param connIndex4MEDFile output containing index connectivity understandable by MEDFile; only used by polygons and polyhedrons (it is face nodal connec).
- * @param connIndexRk24MEDFile output containing index of rank 2 understandable by MEDFile; only used by polyhedrons.
- * @param fam4MEDFile output containing family number of cells whose type is 'type'. This output is updated only if 'families' is different than 0.
- * @return nb of elements extracted.
- */
-int MEDLoaderNS::buildMEDSubConnectivityOfOneTypeStaticTypes(const std::vector<const DataArrayInt *>& connV, const std::vector<const DataArrayInt *>& connVIndex, const std::vector<const DataArrayInt *>& familiesV,
- INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber)
-{
- int ret=0;
- int nbOfMeshes=connV.size();
- int renumOffset=0;
- for(int i=0;i<nbOfMeshes;i++)
- {
- const DataArrayInt *conn=connV[i];
- const DataArrayInt *connIndex=connVIndex[i];
- const DataArrayInt *families=familiesV[i];
- int nbOfElem=connIndex->getNbOfElems()-1;
- const int *connPtr=conn->getConstPointer();
- const int *connIdxPtr=connIndex->getConstPointer();
- const int *famPtr=0;
- if(families)
- famPtr=families->getConstPointer();
- for(int ii=0;ii<nbOfElem;ii++)
- {
- int delta=connIdxPtr[1]-connIdxPtr[0];
- if(*connPtr==type)
- {
- conn4MEDFile.insert(conn4MEDFile.end(),connPtr+1,connPtr+delta);
- if(families)
- fam4MEDFile.push_back(famPtr[ii]);
- renumber.push_back(ii+1+renumOffset);
- ret++;
- }
- connIdxPtr++;
- connPtr+=delta;
- }
- renumOffset+=nbOfElem;
- }
- std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1));
- return ret;
-}
-
-int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyg(const std::vector<const DataArrayInt *>&connV, const std::vector<const DataArrayInt *>& connVIndex, const std::vector<const DataArrayInt *>& familiesV,
- std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber)
-{
- int ret=0;
- int nbOfMeshes=connV.size();
- connIndex4MEDFile.push_back(1);
- int renumOffset=0;
- for(int i=0;i<nbOfMeshes;i++)
- {
- const DataArrayInt *conn=connV[i];
- const DataArrayInt *connIndex=connVIndex[i];
- const DataArrayInt *families=familiesV[i];
- int nbOfElem=connIndex->getNbOfElems()-1;
- const int *connPtr=conn->getConstPointer();
- const int *connIdxPtr=connIndex->getConstPointer();
- const int *famPtr=0;
- if(families)
- famPtr=families->getConstPointer();
- for(int ii=0;ii<nbOfElem;ii++)
- {
- int delta=connIdxPtr[1]-connIdxPtr[0];
- if(*connPtr==INTERP_KERNEL::NORM_POLYGON)
- {
- conn4MEDFile.insert(conn4MEDFile.end(),connPtr+1,connPtr+delta);
- connIndex4MEDFile.push_back(connIndex4MEDFile.back()+delta-1);
- if(families)
- fam4MEDFile.push_back(famPtr[ii]);
- renumber.push_back(ii+1+renumOffset);
- ret++;
- }
- connIdxPtr++;
- connPtr+=delta;
- }
- renumOffset+=nbOfElem;
- }
- std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1));
- return ret;
-}
-
-int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyh(const std::vector<const DataArrayInt *>& connV, const std::vector<const DataArrayInt *>& connVIndex, const std::vector<const DataArrayInt *>& familiesV,
- std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile,
- std::vector<int>& fam4MEDFile, std::vector<int>& renumber)
-{
- int ret=0;
- int nbOfMeshes=connV.size();
- connIndexRk24MEDFile.push_back(1);
- connIndex4MEDFile.push_back(1);
- int renumOffset=0;
- for(int i=0;i<nbOfMeshes;i++)
- {
- const DataArrayInt *conn=connV[i];
- const DataArrayInt *connIndex=connVIndex[i];
- const DataArrayInt *families=familiesV[i];
- int nbOfElem=connIndex->getNbOfElems()-1;
- const int *connPtr=conn->getConstPointer();
- const int *connIdxPtr=connIndex->getConstPointer();
- const int *famPtr=0;
- if(families)
- famPtr=families->getConstPointer();
- for(int ii=0;ii<nbOfElem;ii++)
- {
- int delta=connIdxPtr[1]-connIdxPtr[0];
- if(*connPtr==INTERP_KERNEL::NORM_POLYHED)
- {
- int nbOfFacesOfPolyh=std::count(connPtr+1,connPtr+delta,-1)+1;
- const int *work=connPtr+1;
- while(work!=connPtr+delta)
- {
- const int *end=std::find(work,connPtr+delta,-1);
- conn4MEDFile.insert(conn4MEDFile.end(),work,end);
- connIndex4MEDFile.push_back(connIndex4MEDFile.back()+std::distance(work,end));
- if(end==connPtr+delta)
- work=connPtr+delta;
- else
- work=end+1;
- }
- connIndexRk24MEDFile.push_back(connIndexRk24MEDFile.back()+nbOfFacesOfPolyh);
- if(families)
- fam4MEDFile.push_back(famPtr[ii]);
- renumber.push_back(ii+1+renumOffset);
- ret++;
- }
- connIdxPtr++;
- connPtr+=delta;
- }
- renumOffset+=nbOfElem;
- }
- std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1));
- return ret;
-}
-
-/*!
- * This method builds a sub set of connectivity for a given type 'type'.
- * @param conn input containing connectivity with MEDCoupling format.
- * @param connIndex input containing connectivity index in MEDCoupling format.
- * @param families input containing, if any, the family number of each cells
- * @param type input specifying which cell types will be extracted in conn4MEDFile.
- * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called.
- * @param connIndex4MEDFile output containing index connectivity understandable by MEDFile; only used by polygons and polyhedrons (it is face nodal connec).
- * @param connIndexRk24MEDFile output containing index of rank 2 understandable by MEDFile; only used by polyhedrons.
- * @param fam4MEDFile output containing families id of cells whose type is 'type'.
- * @return nb of elements extracted.
- */
-int MEDLoaderNS::buildMEDSubConnectivityOfOneType(const std::vector<const DataArrayInt *>& conn, const std::vector<const DataArrayInt *>& connIndex, const std::vector<const DataArrayInt *>& families,
- INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile,
- std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber)
-{
-
- const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::GetCellModel(type);
- if(!cellMod.isDynamic())
- return buildMEDSubConnectivityOfOneTypeStaticTypes(conn,connIndex,families,type,conn4MEDFile,fam4MEDFile,renumber);
- else
- {
- if(type==INTERP_KERNEL::NORM_POLYGON)
- return buildMEDSubConnectivityOfOneTypesPolyg(conn,connIndex,families,conn4MEDFile,connIndex4MEDFile,fam4MEDFile,renumber);
- else
- return buildMEDSubConnectivityOfOneTypesPolyh(conn,connIndex,families,conn4MEDFile,connIndex4MEDFile,connIndexRk24MEDFile,fam4MEDFile,renumber);
- }
-}
-
-/*!
- * @param ids is a in vector containing families ids whose cells have to be kept. If empty all cells are kept.
- * @param typesToKeep is a in vector that indicates which types to keep after dimension filtering.
- * @param meshDimExtract out parameter that gives the mesh dimension.
- * @param cellRenum out parameter that specifies the renumbering (if !=0) of cells in file.
- */
-MEDCouplingUMesh *MEDLoaderNS::readUMeshFromFileLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<int>& ids,
- const std::vector<INTERP_KERNEL::NormalizedCellType>& typesToKeep, unsigned& meshDimExtract, int *&cellRenum) throw(INTERP_KERNEL::Exception)