X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileFieldOverView.cxx;h=42b4759ebdfe0c3ae3eb93582fe4e4059d9b6634;hb=f13ce72017fd205546293a53f7b041824cb50eec;hp=2d42a00fbed6e9b030114aa48439fb309f66b439;hpb=629f21d191714b25df5c7be23873f8b38d5ce3d3;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileFieldOverView.cxx b/src/MEDLoader/MEDFileFieldOverView.cxx index 2d42a00fb..42b4759eb 100644 --- a/src/MEDLoader/MEDFileFieldOverView.cxx +++ b/src/MEDLoader/MEDFileFieldOverView.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// Copyright (C) 2007-2014 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 // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -27,7 +27,9 @@ using namespace ParaMEDMEM; const unsigned char MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE[MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH]= - {1,3,21,5,9,7,22,34,23,28,255,255,255,255,10,14,13,255,12,255,24,255,16,27,255,26,255,29,255,255,25,42,36,4}; +{1,3,21,5,9,7,22,34,23,28,255,255,255,255,10,14,13,255,12,255,24,255,16,27,255,26,255,29,255,255,25,42,36,4}; + +const unsigned char MEDMeshMultiLev::HEXA27_PERM_ARRAY[27]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26}; const char MEDFileField1TSStructItem2::NEWLY_CREATED_PFL_NAME[]="???"; @@ -52,12 +54,15 @@ std::vector MEDFileMeshStruct::getDirectChildren() cons MEDFileMeshStruct::MEDFileMeshStruct(const MEDFileMesh *mesh):_mesh(mesh) { - std::vector levs=mesh->getNonEmptyLevels(); + std::vector levs(mesh->getNonEmptyLevels()); _name=mesh->getName(); _nb_nodes=mesh->getNumberOfNodes(); - _geo_types_distrib.resize(levs.size()); - for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) - _geo_types_distrib[-(*lev)]=mesh->getDistributionOfTypes(*lev); + if(!levs.empty()) + { + _geo_types_distrib.resize(-(*std::min_element(levs.begin(),levs.end()))+1); + for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) + _geo_types_distrib[-(*lev)]=mesh->getDistributionOfTypes(*lev); + } } int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const @@ -76,6 +81,9 @@ int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) co throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : The specified geometric type is not present in the mesh structure !"); } +/*! + * \sa MEDFileMeshStruct::doesManageGeoType + */ int MEDFileMeshStruct::getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellType t) const { for(std::vector< std::vector >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++) @@ -91,6 +99,42 @@ int MEDFileMeshStruct::getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellTy throw INTERP_KERNEL::Exception("The specified geometric type is not present in the mesh structure !"); } +/*! + * \sa MEDFileMeshStruct::getNumberOfElemsOfGeoType + */ +bool MEDFileMeshStruct::doesManageGeoType(INTERP_KERNEL::NormalizedCellType t) const +{ + for(std::vector< std::vector >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++) + { + std::size_t sz=(*it1).size(); + if(sz%3!=0) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::doesManageGeoType : internal error in code !"); + std::size_t nbGeo=sz/3; + for(std::size_t i=0;ihasImplicitPart()) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::appendIfImplicitType : by default no implicit geo type can be appended !"); + static const char MSG[]="MEDFileMeshStruct::appendIfImplicitType : the distribution does not looks like structured standard !"; + if(_geo_types_distrib.size()!=1) + throw INTERP_KERNEL::Exception(MSG); + std::size_t sz(_geo_types_distrib[0].size()); + if(sz%3!=0) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::appendIfImplicitType : internal error in code !"); + std::size_t nbGeo(sz/3); + if(nbGeo!=1) + throw INTERP_KERNEL::Exception(MSG); + std::vector arr(3); arr[0]=(int)t; arr[1]=_mesh->buildImplicitPartIfAny(t); arr[2]=-1; + _geo_types_distrib.push_back(arr); +} + + int MEDFileMeshStruct::getNumberOfLevs() const { return (int)_geo_types_distrib.size(); @@ -165,6 +209,15 @@ void MEDMeshMultiLev::setNodeReduction(const DataArrayInt *nr) _node_reduction=const_cast(nr); } +void MEDMeshMultiLev::setCellReduction(const DataArrayInt *cr) +{ + if(_pfls.size()!=1) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::setCellReduction : can be used only for single geo type mesh !"); + _pfls[0]=const_cast(cr); + if(cr) + cr->incrRef(); +} + bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const { if(fst.getType()==ON_NODES) @@ -176,6 +229,8 @@ bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst const DataArrayInt *nr(_node_reduction); if(pflName.empty() && !nr) return true; + if(!pflName.empty() && !nr) + return false; if(pflName==nr->getName()) return true; return false; @@ -335,6 +390,11 @@ void MEDMeshMultiLev::retrieveNumberIdsOnNodes(DataArrayInt *& numIds, bool& isW } } +std::vector< INTERP_KERNEL::NormalizedCellType > MEDMeshMultiLev::getGeoTypes() const +{ + return _geo_types; +} + void MEDMeshMultiLev::setFamilyIdsOnCells(DataArrayInt *famIds, bool isNoCopy) { _cell_fam_ids=famIds; @@ -387,7 +447,7 @@ int MEDMeshMultiLev::getNumberOfCells(INTERP_KERNEL::NormalizedCellType t) const std::size_t sz(_nb_entities.size()); for(std::size_t i=0;ideepCpy(); if(pflName.empty() && nr) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 2 !"); + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 2 !"); if(!pflName.empty() && nr) { MEDCouplingAutoRefCountObjectPtr p1(globs->getProfile(pflName.c_str())->deepCpy()); MEDCouplingAutoRefCountObjectPtr p2(nr->deepCpy()); p1->sort(true); p2->sort(true); if(!p1->isEqualWithoutConsideringStr(*p2)) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 3 !"); + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : it appears that a profile on nodes does not cover the cells correctly !"); p1=DataArrayInt::FindPermutationFromFirstToSecond(globs->getProfile(pflName.c_str()),nr); MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); ret->renumberInPlace(p1->begin()); @@ -543,11 +603,56 @@ DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& } } -MEDMeshMultiLev::MEDMeshMultiLev():_nb_nodes(0),_cell_fam_ids_nocpy(false) +/*! + * This method is called to add NORM_POINT1 cells in \a this so that orphan nodes in \a verticesToAdd will be fetched. + */ +void MEDMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr) { + int nbOfVertices(verticesToAdd->getNumberOfTuples()); + std::size_t sz(_pfls.size()); + _pfls.resize(sz+1); + _geo_types.resize(sz+1,INTERP_KERNEL::NORM_POINT1); + _nb_entities.resize(sz+1,nbOfVertices); + _node_reduction=nr; nr->incrRef(); + _nb_nodes+=nbOfVertices; + const DataArrayInt *cf(_cell_fam_ids),*cn(_cell_num_ids),*nf(_node_fam_ids),*nn(_node_num_ids); + if(cf) + { + MEDCouplingAutoRefCountObjectPtr tmp; + std::vector a(2); + a[0]=cf; + if(nf) + tmp=nf->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end()); + else + { + tmp=DataArrayInt::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero(); + } + a[1]=tmp; + _cell_fam_ids=DataArrayInt::Aggregate(a); + _cell_fam_ids_nocpy=false; + } + if(cn) + { + MEDCouplingAutoRefCountObjectPtr tmp; + std::vector a(2); + a[0]=cn; + if(nn) + tmp=nn->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end()); + else + { + tmp=DataArrayInt::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero(); + } + a[1]=tmp; + _cell_num_ids=DataArrayInt::Aggregate(a); + _cell_num_ids_nocpy=false; + } } -MEDMeshMultiLev::MEDMeshMultiLev(int nbNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):_geo_types(gts),_nb_entities(nbEntities),_nb_nodes(nbNodes),_cell_fam_ids_nocpy(false),_cell_num_ids_nocpy(false),_node_fam_ids_nocpy(false),_node_num_ids_nocpy(false) +MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh):_mesh(mesh),_nb_nodes(0),_cell_fam_ids_nocpy(false) +{ +} + +MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh, int nbNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):_mesh(mesh),_geo_types(gts),_nb_entities(nbEntities),_nb_nodes(nbNodes),_cell_fam_ids_nocpy(false),_cell_num_ids_nocpy(false),_node_fam_ids_nocpy(false),_node_num_ids_nocpy(false) { std::size_t sz(_geo_types.size()); if(sz!=pfls.size() || sz!=nbEntities.size()) @@ -561,7 +666,7 @@ MEDMeshMultiLev::MEDMeshMultiLev(int nbNodes, const std::vector& levs) +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& levs):MEDMeshMultiLev(m) { if(!m) throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : null input pointer !"); @@ -583,6 +688,10 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector v.insert(v.end(),vTmp.begin(),vTmp.end()); } std::size_t sz(v.size()); + if(v.empty()) + { + _coords=m->getCoords(); _coords->incrRef(); + } _parts.resize(sz); _pfls.resize(sz); _geo_types.resize(sz); @@ -619,7 +728,7 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector if(!tmps[i]) f=false; } - if(f) + if(f && !tmps.empty()) _cell_fam_ids=DataArrayInt::Aggregate(tmps); } _cell_num_ids_nocpy=(levs.size()==1); @@ -642,7 +751,7 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector if(!tmps[i]) n=false; } - if(n) + if(n && !tmps.empty()) _cell_num_ids=DataArrayInt::Aggregate(tmps); } // node part @@ -671,7 +780,7 @@ MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector return new MEDUMeshMultiLev(m,gts,pfls,nbEntities); } -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(m->getNumberOfNodes(),gts,pfls,nbEntities) +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) { std::size_t sz(gts.size()); if(sz<1) @@ -752,33 +861,44 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vectorisAllocated()) - return ; - std::size_t sz(_parts.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > a(sz); - std::vector< const DataArrayInt *> aa(sz); - for(std::size_t i=0;i m(_parts[i]); - if(pfl) - m=dynamic_cast(_parts[i]->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - DataArrayInt *cellIds=0; - m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds); - MEDCouplingAutoRefCountObjectPtr cellIdsSafe(cellIds); - MEDCouplingAutoRefCountObjectPtr m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); - int tmp=-1; - MEDCouplingAutoRefCountObjectPtr o2n(m2->getNodeIdsInUse(tmp)); - a[i]=o2n->invertArrayO2N2N2O(tmp); aa[i]=a[i]; - if(pfl) - _pfls[i]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); - else - _pfls[i]=cellIdsSafe; - } - _node_reduction=DataArrayInt::Aggregate(aa); - _node_reduction->sort(true); - _node_reduction=_node_reduction->buildUnique(); + if(!pflNodes || !pflNodes->isAllocated()) + return ; + std::size_t sz(_parts.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr > a(sz); + std::vector< const DataArrayInt *> aa(sz); + for(std::size_t i=0;i m(_parts[i]); + if(pfl) + m=dynamic_cast(_parts[i]->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); + DataArrayInt *cellIds=0; + m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds); + MEDCouplingAutoRefCountObjectPtr cellIdsSafe(cellIds); + MEDCouplingAutoRefCountObjectPtr m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); + int tmp=-1; + MEDCouplingAutoRefCountObjectPtr o2n(m2->getNodeIdsInUse(tmp)); + a[i]=o2n->invertArrayO2N2N2O(tmp); aa[i]=a[i]; + if(pfl) + _pfls[i]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); + else + _pfls[i]=cellIdsSafe; + } + if(!aa.empty()) + _node_reduction=DataArrayInt::Aggregate(aa);//general case + else + _node_reduction=pflNodes->deepCpy();//case where no cells in read mesh. + _node_reduction->sort(true); + _node_reduction=_node_reduction->buildUnique(); + if(_node_reduction->getNumberOfTuples()==pflNodes->getNumberOfTuples()) + return ;//This is the classical case where the input node profile corresponds perfectly to a subset of cells in _parts + if(_node_reduction->getNumberOfTuples()>pflNodes->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::selectPartOfNodes : internal error in MEDCoupling during cell select from a list of nodes !"); + // Here the cells available in _parts is not enough to cover all the nodes in pflNodes. So adding vertices cells in _parts... + MEDCouplingAutoRefCountObjectPtr pflNodes2(pflNodes->deepCpy()); + pflNodes2->sort(true); + MEDCouplingAutoRefCountObjectPtr diff(pflNodes2->buildSubstractionOptimized(_node_reduction)); + appendVertices(diff,pflNodes2); } MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const @@ -786,7 +906,7 @@ MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const return new MEDUMeshMultiLev(*this); } -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts) +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts),_coords(other._coords) { } @@ -800,16 +920,17 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const } /*! + * To be called only once ! Because due to some optimizations (sometimes aggressive) the internal state can be changed... * If returned value is false output pointer \a coords is not the internal pointer. If returned value is true output pointer \a coords is directly the internal pointer. * If true is returned, the \a coords output parameter should be used with care (non const method call) to avoid to change the internal state of MEDFileUMesh instance. */ bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const { + const DataArrayDouble *tmp(0); if(_parts.empty()) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : empty array !"); - if(!(const MEDCoupling1GTUMesh *)_parts[0]) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : first part is null !"); - const DataArrayDouble *tmp(_parts[0]->getCoords()); + tmp=_coords; + else + tmp=_parts[0]->getCoords(); if(!tmp) throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : the coordinates are null !"); MEDCouplingAutoRefCountObjectPtr a(const_cast(tmp)); tmp->incrRef(); @@ -875,12 +996,25 @@ bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte * throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : internal error !"); if(scur) { - int nnpc(scur->getNumberOfNodesPerCell()); - for(int i=0;igetCellModelEnum()!=INTERP_KERNEL::NORM_HEXA27) { - *dPtr++=nnpc; - dPtr=std::copy(connPtr,connPtr+nnpc,dPtr); - *cPtr++=k; k+=nnpc+1; + int nnpc(scur->getNumberOfNodesPerCell()); + for(int i=0;iisObjectInTheProgeny(coords); } void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const @@ -952,6 +1086,11 @@ void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr< const DataArrayInt *nr(_node_reduction); if(!nr) return ; + if(nodalConnVTK->empty() && !polyhedNodalConnVTK) + { + coords=(coords->selectByTupleIdSafe(nr->begin(),nr->end())); + return ; + } int sz(coords->getNumberOfTuples()); std::vector b(sz,false); const int *work(nodalConnVTK->begin()),*endW(nodalConnVTK->end()); @@ -1022,13 +1161,42 @@ void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr< coords=(coords->selectByTupleIdSafe(nr->begin(),nr->end())); } + +void MEDUMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr) +{ + int nbOfCells(verticesToAdd->getNumberOfTuples());//it is not a bug cells are NORM_POINT1 + MEDMeshMultiLev::appendVertices(verticesToAdd,nr); + MEDCouplingAutoRefCountObjectPtr elt(MEDCoupling1SGTUMesh::New("",INTERP_KERNEL::NORM_POINT1)); + elt->allocateCells(nbOfCells); + for(int i=0;igetIJ(i,0)); + elt->insertNextCell(&pt,&pt+1); + } + if(_parts.empty()) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::appendVertices : parts are empty !"); + elt->setCoords(_parts[0]->getCoords()); + MEDCouplingAutoRefCountObjectPtr elt2((MEDCoupling1SGTUMesh *)elt); elt2->incrRef(); + _parts.push_back(elt2); +} + //= -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev() +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector& lev):MEDMeshMultiLev(m),_is_internal(true) +{ + initStdFieldOfIntegers(m); +} + +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, int nbOfNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(m,nbOfNodes,gts,pfls,nbEntities),_is_internal(true) { + initStdFieldOfIntegers(m); } -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector& lev) +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other),_is_internal(true),_face_fam_ids(other._face_fam_ids),_face_fam_ids_nocpy(other._face_fam_ids_nocpy),_face_num_ids(other._face_num_ids),_face_num_ids_nocpy(other._face_num_ids_nocpy) +{ +} + +void MEDStructuredMeshMultiLev::initStdFieldOfIntegers(const MEDFileStructuredMesh *m) { // ids fields management _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true; @@ -1060,39 +1228,72 @@ MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh tmp->incrRef(); _node_num_ids=const_cast(tmp); } -} - -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, int nbOfNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(nbOfNodes,gts,pfls,nbEntities) -{ - // ids fields management - _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true; - const DataArrayInt *tmp(0); - tmp=m->getFamilyFieldAtLevel(0); + // faces (if any) + _face_fam_ids_nocpy=true; _face_num_ids_nocpy=true; + tmp=m->getFamilyFieldAtLevel(-1); if(tmp) { tmp->incrRef(); - _cell_fam_ids=const_cast(tmp); + _face_fam_ids=const_cast(tmp); } - tmp=m->getNumberFieldAtLevel(0); + tmp=m->getNumberFieldAtLevel(-1); if(tmp) { tmp->incrRef(); - _cell_num_ids=const_cast(tmp); + _face_num_ids=const_cast(tmp); } - // - _node_fam_ids_nocpy=true; _node_num_ids_nocpy=true; - tmp=0; - tmp=m->getFamilyFieldAtLevel(1); +} + +void MEDStructuredMeshMultiLev::moveFaceToCell() const +{ + const_cast(this)->_cell_fam_ids_nocpy=_face_fam_ids_nocpy; + const_cast(this)->_cell_num_ids_nocpy=_face_num_ids_nocpy; + const_cast(this)->_cell_fam_ids=_face_fam_ids; const_cast(this)->_face_fam_ids=0; + const_cast(this)->_cell_num_ids=_face_num_ids; const_cast(this)->_face_num_ids=0; +} + +bool MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase(MEDMeshMultiLev *&ret) const +{ + ret=0; + if(_geo_types.empty()) + return false; + if(_geo_types.size()!=1) + throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase only one geo types supported at most supported for the moment !"); + INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(_mesh->getMeshDimension())); + if(_geo_types[0]==gt) + return false; + MEDCoupling1GTUMesh *facesIfPresent((static_cast(_mesh))->getImplicitFaceMesh()); + if(!facesIfPresent) + return false; + const DataArrayInt *pfl(0),*nr(_node_reduction); + if(!_pfls.empty()) + pfl=_pfls[0]; + MEDCouplingAutoRefCountObjectPtr facesIfPresent2(facesIfPresent); facesIfPresent->incrRef(); + moveFaceToCell(); + MEDCouplingAutoRefCountObjectPtr ret2(new MEDUMeshMultiLev(*this,facesIfPresent2)); + if(pfl) + ret2->setCellReduction(pfl); + if(nr) + throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase : case is not treated yet for node reduction on implicit unstructured mesh."); + ret=ret2.retn(); + return true; +} + +void MEDStructuredMeshMultiLev::dealWithImplicitUnstructuredMesh(const MEDFileMesh *m) +{ + _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true; + const DataArrayInt *tmp(0); + tmp=m->getFamilyFieldAtLevel(-1); if(tmp) { tmp->incrRef(); - _node_fam_ids=const_cast(tmp); + _cell_fam_ids=const_cast(tmp); } - tmp=m->getNumberFieldAtLevel(1); + tmp=m->getNumberFieldAtLevel(-1); if(tmp) { tmp->incrRef(); - _node_num_ids=const_cast(tmp); + _cell_num_ids=const_cast(tmp); } } @@ -1121,10 +1322,6 @@ void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) _pfls[0]=cellIdsSafe; } -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other) -{ -} - //= MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& levs) @@ -1143,13 +1340,14 @@ MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor : null input pointer !"); if(levs.size()!=1 || levs[0]!=0) throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor : levels supported is 0 only !"); - int mdim(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension())); - _coords.resize(mdim); - for(int i=0;igetSpaceDimension()); + _coords.resize(sdim); + for(int i=0;i(m->getMesh()->getCoordsAt(i))); if(!elt) throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !"); + elt->incrRef(); _coords[i]=elt; } } @@ -1162,16 +1360,19 @@ MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vectorgetMeshDimension()); INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim)); - if(gt!=gts[0]) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : the unique geo type is invalid regarding meshdim !"); - _coords.resize(mdim); - for(int i=0;i(m->getMesh()->getCoordsAt(i))); - if(!elt) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !"); - _coords[i]=elt; _coords[i]->incrRef(); + _coords.resize(mdim); + for(int i=0;i(m->getMesh()->getCoordsAt(i))); + if(!elt) + throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !"); + _coords[i]=elt; _coords[i]->incrRef(); + } } + else + dealWithImplicitUnstructuredMesh(m); } MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDCMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords) @@ -1188,7 +1389,12 @@ std::vector MEDCMeshMultiLev::getNodeGridStructure() const MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const { - const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction); + MEDMeshMultiLev *retSpecific(0); + if(prepareForImplicitUnstructuredMeshCase(retSpecific)) + return retSpecific; + const DataArrayInt *pfl(0),*nr(_node_reduction); + if(!_pfls.empty()) + pfl=_pfls[0]; MEDCouplingAutoRefCountObjectPtr nnr; std::vector cgs,ngs(getNodeGridStructure()); cgs.resize(ngs.size()); @@ -1200,6 +1406,7 @@ MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) { MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); + ret->_is_internal=false; if(nr) { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } ret->_nb_entities[0]=pfl->getNumberOfTuples(); @@ -1234,7 +1441,7 @@ MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const ret2->setNumberIdsOnCells(tmp,false); } return ret2.retn(); - + } else { @@ -1245,8 +1452,12 @@ MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const } } -std::vector< DataArrayDouble * > MEDCMeshMultiLev::buildVTUArrays() const +/*! + * \a param [out] isInternal if true the returned pointers are those in main data structure. If false those pointers have been built espacially for that method. + */ +std::vector< DataArrayDouble * > MEDCMeshMultiLev::buildVTUArrays(bool& isInternal) const { + isInternal=_is_internal; std::size_t sz(_coords.size()); std::vector< DataArrayDouble * > ret(sz); for(std::size_t i=0;igetMeshDimension())); - if(mdim!=gts[0]) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : the unique geo type is invalid regarding meshdim !"); - DataArrayDouble *coords(const_cast(m->getMesh()->getCoords())); - if(!coords) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !"); - coords->incrRef(); - _coords=coords; - _structure=m->getMesh()->getNodeGridStructure(); + INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension())); + if(gt==gts[0]) + { + DataArrayDouble *coords(const_cast(m->getMesh()->getCoords())); + if(!coords) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !"); + coords->incrRef(); + _coords=coords; + _structure=m->getMesh()->getNodeGridStructure(); + } + else + dealWithImplicitUnstructuredMesh(m); } MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords),_structure(other._structure) @@ -1311,7 +1525,12 @@ std::vector MEDCurveLinearMeshMultiLev::getNodeGridStructure() const MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const { - const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction); + MEDMeshMultiLev *retSpecific(0); + if(prepareForImplicitUnstructuredMeshCase(retSpecific)) + return retSpecific; + const DataArrayInt *pfl(0),*nr(_node_reduction); + if(!_pfls.empty()) + pfl=_pfls[0]; MEDCouplingAutoRefCountObjectPtr nnr; std::vector cgs,ngs(getNodeGridStructure()); cgs.resize(ngs.size()); @@ -1331,6 +1550,7 @@ MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const } MEDCouplingAutoRefCountObjectPtr p(MEDCouplingStructuredMesh::BuildExplicitIdsFrom(ngs,nodeParts)); MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); + ret->_is_internal=false; if(nr) { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } ret->_nb_entities[0]=pfl->getNumberOfTuples(); @@ -1372,8 +1592,9 @@ MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const } } -void MEDCurveLinearMeshMultiLev::buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct) const +void MEDCurveLinearMeshMultiLev::buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct, bool& isInternal) const { + isInternal=_is_internal; nodeStrct=_structure; const DataArrayDouble *coo(_coords); if(!coo) @@ -1394,6 +1615,11 @@ MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::Normalized void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) { + if(!mst->doesManageGeoType(_geo_type)) + { + MEDFileMeshStruct *mstUnConstCasted(const_cast(mst)); + mstUnConstCasted->appendIfImplicitType(_geo_type); + } int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); checkInRange(nbOfEnt,1,globs); } @@ -1474,7 +1700,7 @@ void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MED } } -bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const char *pflName) const +bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const std::string& pflName) const { if(startExp!=_start_end.first) return false; @@ -1486,7 +1712,7 @@ bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::Nor return true; } -bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const { //_nb_of_entity is not taken into account here. It is not a bug, because no mesh consideration needed here to perform fast compare. //idem for _loc. It is not an effective attribute for support comparison. @@ -1586,7 +1812,7 @@ MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::v void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) { switch(_type) - { + { case ON_NODES: { int nbOfEnt=mst->getNumberOfNodes(); @@ -1615,10 +1841,10 @@ void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst } default: throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : not managed field type !"); - } + } } -bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const { if(_type!=other._type) return false; @@ -1771,7 +1997,7 @@ bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, return false; } -const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const throw(INTERP_KERNEL::Exception) +const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const { if(i>=_items.size()) throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !"); @@ -1808,6 +2034,31 @@ MEDMeshMultiLev *MEDFileField1TSStructItem::buildFromScratchDataSetSupportOnCell return MEDMeshMultiLev::New(mst->getTheMesh(),a0,a1,a2); } +std::vector MEDFileField1TSStructItem::getGeoTypes(const MEDFileMesh *m) const +{ + std::vector ret; + if(_type==ON_NODES) + { + if(!_items.empty() && _items[0].getPflName().empty()) + { + if(m) + return m->getAllGeoTypes(); + else + return ret; + } + else + return ret; + } + for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) + { + INTERP_KERNEL::NormalizedCellType elt((*it).getGeo()); + std::vector::iterator it2(std::find(ret.begin(),ret.end(),elt)); + if(it2==ret.end()) + ret.push_back(elt); + } + return ret; +} + MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt) { TypeOfField atype; @@ -1816,7 +2067,7 @@ MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFile std::vector< std::vector > pfls,locs; std::vector< std::vector > typesF; std::vector geoTypes; - std::vector< std::vector > > strtEnds=ref->getFieldSplitedByType(0,geoTypes,typesF,pfls,locs); + std::vector< std::vector > > strtEnds=ref->getFieldSplitedByType(std::string(),geoTypes,typesF,pfls,locs); std::size_t nbOfGeoTypes(geoTypes.size()); if(nbOfGeoTypes==0) throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref !"); @@ -1965,9 +2216,8 @@ MEDMeshMultiLev *MEDFileField1TSStruct::buildFromScratchDataSetSupport(const MED else { if(!presenceOfPartialNodeDiscr(pos1)) - {//we have only all nodes, no cell definition info -> level 0; - std::vector levs(1,0); - return MEDMeshMultiLev::New(mst->getTheMesh(),levs); + {//we have only all nodes, no cell definition info -> all existing levels !; + return MEDMeshMultiLev::New(mst->getTheMesh(),mst->getTheMesh()->getNonEmptyLevels()); } else return MEDMeshMultiLev::NewOnlyOnNode(mst->getTheMesh(),_already_checked[pos1][0].getPfl(globs)); @@ -1991,6 +2241,24 @@ bool MEDFileField1TSStruct::isDataSetSupportFastlyEqualTo(const MEDFileField1TSS return true; } +std::vector MEDFileField1TSStruct::getGeoTypes(const MEDFileMesh *m) const +{ + std::vector ret; + for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) + { + std::vector ret2((*it).getGeoTypes(m)); + for(std::vector::const_iterator it2=ret2.begin();it2!=ret2.end();it2++) + { + if(*it2==INTERP_KERNEL::NORM_ERROR) + continue; + std::vector::iterator it3(std::find(ret.begin(),ret.end(),*it2)); + if(it3==ret.end()) + ret.push_back(*it2); + } + } + return ret; +} + /*! * Returns true if presence in \a this of discretization ON_CELLS, ON_GAUSS_PT, ON_GAUSS_NE. * If true is returned the pos of the easiest is returned. The easiest is the first element in \a this having the less splitted subparts. @@ -2144,3 +2412,24 @@ bool MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne(int const MEDFileField1TSStruct *objRef(_f1ts_cmps[timeStepId-1]); return objRef->isDataSetSupportFastlyEqualTo(*obj,globs); } + +int MEDFileFastCellSupportComparator::getNumberOfTS() const +{ + return _f1ts_cmps.size(); +} + +std::vector MEDFileFastCellSupportComparator::getGeoTypesAt(int timeStepId, const MEDFileMesh *m) const +{ + if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size()) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::getGeoTypesAt : requested time step id #" << timeStepId << " is not in [0," << _f1ts_cmps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileField1TSStruct *elt(_f1ts_cmps[timeStepId]); + if(!elt) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::getGeoTypesAt : requested time step id #" << timeStepId << " points to a NULL pointer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return elt->getGeoTypes(m); +}