From: ageay Date: Fri, 26 Jul 2013 08:26:29 +0000 (+0000) Subject: MEDReader ready -> let's debug X-Git-Tag: B4PolyhIntersect~42 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=3f65596cd3eb0b6f4b6ef47ed543debf3d79d86b;p=modules%2Fmed.git MEDReader ready -> let's debug --- diff --git a/src/MEDLoader/MEDFileFieldOverView.cxx b/src/MEDLoader/MEDFileFieldOverView.cxx index 4f099caa1..2552ebd47 100644 --- a/src/MEDLoader/MEDFileFieldOverView.cxx +++ b/src/MEDLoader/MEDFileFieldOverView.cxx @@ -107,1483 +107,1525 @@ int MEDFileMeshStruct::getNumberOfGeoTypesInLev(int relativeLev) const throw(INT //= -MEDFileField1TSStructItem2::MEDFileField1TSStructItem2() +std::size_t MEDMeshMultiLev::getHeapMemorySize() const { + return 0; } -MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair& b, const std::string& c, const std::string& d):_geo_type(a),_start_end(b),_pfl(DataArrayInt::New()),_loc(d),_nb_of_entity(-1) +MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& levs) throw(INTERP_KERNEL::Exception) { - _pfl->setName(c.c_str()); + if(!m) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : null input pointer !"); + const MEDFileUMesh *um(dynamic_cast(m)); + if(um) + return MEDUMeshMultiLev::New(um,levs); + const MEDFileCMesh *cm(dynamic_cast(m)); + if(cm) + return MEDCMeshMultiLev::New(cm,levs); + const MEDFileCurveLinearMesh *clm(dynamic_cast(m)); + if(clm) + return MEDCurveLinearMeshMultiLev::New(clm,levs); + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !"); } -void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception) { - int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); - checkInRange(nbOfEnt,1,globs); + if(!m) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : null input pointer !"); + const MEDFileUMesh *um(dynamic_cast(m)); + if(um) + return MEDUMeshMultiLev::New(um,gts,pfls,nbEntities); + const MEDFileCMesh *cm(dynamic_cast(m)); + if(cm) + return MEDCMeshMultiLev::New(cm,gts,pfls,nbEntities); + const MEDFileCurveLinearMesh *clm(dynamic_cast(m)); + if(clm) + return MEDCurveLinearMeshMultiLev::New(clm,gts,pfls,nbEntities); + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !"); } -void MEDFileField1TSStructItem2::checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev *MEDMeshMultiLev::NewOnlyOnNode(const MEDFileMesh *m, const DataArrayInt *pflOnNode) throw(INTERP_KERNEL::Exception) { - int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - checkInRange(nbOfEnt,(int)cm.getNumberOfNodes(),globs); + std::vector levs(1,0); + MEDCouplingAutoRefCountObjectPtr ret(MEDMeshMultiLev::New(m,levs)); + ret->selectPartOfNodes(pflOnNode); + return ret.retn(); } -void MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +void MEDMeshMultiLev::setNodeReduction(const DataArrayInt *nr) { - if(!globs) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no globals specified !"); - if(_loc.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no localization specified !"); - const MEDFileFieldLoc& loc=globs->getLocalization(_loc.c_str()); - int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); - checkInRange(nbOfEnt,loc.getNumberOfGaussPoints(),globs); + if(nr) + nr->incrRef(); + _node_reduction=const_cast(nr); } -int MEDFileField1TSStructItem2::getNbOfIntegrationPts(const MEDFileFieldGlobsReal *globs) const +bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) { - if(_loc.empty()) + if(fst.getType()==ON_NODES) { - if(getPflName().empty()) - return (_start_end.second-_start_end.first)/_nb_of_entity; - else - return (_start_end.second-_start_end.first)/getPfl(globs)->getNumberOfTuples(); + if(fst.getNumberOfItems()!=1) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::isFastlyTheSameStruct : unexpected situation for nodes !"); + const MEDFileField1TSStructItem2& p(fst[0]); + std::string pflName(p.getPflName()); + const DataArrayInt *nr(_node_reduction); + if(pflName.empty() && !nr) + return true; + if(pflName==nr->getName()) + return true; + return false; } else { - const MEDFileFieldLoc& loc(globs->getLocalization(_loc.c_str())); - return loc.getNumberOfGaussPoints(); + std::size_t sz(fst.getNumberOfItems()); + if(sz!=_geo_types.size()) + return false; + int strt(0); + for(std::size_t i=0;igetName(); + MEDCouplingAutoRefCountObjectPtr ret(const_cast(vals)); ret->incrRef(); + if(isFastlyTheSameStruct(fst,globs)) + return ret.retn(); + else + return constructDataArray(fst,globs,vals); } -const DataArrayInt *MEDFileField1TSStructItem2::getPfl(const MEDFileFieldGlobsReal *globs) const +std::string MEDMeshMultiLev::getPflNameOfId(int id) const { - if(!_pfl->isAllocated()) - { - if(_pfl->getName().empty()) - return 0; - else - return globs->getProfile(_pfl->getName().c_str()); - } - else - return _pfl; + std::size_t sz(_pfls.size()); + if(id<0 || id>=sz) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::getPflNameOfId : invalid input id !"); + const DataArrayInt *pfl(_pfls[id]); + if(!pfl) + return std::string(""); + return pfl->getName(); } -/*! - * \param [in] nbOfEntity - number of entity that can be either cells or nodes. Not other possiblity. - * \param [in] nip - number of integration points. 1 for ON_CELLS and NO_NODES - */ -void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const throw(INTERP_KERNEL::Exception) { - _nb_of_entity=nbOfEntity; - if(_pfl->getName().empty()) + if(fst.getType()==ON_NODES) { - if(nbOfEntity!=(_start_end.second-_start_end.first)/nip) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Mismatch between number of entities and size of node field !"); - return ; + if(fst.getNumberOfItems()!=1) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes !"); + const MEDFileField1TSStructItem2& p(fst[0]); + std::string pflName(p.getPflName()); + const DataArrayInt *nr(_node_reduction); + if(pflName.empty() && !nr) + return vals->deepCpy(); + if(pflName.empty() && nr) + 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 !"); + p1=DataArrayInt::FindPermutationFromFirstToSecond(globs->getProfile(pflName.c_str()),nr); + MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); + ret->renumberInPlace(p1->begin()); + return ret.retn(); + } + if(!pflName.empty() && !nr) + { + MEDCouplingAutoRefCountObjectPtr p1(globs->getProfile(pflName.c_str())->deepCpy()); + p1->sort(true); + if(!p1->isIdentity() || p1->getNumberOfTuples()!=p.getNbEntity()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 4 !"); + MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); + ret->renumberInPlace(globs->getProfile(pflName.c_str())->begin()); + return ret.retn(); + } + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 5 !"); } else { - if(!globs) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no globals found in file !"); - const DataArrayInt *pfl=globs->getProfile(_pfl->getName().c_str()); - if(!pfl) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no such profile found in file !"); - pfl->checkAllIdsInRange(0,nbOfEntity); + std::size_t sz(fst.getNumberOfItems()); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrSafe(sz); + std::vector< const DataArray *> arr(sz); + for(std::size_t i=0;i& strtStop(p.getStartStop()); + std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator it(std::find(_geo_types.begin(),_geo_types.end(),p.getGeo())); + if(it==_geo_types.end()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 1 !"); + if(std::find(it+1,_geo_types.end(),p.getGeo())!=_geo_types.end()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 2 !"); + std::size_t pos(std::distance(_geo_types.begin(),it)); + const DataArrayInt *thisP(_pfls[pos]),*otherP(p.getPfl(globs)); + MEDCouplingAutoRefCountObjectPtr ret(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); + if(!thisP && !otherP) + { + arrSafe[i]=ret; arr[i]=ret; + continue; + } + int nbi(p.getNbOfIntegrationPts(globs)),nc(ret->getNumberOfComponents()); + if(!thisP && otherP) + { + MEDCouplingAutoRefCountObjectPtr p1(otherP->deepCpy()); + p1->sort(true); + if(!p1->isIdentity() || p1->getNumberOfTuples()!=p.getNbEntity()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 3 !"); + ret->rearrange(nbi*nc); ret->renumberInPlace(otherP->begin()); ret->rearrange(nc); + arrSafe[i]=ret; arr[i]=ret; + continue; + } + if(thisP && otherP) + { + MEDCouplingAutoRefCountObjectPtr p1(otherP->deepCpy()); + MEDCouplingAutoRefCountObjectPtr p2(thisP->deepCpy()); + p1->sort(true); p2->sort(true); + if(!p1->isEqualWithoutConsideringStr(*p2)) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 4 !"); + p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,thisP); + ret->rearrange(nbi*nc); ret->renumberInPlace(p1->begin()); ret->rearrange(nc); + continue; + } + if(thisP && !otherP) + { + MEDCouplingAutoRefCountObjectPtr p1(thisP->deepCpy()); + p1->sort(true); + if(!p1->isIdentity() || p1->getNumberOfTuples()!=p.getNbEntity()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 3 !"); + ret->rearrange(nbi*nc); ret->renumberInPlaceR(otherP->begin()); ret->rearrange(nc); + arrSafe[i]=ret; arr[i]=ret; + continue; + } + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 6 !"); + } + return DataArray::Aggregate(arr); } } -bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const char *pflName) const +MEDMeshMultiLev::MEDMeshMultiLev() { - if(startExp!=_start_end.first) - return false; - if(gt!=_geo_type) - return false; - if(getPflName()!=pflName) - return false; - startExp=_start_end.second; - return true; } -bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev::MEDMeshMultiLev(const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):_geo_types(gts),_nb_entities(nbEntities) { - //_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. - return _geo_type==other._geo_type && _start_end==other._start_end && _pfl->getName()==other._pfl->getName(); + std::size_t sz(_geo_types.size()); + if(sz!=pfls.size() || sz!=nbEntities.size()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::MEDMeshMultiLev : input vector must have the same size !"); + _pfls.resize(sz); + for(std::size_t i=0;iincrRef(); + _pfls[i]=const_cast(pfls[i]); + } } -bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev::MEDMeshMultiLev(const MEDMeshMultiLev& other):_pfls(other._pfls),_geo_types(other._geo_types),_nb_entities(other._nb_entities),_node_reduction(other._node_reduction) { - if(_geo_type!=other._geo_type) - return false; - if(_nb_of_entity!=other._nb_of_entity) - return false; - if((_pfl->getName().empty() && !other._pfl->getName().empty()) || (!_pfl->getName().empty() && other._pfl->getName().empty())) - return false; - if(_pfl->getName().empty() && other._pfl->getName().empty()) - return true; - const DataArrayInt *pfl1(getPfl(globs)),*pfl2(other.getPfl(globs)); - return pfl1->isEqualWithoutConsideringStr(*pfl2); } -bool MEDFileField1TSStructItem2::isNodeSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) -{ - return isCellSupportEqual(other,globs); +//= + +MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& levs) throw(INTERP_KERNEL::Exception) +{ + return new MEDUMeshMultiLev(m,levs); } -/*! - * \a objs must be non empty. \a objs should contain items having same geometric type. - */ -MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const std::vector& objs, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& levs) { - if(objs.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : empty input !"); - if(objs.size()==1) - return MEDFileField1TSStructItem2(*objs[0]); - INTERP_KERNEL::NormalizedCellType gt(objs[0]->_geo_type); - int nbEntityRef(objs[0]->_nb_of_entity); - std::size_t sz(objs.size()); - std::vector arrs(sz); - for(std::size_t i=0;i_geo_type) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the same geo type !"); - if(nbEntityRef!=obj->_nb_of_entity) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the global nb of entity !"); - if(obj->_pfl->getName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! Several same geo type chunk must all lie on profiles !"); - arrs[i]=globs->getProfile(obj->_pfl->getName().c_str()); - } - MEDCouplingAutoRefCountObjectPtr arr(DataArrayInt::Aggregate(arrs)); - arr->sort(); - int oldNbTuples(arr->getNumberOfTuples()); - arr=arr->buildUnique(); - if(oldNbTuples!=arr->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : some entities are present several times !"); - if(arr->isIdentity() && oldNbTuples==nbEntityRef) + if(!m) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : null input pointer !"); + std::vector v; + for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) { - std::pair p(0,nbEntityRef); - std::string a,b; - MEDFileField1TSStructItem2 ret(gt,p,a,b); - ret._nb_of_entity=nbEntityRef; - return ret; + std::vector vTmp(m->getDirectUndergroundSingleGeoTypeMeshes(*it)); + v.insert(v.end(),vTmp.begin(),vTmp.end()); } - else + std::size_t sz(v.size()); + _parts.resize(sz); + _pfls.resize(sz); + _geo_types.resize(sz); + for(std::size_t i=0;isetName(NEWLY_CREATED_PFL_NAME); - std::pair p(0,oldNbTuples); - std::string a,b; - MEDFileField1TSStructItem2 ret(gt,p,a,b); - ret._nb_of_entity=nbEntityRef; - ret._pfl=arr; - return ret; + MEDCoupling1GTUMesh *obj(v[i]); + if(obj) + obj->incrRef(); + else + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : presence of a null pointer !"); + _parts[i]=obj; + _geo_types[i]=obj->getCellModelEnum(); } } -std::size_t MEDFileField1TSStructItem2::getHeapMemorySize() const -{ - std::size_t ret(0); - const DataArrayInt *pfl(_pfl); - if(pfl) - ret+=pfl->getHeapMemorySize(); - ret+=_loc.capacity(); - return ret; -} - -//= - -MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b):_computed(false),_type(a),_items(b) +MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception) { + return new MEDUMeshMultiLev(m,gts,pfls,nbEntities); } -void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(gts,pfls,nbEntities) { - switch(_type) + std::size_t sz(gts.size()); + _parts.resize(sz); + for(std::size_t i=0;igetNumberOfNodes(); - if(_items.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : for nodes field only one subdivision supported !"); - _items[0].checkInRange(nbOfEnt,1,globs); - break ; - } - case ON_CELLS: - { - for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) - (*it).checkWithMeshStructForCells(mst,globs); - break; - } - case ON_GAUSS_NE: - { - for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) - (*it).checkWithMeshStructForGaussNE(mst,globs); - break; - } - case ON_GAUSS_PT: - { - for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) - (*it).checkWithMeshStructForGaussPT(mst,globs); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : not managed field type !"); + MEDCoupling1GTUMesh *elt(m->getDirectUndergroundSingleGeoTypeMesh(gts[i])); + if(elt) + elt->incrRef(); + _parts[i]=elt; } } -bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception) +void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) throw(INTERP_KERNEL::Exception) { - if(_type!=other._type) - return false; - if(_items.size()!=other._items.size()) - return false; - for(std::size_t i=0;i<_items.size();i++) - if(!(_items[i]==other._items[i])) - return false; - return true; + 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; + a[i]=m2->getNodeIdsInUse(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(); } -bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exception) { - if(_type!=other._type) - return false; - if(_items.size()!=other._items.size()) - return false; - for(std::size_t i=0;i<_items.size();i++) - if(!(_items[i].isCellSupportEqual(other._items[i],globs))) - return false; - return true; + return new MEDUMeshMultiLev(*this); } -bool MEDFileField1TSStructItem::isNodeSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts) { - if(_type!=other._type) - return false; - if(_items.size()!=other._items.size()) - return false; - for(std::size_t i=0;i<_items.size();i++) - if(!(_items[i].isNodeSupportEqual(other._items[i],globs))) - return false; - return true; } -bool MEDFileField1TSStructItem::isEntityCell() const +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MEDCouplingAutoRefCountObjectPtr& part):MEDMeshMultiLev(other) { - if(_type==ON_NODES) - return false; - else - return true; + _parts.resize(1); + _parts[0]=part; } -class CmpGeo -{ -public: - CmpGeo(INTERP_KERNEL::NormalizedCellType geoTyp):_geo_type(geoTyp) { } - bool operator()(const std::pair< INTERP_KERNEL::NormalizedCellType, std::vector > & v) const { return _geo_type==v.first; } -private: - INTERP_KERNEL::NormalizedCellType _geo_type; -}; - -MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +void MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const throw(INTERP_KERNEL::Exception) { - if(!isEntityCell()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::simplifyMeOnCellEntity : must be on ON_CELLS, ON_GAUSS_NE or ON_GAUSS_PT !"); - std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector > > m; - std::size_t i=0; - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++) + 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()); + if(!tmp) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : the coordinates are null !"); + MEDCouplingAutoRefCountObjectPtr a(const_cast(tmp)); tmp->incrRef(); + int szBCE(0),szD(0),szF(0); + bool isPolyh(false); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_parts.begin();it!=_parts.end();it++) { - std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector > >::iterator it0(std::find_if(m.begin(),m.end(),CmpGeo((*it).getGeo()))); - if(it0==m.end()) - m.push_back(std::pair< INTERP_KERNEL::NormalizedCellType, std::vector >((*it).getGeo(),std::vector(1,i))); + const MEDCoupling1GTUMesh *cur(*it); + if(!cur) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : a part is null !"); + int curNbCells(cur->getNumberOfCells()); + szBCE+=curNbCells; + if((*it)->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + szD=(*it)->getNodalConnectivity()->getNumberOfTuples()+curNbCells; else - (*it0).second.push_back(i); - } - if(m.size()==_items.size()) - { - MEDFileField1TSStructItem ret(*this); - ret._type=ON_CELLS; - return ret; + { + isPolyh=true; + MEDCouplingAutoRefCountObjectPtr tmp((*it)->computeEffectiveNbOfNodesPerCell()); + szD+=tmp->accumulate(0)+curNbCells; + szF+=2*curNbCells+(*it)->getNodalConnectivity()->getNumberOfTuples(); + } } - std::size_t sz(m.size()); - std::vector< MEDFileField1TSStructItem2 > items(sz); - for(i=0;i b(DataArrayByte::New()); b->alloc(szBCE,1); char *bPtr(b->getPointer()); + MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc(szBCE,1); int *cPtr(c->getPointer()); + MEDCouplingAutoRefCountObjectPtr d(DataArrayInt::New()); d->alloc(szD,1); int *dPtr(d->getPointer()); + MEDCouplingAutoRefCountObjectPtr e(DataArrayInt::New()),f(DataArrayInt::New()); int *ePtr(0),*fPtr(0); + if(isPolyh) + { e->alloc(szBCE,1); ePtr=e->getPointer(); f->alloc(szF,1); fPtr=f->getPointer(); } + int k(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_parts.begin();it!=_parts.end();it++) { - const std::vector& ids=m[i].second; - std::vectorobjs(ids.size()); - for(std::size_t j=0;jgetNumberOfCells()); + int gt((int)cur->getCellModelEnum()); + if(gt<0 || gt>=PARAMEDMEM_2_VTKTYPE_LGTH) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : invalid geometric type !"); + unsigned char gtvtk(PARAMEDMEM_2_VTKTYPE[gt]); + if(gtvtk==-1) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : no VTK type for the requested INTERP_KERNEL geometric type !"); + std::fill(bPtr,bPtr+curNbCells,gtvtk); bPtr+=curNbCells; + const MEDCoupling1SGTUMesh *scur(dynamic_cast(cur)); + const MEDCoupling1DGTUMesh *dcur(dynamic_cast(cur)); + const int *connPtr(cur->getNodalConnectivity()->begin()); + if(!scur && !dcur) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : internal error !"); + if(scur) + { + int nnpc(scur->getNumberOfNodesPerCell()); + for(int i=0;igetNodalConnectivityIndex()->begin()); + if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + { + for(int i=0;i s(connPtr+connIPtr[0],connPtr+connIPtr[1]); + *dPtr++=(int)s.size(); + dPtr=std::copy(s.begin(),s.end(),dPtr); + *cPtr=k+(int)s.size(); k=*cPtr++; + } + } + if(isPolyh) + { + connIPtr=dcur->getNodalConnectivityIndex()->begin(); + if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + { std::fill(ePtr,ePtr+curNbCells,-1); ePtr+=curNbCells; } + else + { + int kk(0); + for(int i=0;igetNumberOfTuples()); + std::vector b(sz,false); + const int *work(nodalConnVTK->begin()),*endW(nodalConnVTK->end()); + while(work!=endW) + { + int nb(*work++); + for(int i=0;i=0 && *workgetProfile(otherNodeIt.getPflName().c_str()); - MEDCouplingAutoRefCountObjectPtr cpyPfl(pfl->deepCpy()); - cpyPfl->sort(); - int nbOfNodes(meshSt->getNumberOfNodes()); - if(cpyPfl->isIdentity() && cpyPfl->getNumberOfTuples()==nbOfNodes) - {//on all nodes also ! - if(!ret0) - return false; - return theFirstLevFull==0; + work=polyhedNodalConnVTK->begin(); endW=polyhedNodalConnVTK->end(); + while(work!=endW) + { + int nb(*work++); + for(int i=0;i=0 && *work nodesFetched(nbOfNodes,false); - meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched); - return cpyPfl->isFittingWith(nodesFetched); } -} - -bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const throw(INTERP_KERNEL::Exception) -{ - if(_type!=ON_CELLS) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : works only for ON_CELLS discretization !"); - if(_items.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : items vector is empty !"); - int nbOfLevs(meshSt->getNumberOfLevs()); - if(nbOfLevs==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : no levels in input mesh structure !"); - std::vector levs(nbOfLevs); - theFirstLevFull=1; - int nbOfGT=0; - std::set gts; - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) + int szExp(std::count(b.begin(),b.end(),true)); + if(szExp!=nr->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::reorderNodesIfNecessary : internal error #3 !"); + // Go renumbering ! + MEDCouplingAutoRefCountObjectPtr o2n(DataArrayInt::New()); o2n->alloc(sz,1); + int *o2nPtr(o2n->getPointer()); + int newId(0); + for(int i=0;ibegin()); + MEDCouplingAutoRefCountObjectPtr n2o(o2n->invertArrayO2N2N2O(nr->getNumberOfTuples())); + MEDCouplingAutoRefCountObjectPtr perm(DataArrayInt::FindPermutationFromFirstToSecond(n2o,nr)); + const int *permPtr(perm->begin()); + int *work2(nodalConnVTK->getPointer()),*endW2(nodalConnVTK->getPointer()+nodalConnVTK->getNumberOfTuples()); + while(work2!=endW2) { - if(!(*it).getPflName().empty()) - return false; - INTERP_KERNEL::NormalizedCellType gt((*it).getGeo()); - if(gts.find(gt)!=gts.end()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : internal error !"); - gts.insert(gt); - int pos(meshSt->getLevelOfGeoType((*it).getGeo())); - levs[-pos]++; + int nb(*work2++); + for(int i=0;igetNumberOfGeoTypesInLev(-i)==levs[i]) - { theFirstLevFull=-i; return true; } - return false; + if(polyhedNodalConnVTK) + { + work2=polyhedNodalConnVTK->getPointer(); endW2=polyhedNodalConnVTK->getPointer()+polyhedNodalConnVTK->getNumberOfTuples(); + while(work2!=endW2) + { + int nb(*work2++); + for(int i=0;i coo(coords->selectByTupleIdSafe(nr->begin(),nr->end())); + coords->cpyFrom(*coo); } -const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const throw(INTERP_KERNEL::Exception) +//= + +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev() { - if(i<0 || i>=_items.size()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !"); - return _items[i]; } -std::size_t MEDFileField1TSStructItem::getHeapMemorySize() const +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(gts,pfls,nbEntities) { - std::size_t ret(0); - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) - ret+=(*it).getHeapMemorySize(); - ret+=_items.size()*sizeof(MEDFileField1TSStructItem2); - return ret; } -MEDMeshMultiLev *MEDFileField1TSStructItem::buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) throw(INTERP_KERNEL::Exception) { - std::vector a0; - std::vector a1; - std::vector a2; - std::size_t i(0); - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++) + if(!pflNodes || !pflNodes->isAllocated()) + return ; + std::vector ngs(getNodeGridStructure()); + MEDCouplingAutoRefCountObjectPtr conn(MEDCouplingStructuredMesh::Build1GTNodalConnectivity(&ngs[0],&ngs[0]+ngs.size())); + MEDCouplingAutoRefCountObjectPtr m(MEDCoupling1SGTUMesh::New("",MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(ngs.size()))); + m->setNodalConnectivity(conn); + const DataArrayInt *pfl(_pfls[0]); + if(pfl) { - a0[i]=(*it).getGeo(); - a1[i]=(*it).getPfl(globs); - a2[i]=mst->getNumberOfElemsOfGeoType((*it).getGeo()); + m=dynamic_cast(m->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); } - return MEDMeshMultiLev::New(mst->getTheMesh(),a0,a1,a2); + 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; + _node_reduction=m2->getNodeIdsInUse(tmp); + if(pfl) + _pfls[0]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); + else + _pfls[0]=cellIdsSafe; } -//= - -MEDFileField1TSStruct *MEDFileField1TSStruct::New(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst) throw(INTERP_KERNEL::Exception) +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other) { - return new MEDFileField1TSStruct(ref,mst); } -MEDFileField1TSStruct::MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst) +//= + +MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& levs) throw(INTERP_KERNEL::Exception) { - _already_checked.push_back(BuildItemFrom(ref,mst)); + return new MEDCMeshMultiLev(m,levs); } -void MEDFileField1TSStruct::checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) +MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception) { - if(_already_checked.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::checkWithMeshStruct : not correctly initialized !"); - _already_checked.back().checkWithMeshStruct(mst,globs); + return new MEDCMeshMultiLev(m,gts,pfls,nbEntities); } -bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *mst) const throw(INTERP_KERNEL::Exception) +MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& levs) { - MEDFileField1TSStructItem b(BuildItemFrom(other,mst)); - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) - { - if((*it)==b) - return true; - } - return false; -} - -/*! - * Not const because \a other structure will be added to the \c _already_checked attribute in case of success. - */ -bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception) -{ - if(_already_checked.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : no ref !"); - MEDFileField1TSStructItem b(BuildItemFrom(other,meshSt)); - if(!_already_checked[0].isEntityCell() || !b.isEntityCell()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : only available on cell entities !"); - MEDFileField1TSStructItem other1(b.simplifyMeOnCellEntity(other)); - int found=-1,i=0; - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) - if((*it).isComputed()) - { found=i; break; } - bool ret(false); - if(found==-1) + if(!m) + 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;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; } - else - ret=_already_checked[found].isCellSupportEqual(other1,other); - if(ret) - _already_checked.push_back(b); - return ret; } -bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception) +MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(gts,pfls,nbEntities) { - if(_already_checked.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : no ref !"); - if(!_already_checked[0].isEntityCell()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : only available on cell entities !"); - MEDFileField1TSStructItem other1(BuildItemFrom(other,meshSt)); - // - int found=-1,i=0; - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) - if((*it).isComputed()) - { found=i; break; } - bool ret(false); - if(found==-1) + if(!m) + throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : null input pointer !"); + if(gts.size()!=1 || pfls.size()!=1) + throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !"); + int mdim(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension())); + if(mdim!=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; } - else - ret=_already_checked[found].isCompatibleWithNodesDiscr(other1,meshSt,other); - if(ret) - _already_checked.push_back(other1); - return ret; } -std::size_t MEDFileField1TSStruct::getHeapMemorySize() const +MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDCMeshMultiLev& other):MEDStructuredMeshMultiLev(other) { - std::size_t ret(0); - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) - ret+=(*it).getHeapMemorySize(); - ret+=_already_checked.capacity()*sizeof(MEDFileField1TSStructItem); - return ret; } -MEDFileField1TSStructItem MEDFileField1TSStruct::BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt) +std::vector MEDCMeshMultiLev::getNodeGridStructure() const throw(INTERP_KERNEL::Exception) { - TypeOfField atype; - std::vector< MEDFileField1TSStructItem2 > anItems; - // - 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::size_t nbOfGeoTypes(geoTypes.size()); - if(nbOfGeoTypes==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref !"); - bool isFirst=true; - for(std::size_t i=0;i ret(_coords.size()); + for(std::size_t i=0;i<_coords.size();i++) + ret[i]=_coords[i]->getNumberOfTuples(); return ret; } -MEDMeshMultiLev *MEDFileField1TSStruct::buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exception) { - if(_already_checked.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::buildFromScratchDataSetSupport : No outline structure in this !"); - int pos0(-1),pos1(-1); - if(presenceOfCellDiscr(pos0)) - { - MEDCouplingAutoRefCountObjectPtr ret(_already_checked[pos0].buildFromScratchDataSetSupportOnCells(mst,globs)); - if(presenceOfPartialNodeDiscr(pos1)) - ret->setNodeReduction(_already_checked[pos1][0].getPfl(globs)); - return ret.retn(); - } - else + const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction); + MEDCouplingAutoRefCountObjectPtr nnr; + std::vector cgs,ngs(getNodeGridStructure()); + cgs.resize(ngs.size()); + std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus(),-1)); + if(pfl) { - 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); + std::vector< std::pair > cellParts; + if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) + { + MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); + if(nr) + { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + ret->_nb_entities[0]=pfl->getNumberOfTuples(); + ret->_pfls[0]=0; + std::vector< MEDCouplingAutoRefCountObjectPtr > coords(_coords.size()); + for(std::size_t i=0;i<_coords.size();i++) + coords[i]=_coords[i]->selectByTupleId2(cellParts[i].first,cellParts[i].second+1,1); + ret->_coords=coords; + return ret.retn(); } else - return MEDMeshMultiLev::NewOnlyOnNode(mst->getTheMesh(),_already_checked[pos1][0].getPfl(globs)); - } -} - -bool MEDFileField1TSStruct::isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) -{ - int b0,b1; - bool a0(presenceOfCellDiscr(b0)),a1(presenceOfPartialNodeDiscr(b1)); - int d0,d1; - bool c0(other.presenceOfCellDiscr(d0)),c1(other.presenceOfPartialNodeDiscr(d1)); - if(a0!=c0 || a1!=c1) - return false; - if(a0) - if(!_already_checked[b0].isCellSupportEqual(other._already_checked[d0],globs)) - return false; - if(a1) - if(!_already_checked[b1].isNodeSupportEqual(other._already_checked[d1],globs)) - return false; - return true; -} - -/*! - * 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. - */ -bool MEDFileField1TSStruct::presenceOfCellDiscr(int& pos) const throw(INTERP_KERNEL::Exception) -{ - std::size_t refSz(std::numeric_limits::max()); - bool ret(false); - int i(0); - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) - { - if((*it).getType()!=ON_NODES) { - ret=true; - std::size_t sz((*it).getNumberOfItems()); - if(refSz>sz) - { pos=i; refSz=sz; } + MEDCouplingAutoRefCountObjectPtr m(MEDCouplingCMesh::New()); + for(std::size_t i=0;isetCoordsAt(i,_coords[i]); + MEDCouplingAutoRefCountObjectPtr m2(m->build1SGTUnstructured()); + MEDCouplingAutoRefCountObjectPtr m3=dynamic_cast(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); + MEDCouplingAutoRefCountObjectPtr ret(new MEDUMeshMultiLev(*this,m3)); + if(nr) + { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + return ret.retn(); } } - if(refSz==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfCellDiscr : an element in this on entity CELL is empty !"); - return ret; + else + { + MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); + if(nr) + { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + return ret.retn(); + } } -/*! - * Returns true if presence in \a this of discretization ON_NODES. - * If true is returned the pos of the first element containing the single subpart. - */ -bool MEDFileField1TSStruct::presenceOfPartialNodeDiscr(int& pos) const throw(INTERP_KERNEL::Exception) +std::vector< DataArrayDouble * > MEDCMeshMultiLev::buildVTUArrays() const throw(INTERP_KERNEL::Exception) { - int i(0); - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) + std::size_t sz(_coords.size()); + std::vector< DataArrayDouble * > ret(sz); + for(std::size_t i=0;i((const DataArrayDouble *)_coords[i]); + ret[i]->incrRef(); } - return false; + return ret; } //= -MEDFileFastCellSupportComparator *MEDFileFastCellSupportComparator::New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) throw(INTERP_KERNEL::Exception) +MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector& levs) throw(INTERP_KERNEL::Exception) { - return new MEDFileFastCellSupportComparator(m,ref); + return new MEDCurveLinearMeshMultiLev(m,levs); } -MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) +MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception) { - if(!m) - throw INTERP_KERNEL::Exception("MEDFileFastCellSupportComparator constructor : null input mesh struct !"); - _mesh_comp=const_cast(m); _mesh_comp->incrRef(); - int nbPts=ref->getNumberOfTS(); - _f1ts_cmps.resize(nbPts); - for(int i=0;i elt=ref->getTimeStepAtPos(i); - _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt,_mesh_comp); - _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt); - } + return new MEDCurveLinearMeshMultiLev(m,gts,pfls,nbEntities); } -std::size_t MEDFileFastCellSupportComparator::getHeapMemorySize() const +MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& levs) { - std::size_t ret(0); - const MEDFileMeshStruct *mst(_mesh_comp); - if(mst) - ret+=mst->getHeapMemorySize(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_f1ts_cmps.begin();it!=_f1ts_cmps.end();it++) - { - const MEDFileField1TSStruct *cur(*it); - if(cur) - ret+=cur->getHeapMemorySize()+sizeof(MEDFileField1TSStruct); - } - ret+=_f1ts_cmps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); - return ret; + if(!m) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : null input pointer !"); + if(levs.size()!=1 || levs[0]!=0) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : levels supported is 0 only !"); + 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(); } -bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception) +MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(gts,pfls,nbEntities) { - int nbPts=other->getNumberOfTS(); - if(nbPts!=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isEqual : unexpected nb of time steps in input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;i elt=other->getTimeStepAtPos(i); - if(!_f1ts_cmps[i]->isEqualConsideringThePast(elt,_mesh_comp)) - if(!_f1ts_cmps[i]->isSupportSameAs(elt,_mesh_comp)) - return false; - } - return true; + if(!m) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : null input pointer !"); + if(gts.size()!=1 || pfls.size()!=1) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !"); + int mdim(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension())); + 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(); } -bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception) +MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords),_structure(other._structure) { - int nbPts=other->getNumberOfTS(); - if(nbPts!=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr : unexpected nb of time steps in input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;i elt=other->getTimeStepAtPos(i); - if(!_f1ts_cmps[i]->isCompatibleWithNodesDiscr(elt,_mesh_comp)) - return false; - } - return true; } -MEDMeshMultiLev *MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +std::vector MEDCurveLinearMeshMultiLev::getNodeGridStructure() const throw(INTERP_KERNEL::Exception) { - if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size()) + return _structure; +} + +MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exception) +{ + const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction); + MEDCouplingAutoRefCountObjectPtr nnr; + std::vector cgs,ngs(getNodeGridStructure()); + cgs.resize(ngs.size()); + std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus(),-1)); + if(pfl) { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : requested time step id #" << timeStepId << " is not in [0," << _f1ts_cmps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + std::vector< std::pair > cellParts,nodeParts; + if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) + { + nodeParts=cellParts; + std::vector st(ngs.size()); + for(std::size_t i=0;i p(MEDCouplingStructuredMesh::BuildExplicitIdsFrom(ngs,nodeParts)); + MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); + if(nr) + { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + ret->_nb_entities[0]=pfl->getNumberOfTuples(); + ret->_pfls[0]=0; + ret->_coords=_coords->selectByTupleIdSafe(p->begin(),p->end()); + ret->_structure=st; + return ret.retn(); + } + else + { + MEDCouplingAutoRefCountObjectPtr m(MEDCouplingCurveLinearMesh::New()); + m->setCoords(_coords); m->setNodeGridStructure(&_structure[0],&_structure[0]+_structure.size()); + MEDCouplingAutoRefCountObjectPtr m2(m->build1SGTUnstructured()); + MEDCouplingAutoRefCountObjectPtr m3=dynamic_cast(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); + MEDCouplingAutoRefCountObjectPtr ret(new MEDUMeshMultiLev(*this,m3)); + if(nr) + { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + return ret.retn(); + } } - const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]); - if(!obj) + else { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : at time step id #" << timeStepId << " no field structure overview defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); + if(nr) + { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + return ret.retn(); } - return obj->buildFromScratchDataSetSupport(_mesh_comp,globs); } -bool MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +void MEDCurveLinearMeshMultiLev::buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct) const throw(INTERP_KERNEL::Exception) { - if(timeStepId<=0 || timeStepId>=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne : requested time step id #" << timeStepId << " is not in [1," << _f1ts_cmps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]); - const MEDFileField1TSStruct *objRef(_f1ts_cmps[timeStepId-1]); - return objRef->isDataSetSupportFastlyEqualTo(*obj,globs); + nodeStrct=_structure; + const DataArrayDouble *coo(_coords); + if(!coo) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev::buildVTUArrays : null pointer on coordinates !"); + coords=const_cast(coo); coords->incrRef(); } //= -std::size_t MEDMeshMultiLev::getHeapMemorySize() const +MEDFileField1TSStructItem2::MEDFileField1TSStructItem2() { - return 0; } -MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& levs) throw(INTERP_KERNEL::Exception) +MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair& b, const std::string& c, const std::string& d):_geo_type(a),_start_end(b),_pfl(DataArrayInt::New()),_loc(d),_nb_of_entity(-1) { - if(!m) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : null input pointer !"); - const MEDFileUMesh *um(dynamic_cast(m)); - if(um) - return MEDUMeshMultiLev::New(um,levs); - const MEDFileCMesh *cm(dynamic_cast(m)); - if(cm) - return MEDCMeshMultiLev::New(cm,levs); - const MEDFileCurveLinearMesh *clm(dynamic_cast(m)); - if(clm) - return MEDCurveLinearMeshMultiLev::New(clm,levs); - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !"); + _pfl->setName(c.c_str()); } -MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception) +void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) { - if(!m) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : null input pointer !"); - const MEDFileUMesh *um(dynamic_cast(m)); - if(um) - return MEDUMeshMultiLev::New(um,gts,pfls,nbEntities); - const MEDFileCMesh *cm(dynamic_cast(m)); - if(cm) - return MEDCMeshMultiLev::New(cm,gts,pfls,nbEntities); - const MEDFileCurveLinearMesh *clm(dynamic_cast(m)); - if(clm) - return MEDCurveLinearMeshMultiLev::New(clm,gts,pfls,nbEntities); - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !"); + int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); + checkInRange(nbOfEnt,1,globs); } -MEDMeshMultiLev *MEDMeshMultiLev::NewOnlyOnNode(const MEDFileMesh *m, const DataArrayInt *pflOnNode) throw(INTERP_KERNEL::Exception) +void MEDFileField1TSStructItem2::checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) { - std::vector levs(1,0); - MEDCouplingAutoRefCountObjectPtr ret(MEDMeshMultiLev::New(m,levs)); - ret->selectPartOfNodes(pflOnNode); - return ret.retn(); + int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + checkInRange(nbOfEnt,(int)cm.getNumberOfNodes(),globs); } -void MEDMeshMultiLev::setNodeReduction(const DataArrayInt *nr) +void MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) { - if(nr) - nr->incrRef(); - _node_reduction=const_cast(nr); + if(!globs) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no globals specified !"); + if(_loc.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no localization specified !"); + const MEDFileFieldLoc& loc=globs->getLocalization(_loc.c_str()); + int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); + checkInRange(nbOfEnt,loc.getNumberOfGaussPoints(),globs); } -bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +int MEDFileField1TSStructItem2::getNbOfIntegrationPts(const MEDFileFieldGlobsReal *globs) const { - if(fst.getType()==ON_NODES) + if(_loc.empty()) { - if(fst.getNumberOfItems()!=1) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::isFastlyTheSameStruct : unexpected situation for nodes !"); - const MEDFileField1TSStructItem2& p(fst[0]); - std::string pflName(p.getPflName()); - const DataArrayInt *nr(_node_reduction); - if(pflName.empty() && !nr) - return true; - if(pflName==nr->getName()) - return true; - return false; + if(getPflName().empty()) + return (_start_end.second-_start_end.first)/_nb_of_entity; + else + return (_start_end.second-_start_end.first)/getPfl(globs)->getNumberOfTuples(); } else { - std::size_t sz(fst.getNumberOfItems()); - if(sz!=_geo_types.size()) - return false; - int strt(0); - for(std::size_t i=0;igetLocalization(_loc.c_str())); + return loc.getNumberOfGaussPoints(); } } -DataArray *MEDMeshMultiLev::buildDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const throw(INTERP_KERNEL::Exception) +std::string MEDFileField1TSStructItem2::getPflName() const { - MEDCouplingAutoRefCountObjectPtr ret(const_cast(vals)); ret->incrRef(); - if(isFastlyTheSameStruct(fst,globs)) - return ret.retn(); - else - return constructDataArray(fst,globs,vals); + return _pfl->getName(); } -std::string MEDMeshMultiLev::getPflNameOfId(int id) const +const DataArrayInt *MEDFileField1TSStructItem2::getPfl(const MEDFileFieldGlobsReal *globs) const { - std::size_t sz(_pfls.size()); - if(id<0 || id>=sz) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::getPflNameOfId : invalid input id !"); - const DataArrayInt *pfl(_pfls[id]); - if(!pfl) - return std::string(""); - return pfl->getName(); + if(!_pfl->isAllocated()) + { + if(_pfl->getName().empty()) + return 0; + else + return globs->getProfile(_pfl->getName().c_str()); + } + else + return _pfl; } -DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const throw(INTERP_KERNEL::Exception) +/*! + * \param [in] nbOfEntity - number of entity that can be either cells or nodes. Not other possiblity. + * \param [in] nip - number of integration points. 1 for ON_CELLS and NO_NODES + */ +void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) { - if(fst.getType()==ON_NODES) + _nb_of_entity=nbOfEntity; + if(_pfl->getName().empty()) { - if(fst.getNumberOfItems()!=1) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes !"); - const MEDFileField1TSStructItem2& p(fst[0]); - std::string pflName(p.getPflName()); - const DataArrayInt *nr(_node_reduction); - if(pflName.empty() && !nr) - return vals->deepCpy(); - if(pflName.empty() && nr) - 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 !"); - p1=DataArrayInt::FindPermutationFromFirstToSecond(globs->getProfile(pflName.c_str()),nr); - MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); - ret->renumberInPlace(p1->begin()); - return ret.retn(); - } - if(!pflName.empty() && !nr) - { - MEDCouplingAutoRefCountObjectPtr p1(globs->getProfile(pflName.c_str())->deepCpy()); - p1->sort(true); - if(!p1->isIdentity() || p1->getNumberOfTuples()!=p.getNbEntity()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 4 !"); - MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); - ret->renumberInPlace(globs->getProfile(pflName.c_str())->begin()); - return ret.retn(); - } - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 5 !"); + if(nbOfEntity!=(_start_end.second-_start_end.first)/nip) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Mismatch between number of entities and size of node field !"); + return ; } else { - std::size_t sz(fst.getNumberOfItems()); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrSafe(sz); - std::vector< const DataArray *> arr(sz); - for(std::size_t i=0;i& strtStop(p.getStartStop()); - std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator it(std::find(_geo_types.begin(),_geo_types.end(),p.getGeo())); - if(it==_geo_types.end()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 1 !"); - if(std::find(it+1,_geo_types.end(),p.getGeo())!=_geo_types.end()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 2 !"); - std::size_t pos(std::distance(_geo_types.begin(),it)); - const DataArrayInt *thisP(_pfls[pos]),*otherP(p.getPfl(globs)); - MEDCouplingAutoRefCountObjectPtr ret(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); - if(!thisP && !otherP) - { - arrSafe[i]=ret; arr[i]=ret; - continue; - } - int nbi(p.getNbOfIntegrationPts(globs)),nc(ret->getNumberOfComponents()); - if(!thisP && otherP) - { - MEDCouplingAutoRefCountObjectPtr p1(otherP->deepCpy()); - p1->sort(true); - if(!p1->isIdentity() || p1->getNumberOfTuples()!=p.getNbEntity()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 3 !"); - ret->rearrange(nbi*nc); ret->renumberInPlace(otherP->begin()); ret->rearrange(nc); - arrSafe[i]=ret; arr[i]=ret; - continue; - } - if(thisP && otherP) - { - MEDCouplingAutoRefCountObjectPtr p1(otherP->deepCpy()); - MEDCouplingAutoRefCountObjectPtr p2(thisP->deepCpy()); - p1->sort(true); p2->sort(true); - if(!p1->isEqualWithoutConsideringStr(*p2)) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 4 !"); - p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,thisP); - ret->rearrange(nbi*nc); ret->renumberInPlace(p1->begin()); ret->rearrange(nc); - continue; - } - if(thisP && !otherP) - { - MEDCouplingAutoRefCountObjectPtr p1(thisP->deepCpy()); - p1->sort(true); - if(!p1->isIdentity() || p1->getNumberOfTuples()!=p.getNbEntity()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 3 !"); - ret->rearrange(nbi*nc); ret->renumberInPlaceR(otherP->begin()); ret->rearrange(nc); - arrSafe[i]=ret; arr[i]=ret; - continue; - } - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 6 !"); - } - return DataArray::Aggregate(arr); + if(!globs) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no globals found in file !"); + const DataArrayInt *pfl=globs->getProfile(_pfl->getName().c_str()); + if(!pfl) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no such profile found in file !"); + pfl->checkAllIdsInRange(0,nbOfEntity); } } -MEDMeshMultiLev::MEDMeshMultiLev() +bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const char *pflName) const { + if(startExp!=_start_end.first) + return false; + if(gt!=_geo_type) + return false; + if(getPflName()!=pflName) + return false; + startExp=_start_end.second; + return true; } -MEDMeshMultiLev::MEDMeshMultiLev(const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):_geo_types(gts),_nb_entities(nbEntities) +bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception) { - std::size_t sz(_geo_types.size()); - if(sz!=pfls.size() || sz!=nbEntities.size()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::MEDMeshMultiLev : input vector must have the same size !"); - _pfls.resize(sz); - for(std::size_t i=0;iincrRef(); - _pfls[i]=const_cast(pfls[i]); - } + //_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. + return _geo_type==other._geo_type && _start_end==other._start_end && _pfl->getName()==other._pfl->getName(); } -MEDMeshMultiLev::MEDMeshMultiLev(const MEDMeshMultiLev& other):_pfls(other._pfls),_geo_types(other._geo_types),_nb_entities(other._nb_entities),_node_reduction(other._node_reduction) +bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) { + if(_geo_type!=other._geo_type) + return false; + if(_nb_of_entity!=other._nb_of_entity) + return false; + if((_pfl->getName().empty() && !other._pfl->getName().empty()) || (!_pfl->getName().empty() && other._pfl->getName().empty())) + return false; + if(_pfl->getName().empty() && other._pfl->getName().empty()) + return true; + const DataArrayInt *pfl1(getPfl(globs)),*pfl2(other.getPfl(globs)); + return pfl1->isEqualWithoutConsideringStr(*pfl2); } -//= - -MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& levs) throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem2::isNodeSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) { - return new MEDUMeshMultiLev(m,levs); + return isCellSupportEqual(other,globs); } -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& levs) +/*! + * \a objs must be non empty. \a objs should contain items having same geometric type. + */ +MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const std::vector& objs, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) { - if(!m) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : null input pointer !"); - std::vector v; - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) + if(objs.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : empty input !"); + if(objs.size()==1) + return MEDFileField1TSStructItem2(*objs[0]); + INTERP_KERNEL::NormalizedCellType gt(objs[0]->_geo_type); + int nbEntityRef(objs[0]->_nb_of_entity); + std::size_t sz(objs.size()); + std::vector arrs(sz); + for(std::size_t i=0;i vTmp(m->getDirectUndergroundSingleGeoTypeMeshes(*it)); - v.insert(v.end(),vTmp.begin(),vTmp.end()); + const MEDFileField1TSStructItem2 *obj(objs[i]); + if(gt!=obj->_geo_type) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the same geo type !"); + if(nbEntityRef!=obj->_nb_of_entity) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the global nb of entity !"); + if(obj->_pfl->getName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! Several same geo type chunk must all lie on profiles !"); + arrs[i]=globs->getProfile(obj->_pfl->getName().c_str()); } - std::size_t sz(v.size()); - _parts.resize(sz); - _pfls.resize(sz); - _geo_types.resize(sz); - for(std::size_t i=0;i arr(DataArrayInt::Aggregate(arrs)); + arr->sort(); + int oldNbTuples(arr->getNumberOfTuples()); + arr=arr->buildUnique(); + if(oldNbTuples!=arr->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : some entities are present several times !"); + if(arr->isIdentity() && oldNbTuples==nbEntityRef) { - MEDCoupling1GTUMesh *obj(v[i]); - if(obj) - obj->incrRef(); - else - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : presence of a null pointer !"); - _parts[i]=obj; - _geo_types[i]=obj->getCellModelEnum(); + std::pair p(0,nbEntityRef); + std::string a,b; + MEDFileField1TSStructItem2 ret(gt,p,a,b); + ret._nb_of_entity=nbEntityRef; + return ret; + } + else + { + arr->setName(NEWLY_CREATED_PFL_NAME); + std::pair p(0,oldNbTuples); + std::string a,b; + MEDFileField1TSStructItem2 ret(gt,p,a,b); + ret._nb_of_entity=nbEntityRef; + ret._pfl=arr; + return ret; } } -MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception) +std::size_t MEDFileField1TSStructItem2::getHeapMemorySize() const { - return new MEDUMeshMultiLev(m,gts,pfls,nbEntities); + std::size_t ret(0); + const DataArrayInt *pfl(_pfl); + if(pfl) + ret+=pfl->getHeapMemorySize(); + ret+=_loc.capacity(); + return ret; } -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(gts,pfls,nbEntities) +//= + +MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b):_computed(false),_type(a),_items(b) { - std::size_t sz(gts.size()); - _parts.resize(sz); - for(std::size_t i=0;igetDirectUndergroundSingleGeoTypeMesh(gts[i])); - if(elt) - elt->incrRef(); - _parts[i]=elt; + case ON_NODES: + { + int nbOfEnt=mst->getNumberOfNodes(); + if(_items.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : for nodes field only one subdivision supported !"); + _items[0].checkInRange(nbOfEnt,1,globs); + break ; + } + case ON_CELLS: + { + for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) + (*it).checkWithMeshStructForCells(mst,globs); + break; + } + case ON_GAUSS_NE: + { + for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) + (*it).checkWithMeshStructForGaussNE(mst,globs); + break; + } + case ON_GAUSS_PT: + { + for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) + (*it).checkWithMeshStructForGaussPT(mst,globs); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : not managed field type !"); } } -void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception) { - 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; - a[i]=m2->getNodeIdsInUse(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(_type!=other._type) + return false; + if(_items.size()!=other._items.size()) + return false; + for(std::size_t i=0;i<_items.size();i++) + if(!(_items[i]==other._items[i])) + return false; + return true; } -MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) { - return new MEDUMeshMultiLev(*this); + if(_type!=other._type) + return false; + if(_items.size()!=other._items.size()) + return false; + for(std::size_t i=0;i<_items.size();i++) + if(!(_items[i].isCellSupportEqual(other._items[i],globs))) + return false; + return true; } -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts) +bool MEDFileField1TSStructItem::isNodeSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) { + if(_type!=other._type) + return false; + if(_items.size()!=other._items.size()) + return false; + for(std::size_t i=0;i<_items.size();i++) + if(!(_items[i].isNodeSupportEqual(other._items[i],globs))) + return false; + return true; } -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MEDCouplingAutoRefCountObjectPtr& part):MEDMeshMultiLev(other) +bool MEDFileField1TSStructItem::isEntityCell() const { - _parts.resize(1); - _parts[0]=part; + if(_type==ON_NODES) + return false; + else + return true; } -void MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const throw(INTERP_KERNEL::Exception) +class CmpGeo { - 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()); - if(!tmp) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : the coordinates are null !"); - MEDCouplingAutoRefCountObjectPtr a(const_cast(tmp)); tmp->incrRef(); - int szBCE(0),szD(0),szF(0); - bool isPolyh(false); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_parts.begin();it!=_parts.end();it++) +public: + CmpGeo(INTERP_KERNEL::NormalizedCellType geoTyp):_geo_type(geoTyp) { } + bool operator()(const std::pair< INTERP_KERNEL::NormalizedCellType, std::vector > & v) const { return _geo_type==v.first; } +private: + INTERP_KERNEL::NormalizedCellType _geo_type; +}; + +MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +{ + if(!isEntityCell()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::simplifyMeOnCellEntity : must be on ON_CELLS, ON_GAUSS_NE or ON_GAUSS_PT !"); + std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector > > m; + std::size_t i=0; + for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++) { - const MEDCoupling1GTUMesh *cur(*it); - if(!cur) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : a part is null !"); - int curNbCells(cur->getNumberOfCells()); - szBCE+=curNbCells; - if((*it)->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - szD=(*it)->getNodalConnectivity()->getNumberOfTuples()+curNbCells; + std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector > >::iterator it0(std::find_if(m.begin(),m.end(),CmpGeo((*it).getGeo()))); + if(it0==m.end()) + m.push_back(std::pair< INTERP_KERNEL::NormalizedCellType, std::vector >((*it).getGeo(),std::vector(1,i))); else - { - isPolyh=true; - MEDCouplingAutoRefCountObjectPtr tmp((*it)->computeEffectiveNbOfNodesPerCell()); - szD+=tmp->accumulate(0)+curNbCells; - szF+=2*curNbCells+(*it)->getNodalConnectivity()->getNumberOfTuples(); - } + (*it0).second.push_back(i); } - MEDCouplingAutoRefCountObjectPtr b(DataArrayByte::New()); b->alloc(szBCE,1); char *bPtr(b->getPointer()); - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc(szBCE,1); int *cPtr(c->getPointer()); - MEDCouplingAutoRefCountObjectPtr d(DataArrayInt::New()); d->alloc(szD,1); int *dPtr(d->getPointer()); - MEDCouplingAutoRefCountObjectPtr e(DataArrayInt::New()),f(DataArrayInt::New()); int *ePtr(0),*fPtr(0); - if(isPolyh) - { e->alloc(szBCE,1); ePtr=e->getPointer(); f->alloc(szF,1); fPtr=f->getPointer(); } - int k(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_parts.begin();it!=_parts.end();it++) + if(m.size()==_items.size()) { - const MEDCoupling1GTUMesh *cur(*it); - int curNbCells(cur->getNumberOfCells()); - int gt((int)cur->getCellModelEnum()); - if(gt<0 || gt>=PARAMEDMEM_2_VTKTYPE_LGTH) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : invalid geometric type !"); - unsigned char gtvtk(PARAMEDMEM_2_VTKTYPE[gt]); - if(gtvtk==-1) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : no VTK type for the requested INTERP_KERNEL geometric type !"); - std::fill(bPtr,bPtr+curNbCells,gtvtk); bPtr+=curNbCells; - const MEDCoupling1SGTUMesh *scur(dynamic_cast(cur)); - const MEDCoupling1DGTUMesh *dcur(dynamic_cast(cur)); - const int *connPtr(cur->getNodalConnectivity()->begin()); - if(!scur && !dcur) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : internal error !"); - if(scur) - { - int nnpc(scur->getNumberOfNodesPerCell()); - for(int i=0;igetNodalConnectivityIndex()->begin()); - if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - { - for(int i=0;i s(connPtr+connIPtr[0],connPtr+connIPtr[1]); - *dPtr++=(int)s.size(); - dPtr=std::copy(s.begin(),s.end(),dPtr); - *cPtr=k+(int)s.size(); k=*cPtr++; - } - } - if(isPolyh) - { - connIPtr=dcur->getNodalConnectivityIndex()->begin(); - if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - { std::fill(ePtr,ePtr+curNbCells,-1); ePtr+=curNbCells; } - else - { - int kk(0); - for(int i=0;i items(sz); + for(i=0;i& ids=m[i].second; + std::vectorobjs(ids.size()); + for(std::size_t j=0;jgetProfile(otherNodeIt.getPflName().c_str()); + MEDCouplingAutoRefCountObjectPtr cpyPfl(pfl->deepCpy()); + cpyPfl->sort(); + int nbOfNodes(meshSt->getNumberOfNodes()); + if(cpyPfl->isIdentity() && cpyPfl->getNumberOfTuples()==nbOfNodes) + {//on all nodes also ! + if(!ret0) + return false; + return theFirstLevFull==0; } + std::vector nodesFetched(nbOfNodes,false); + meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched); + return cpyPfl->isFittingWith(nodesFetched); + } +} + +bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const throw(INTERP_KERNEL::Exception) +{ + if(_type!=ON_CELLS) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : works only for ON_CELLS discretization !"); + if(_items.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : items vector is empty !"); + int nbOfLevs(meshSt->getNumberOfLevs()); + if(nbOfLevs==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : no levels in input mesh structure !"); + std::vector levs(nbOfLevs); + theFirstLevFull=1; + int nbOfGT=0; + std::set gts; + for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) + { + if(!(*it).getPflName().empty()) + return false; + INTERP_KERNEL::NormalizedCellType gt((*it).getGeo()); + if(gts.find(gt)!=gts.end()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : internal error !"); + gts.insert(gt); + int pos(meshSt->getLevelOfGeoType((*it).getGeo())); + levs[-pos]++; } - if(!isPolyh) - reorderNodesIfNecessary(a,d,0); - else - reorderNodesIfNecessary(a,d,f); - coords=a.retn(); types=b.retn(); cellLocations=c.retn(); cells=d.retn(); - if(!isPolyh) - { faceLocations=0; faces=0; } - else - { faceLocations=e.retn(); faces=f.retn(); } + for(int i=0;igetNumberOfGeoTypesInLev(-i)==levs[i]) + { theFirstLevFull=-i; return true; } + return false; } -void MEDUMeshMultiLev::reorderNodesIfNecessary(DataArrayDouble *coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const throw(INTERP_KERNEL::Exception) +const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const throw(INTERP_KERNEL::Exception) { - const DataArrayInt *nr(_node_reduction); - if(!nr) - return ; - int sz(coords->getNumberOfTuples()); - std::vector b(sz,false); - const int *work(nodalConnVTK->begin()),*endW(nodalConnVTK->end()); - while(work!=endW) + if(i<0 || i>=_items.size()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !"); + return _items[i]; +} + +std::size_t MEDFileField1TSStructItem::getHeapMemorySize() const +{ + std::size_t ret(0); + for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) + ret+=(*it).getHeapMemorySize(); + ret+=_items.size()*sizeof(MEDFileField1TSStructItem2); + return ret; +} + +MEDMeshMultiLev *MEDFileField1TSStructItem::buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +{ + std::vector a0; + std::vector a1; + std::vector a2; + std::size_t i(0); + for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++) { - int nb(*work++); - for(int i=0;i=0 && *workgetNumberOfElemsOfGeoType((*it).getGeo()); } - if(polyhedNodalConnVTK) + return MEDMeshMultiLev::New(mst->getTheMesh(),a0,a1,a2); +} + +MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt) +{ + TypeOfField atype; + std::vector< MEDFileField1TSStructItem2 > anItems; + // + 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::size_t nbOfGeoTypes(geoTypes.size()); + if(nbOfGeoTypes==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref !"); + bool isFirst=true; + for(std::size_t i=0;ibegin(); endW=polyhedNodalConnVTK->end(); - while(work!=endW) + std::size_t sz=typesF[i].size(); + if(strtEnds[i].size()<1 || sz<1 || pfls[i].size()<1) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : internal error #1 !"); + // + if(isFirst) + atype=typesF[i][0]; + isFirst=false; + // + for(std::size_t j=0;j=0 && *workgetNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::reorderNodesIfNecessary : internal error #3 !"); - // Go renumbering ! - MEDCouplingAutoRefCountObjectPtr o2n(DataArrayInt::New()); o2n->alloc(sz,1); - int *o2nPtr(o2n->getPointer()); - int newId(0); - for(int i=0;i n2o(o2n->invertO2N2N2O(nr->getNumberOfTuples())); - - const int *o2nc(o2n->begin()); - int *work2(nodalConnVTK->getPointer()),*endW2(nodalConnVTK->getPointer()); - MEDCouplingAutoRefCountObjectPtr coo(coords->selectByTupleIdSafe(nr->begin(),nr->end()));*/ + MEDFileField1TSStructItem ret(atype,anItems); + ret.checkWithMeshStruct(meshSt,ref); + return ret; } //= -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev() +MEDFileField1TSStruct *MEDFileField1TSStruct::New(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst) throw(INTERP_KERNEL::Exception) { + return new MEDFileField1TSStruct(ref,mst); } -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(gts,pfls,nbEntities) +MEDFileField1TSStruct::MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst) { + _already_checked.push_back(MEDFileField1TSStructItem::BuildItemFrom(ref,mst)); } -void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) throw(INTERP_KERNEL::Exception) +void MEDFileField1TSStruct::checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception) { - if(!pflNodes || !pflNodes->isAllocated()) - return ; - std::vector ngs(getNodeGridStructure()); - MEDCouplingAutoRefCountObjectPtr conn(MEDCouplingStructuredMesh::Build1GTNodalConnectivity(&ngs[0],&ngs[0]+ngs.size())); - MEDCouplingAutoRefCountObjectPtr m(MEDCoupling1SGTUMesh::New("",MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(ngs.size()))); - m->setNodalConnectivity(conn); - const DataArrayInt *pfl(_pfls[0]); - if(pfl) - { - m=dynamic_cast(m->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; - _node_reduction=m2->getNodeIdsInUse(tmp); - if(pfl) - _pfls[0]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); - else - _pfls[0]=cellIdsSafe; + if(_already_checked.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::checkWithMeshStruct : not correctly initialized !"); + _already_checked.back().checkWithMeshStruct(mst,globs); } -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other) +bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *mst) const throw(INTERP_KERNEL::Exception) { + MEDFileField1TSStructItem b(MEDFileField1TSStructItem::BuildItemFrom(other,mst)); + for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) + { + if((*it)==b) + return true; + } + return false; } -//= - -MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& levs) throw(INTERP_KERNEL::Exception) +/*! + * Not const because \a other structure will be added to the \c _already_checked attribute in case of success. + */ +bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception) { - return new MEDCMeshMultiLev(m,levs); + if(_already_checked.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : no ref !"); + MEDFileField1TSStructItem b(MEDFileField1TSStructItem::BuildItemFrom(other,meshSt)); + if(!_already_checked[0].isEntityCell() || !b.isEntityCell()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : only available on cell entities !"); + MEDFileField1TSStructItem other1(b.simplifyMeOnCellEntity(other)); + int found=-1,i=0; + for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) + if((*it).isComputed()) + { found=i; break; } + bool ret(false); + if(found==-1) + { + MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other)); + ret=this1.isCellSupportEqual(other1,other); + if(ret) + _already_checked.push_back(this1); + } + else + ret=_already_checked[found].isCellSupportEqual(other1,other); + if(ret) + _already_checked.push_back(b); + return ret; } -MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception) +bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception) { - return new MEDCMeshMultiLev(m,gts,pfls,nbEntities); + if(_already_checked.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : no ref !"); + if(!_already_checked[0].isEntityCell()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : only available on cell entities !"); + MEDFileField1TSStructItem other1(MEDFileField1TSStructItem::BuildItemFrom(other,meshSt)); + // + int found=-1,i=0; + for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) + if((*it).isComputed()) + { found=i; break; } + bool ret(false); + if(found==-1) + { + MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other)); + ret=this1.isCompatibleWithNodesDiscr(other1,meshSt,other); + if(ret) + _already_checked.push_back(this1); + } + else + ret=_already_checked[found].isCompatibleWithNodesDiscr(other1,meshSt,other); + if(ret) + _already_checked.push_back(other1); + return ret; } -MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& levs) +std::size_t MEDFileField1TSStruct::getHeapMemorySize() const { - if(!m) - 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;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; - } + std::size_t ret(0); + for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) + ret+=(*it).getHeapMemorySize(); + ret+=_already_checked.capacity()*sizeof(MEDFileField1TSStructItem); + return ret; } -MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(gts,pfls,nbEntities) +MEDMeshMultiLev *MEDFileField1TSStruct::buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) { - if(!m) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : null input pointer !"); - if(gts.size()!=1 || pfls.size()!=1) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !"); - int mdim(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension())); - if(mdim!=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; + MEDCouplingAutoRefCountObjectPtr ret(_already_checked[pos0].buildFromScratchDataSetSupportOnCells(mst,globs)); + if(presenceOfPartialNodeDiscr(pos1)) + ret->setNodeReduction(_already_checked[pos1][0].getPfl(globs)); + return ret.retn(); + } + 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); + } + else + return MEDMeshMultiLev::NewOnlyOnNode(mst->getTheMesh(),_already_checked[pos1][0].getPfl(globs)); } } -MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDCMeshMultiLev& other):MEDStructuredMeshMultiLev(other) +bool MEDFileField1TSStruct::isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) { + int b0,b1; + bool a0(presenceOfCellDiscr(b0)),a1(presenceOfPartialNodeDiscr(b1)); + int d0,d1; + bool c0(other.presenceOfCellDiscr(d0)),c1(other.presenceOfPartialNodeDiscr(d1)); + if(a0!=c0 || a1!=c1) + return false; + if(a0) + if(!_already_checked[b0].isCellSupportEqual(other._already_checked[d0],globs)) + return false; + if(a1) + if(!_already_checked[b1].isNodeSupportEqual(other._already_checked[d1],globs)) + return false; + return true; } -std::vector MEDCMeshMultiLev::getNodeGridStructure() const throw(INTERP_KERNEL::Exception) +/*! + * 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. + */ +bool MEDFileField1TSStruct::presenceOfCellDiscr(int& pos) const throw(INTERP_KERNEL::Exception) { - std::vector ret(_coords.size()); - for(std::size_t i=0;i<_coords.size();i++) - ret[i]=_coords[i]->getNumberOfTuples(); + std::size_t refSz(std::numeric_limits::max()); + bool ret(false); + int i(0); + for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) + { + if((*it).getType()!=ON_NODES) + { + ret=true; + std::size_t sz((*it).getNumberOfItems()); + if(refSz>sz) + { pos=i; refSz=sz; } + } + } + if(refSz==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfCellDiscr : an element in this on entity CELL is empty !"); return ret; } -MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exception) +/*! + * Returns true if presence in \a this of discretization ON_NODES. + * If true is returned the pos of the first element containing the single subpart. + */ +bool MEDFileField1TSStruct::presenceOfPartialNodeDiscr(int& pos) const throw(INTERP_KERNEL::Exception) { - const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction); - MEDCouplingAutoRefCountObjectPtr nnr; - std::vector cgs,ngs(getNodeGridStructure()); - cgs.resize(ngs.size()); - std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus(),-1)); - if(pfl) + int i(0); + for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) { - std::vector< std::pair > cellParts; - if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) - { - MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); - if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - ret->_nb_entities[0]=pfl->getNumberOfTuples(); - ret->_pfls[0]=0; - std::vector< MEDCouplingAutoRefCountObjectPtr > coords(_coords.size()); - for(std::size_t i=0;i<_coords.size();i++) - coords[i]=_coords[i]->selectByTupleId2(cellParts[i].first,cellParts[i].second+1,1); - ret->_coords=coords; - return ret.retn(); - } - else + if((*it).getType()==ON_NODES) { - MEDCouplingAutoRefCountObjectPtr m(MEDCouplingCMesh::New()); - for(std::size_t i=0;isetCoordsAt(i,_coords[i]); - MEDCouplingAutoRefCountObjectPtr m2(m->build1SGTUnstructured()); - MEDCouplingAutoRefCountObjectPtr m3=dynamic_cast(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - MEDCouplingAutoRefCountObjectPtr ret(new MEDUMeshMultiLev(*this,m3)); - if(nr) - { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - return ret.retn(); + std::size_t sz((*it).getNumberOfItems()); + if(sz==1) + { + if(!(*it)[0].getPflName().empty()) + { pos=i; return true; } + } + else + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfPartialNodeDiscr : an element in this on entity NODE is split into several parts !"); } } - else - { - MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); - if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - return ret.retn(); - } + return false; } //= -MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector& levs) throw(INTERP_KERNEL::Exception) -{ - return new MEDCurveLinearMeshMultiLev(m,levs); -} - -MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception) +MEDFileFastCellSupportComparator *MEDFileFastCellSupportComparator::New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) throw(INTERP_KERNEL::Exception) { - return new MEDCurveLinearMeshMultiLev(m,gts,pfls,nbEntities); + return new MEDFileFastCellSupportComparator(m,ref); } -MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& levs) +MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) { if(!m) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : null input pointer !"); - if(levs.size()!=1 || levs[0]!=0) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : levels supported is 0 only !"); - 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(); + throw INTERP_KERNEL::Exception("MEDFileFastCellSupportComparator constructor : null input mesh struct !"); + _mesh_comp=const_cast(m); _mesh_comp->incrRef(); + int nbPts=ref->getNumberOfTS(); + _f1ts_cmps.resize(nbPts); + for(int i=0;i elt=ref->getTimeStepAtPos(i); + _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt,_mesh_comp); + _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt); + } } -MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(gts,pfls,nbEntities) +std::size_t MEDFileFastCellSupportComparator::getHeapMemorySize() const { - if(!m) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : null input pointer !"); - if(gts.size()!=1 || pfls.size()!=1) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !"); - int mdim(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension())); - 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(); + std::size_t ret(0); + const MEDFileMeshStruct *mst(_mesh_comp); + if(mst) + ret+=mst->getHeapMemorySize(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_f1ts_cmps.begin();it!=_f1ts_cmps.end();it++) + { + const MEDFileField1TSStruct *cur(*it); + if(cur) + ret+=cur->getHeapMemorySize()+sizeof(MEDFileField1TSStruct); + } + ret+=_f1ts_cmps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); + return ret; } -MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords),_structure(other._structure) +bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception) { + int nbPts=other->getNumberOfTS(); + if(nbPts!=(int)_f1ts_cmps.size()) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isEqual : unexpected nb of time steps in input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int i=0;i elt=other->getTimeStepAtPos(i); + if(!_f1ts_cmps[i]->isEqualConsideringThePast(elt,_mesh_comp)) + if(!_f1ts_cmps[i]->isSupportSameAs(elt,_mesh_comp)) + return false; + } + return true; } -std::vector MEDCurveLinearMeshMultiLev::getNodeGridStructure() const throw(INTERP_KERNEL::Exception) +bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception) { - return _structure; + int nbPts=other->getNumberOfTS(); + if(nbPts!=(int)_f1ts_cmps.size()) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr : unexpected nb of time steps in input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int i=0;i elt=other->getTimeStepAtPos(i); + if(!_f1ts_cmps[i]->isCompatibleWithNodesDiscr(elt,_mesh_comp)) + return false; + } + return true; } -MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const throw(INTERP_KERNEL::Exception) +MEDMeshMultiLev *MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) { - const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction); - MEDCouplingAutoRefCountObjectPtr nnr; - std::vector cgs,ngs(getNodeGridStructure()); - cgs.resize(ngs.size()); - std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus(),-1)); - if(pfl) + if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size()) { - std::vector< std::pair > cellParts,nodeParts; - if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) - { - nodeParts=cellParts; - std::vector st(ngs.size()); - for(std::size_t i=0;i p(MEDCouplingStructuredMesh::BuildExplicitIdsFrom(ngs,nodeParts)); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); - if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - ret->_nb_entities[0]=pfl->getNumberOfTuples(); - ret->_pfls[0]=0; - ret->_coords=_coords->selectByTupleIdSafe(p->begin(),p->end()); - ret->_structure=st; - return ret.retn(); - } - else - { - MEDCouplingAutoRefCountObjectPtr m(MEDCouplingCurveLinearMesh::New()); - m->setCoords(_coords); m->setNodeGridStructure(&_structure[0],&_structure[0]+_structure.size()); - MEDCouplingAutoRefCountObjectPtr m2(m->build1SGTUnstructured()); - MEDCouplingAutoRefCountObjectPtr m3=dynamic_cast(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - MEDCouplingAutoRefCountObjectPtr ret(new MEDUMeshMultiLev(*this,m3)); - if(nr) - { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - return ret.retn(); - } + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : requested time step id #" << timeStepId << " is not in [0," << _f1ts_cmps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - else + const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]); + if(!obj) { - MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); - if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - return ret.retn(); + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : at time step id #" << timeStepId << " no field structure overview defined !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return obj->buildFromScratchDataSetSupport(_mesh_comp,globs); +} + +bool MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception) +{ + if(timeStepId<=0 || timeStepId>=(int)_f1ts_cmps.size()) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne : requested time step id #" << timeStepId << " is not in [1," << _f1ts_cmps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } + const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]); + const MEDFileField1TSStruct *objRef(_f1ts_cmps[timeStepId-1]); + return objRef->isDataSetSupportFastlyEqualTo(*obj,globs); } diff --git a/src/MEDLoader/MEDFileFieldOverView.hxx b/src/MEDLoader/MEDFileFieldOverView.hxx index 441d45322..1eeedd0c3 100644 --- a/src/MEDLoader/MEDFileFieldOverView.hxx +++ b/src/MEDLoader/MEDFileFieldOverView.hxx @@ -134,6 +134,7 @@ namespace ParaMEDMEM static MEDCMeshMultiLev *New(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) throw(INTERP_KERNEL::Exception); std::vector getNodeGridStructure() const throw(INTERP_KERNEL::Exception); MEDMeshMultiLev *prepare() const throw(INTERP_KERNEL::Exception); + std::vector< DataArrayDouble * > buildVTUArrays() const throw(INTERP_KERNEL::Exception); private: MEDCMeshMultiLev(const MEDCMeshMultiLev& other); MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& levs); @@ -149,6 +150,7 @@ namespace ParaMEDMEM static MEDCurveLinearMeshMultiLev *New(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls , const std::vector& nbEntities) throw(INTERP_KERNEL::Exception); std::vector getNodeGridStructure() const throw(INTERP_KERNEL::Exception); MEDMeshMultiLev *prepare() const throw(INTERP_KERNEL::Exception); + void buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct) const throw(INTERP_KERNEL::Exception); private: MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other); MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& levs); @@ -195,6 +197,7 @@ namespace ParaMEDMEM class MEDFileField1TSStructItem : public RefCountObject { public: + MEDFileField1TSStructItem() { } MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b); void checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) throw(INTERP_KERNEL::Exception); bool operator==(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception); @@ -211,6 +214,7 @@ namespace ParaMEDMEM bool isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception); bool isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const throw(INTERP_KERNEL::Exception); MEDMeshMultiLev *buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception); + static MEDFileField1TSStructItem BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt); private: bool _computed; TypeOfField _type; @@ -228,7 +232,6 @@ namespace ParaMEDMEM bool isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception); MEDMeshMultiLev *buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception); bool isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception); - static MEDFileField1TSStructItem BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt); private: MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst); bool presenceOfCellDiscr(int& pos) const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/MEDLoader/Swig/MEDLoaderCommon.i index c0b36d9bc..864f1307f 100644 --- a/src/MEDLoader/Swig/MEDLoaderCommon.i +++ b/src/MEDLoader/Swig/MEDLoaderCommon.i @@ -32,6 +32,7 @@ #include "MEDFileParameter.hxx" #include "MEDFileData.hxx" #include "MEDFileMeshReadSelector.hxx" +#include "MEDFileFieldOverView.hxx" #include "MEDLoaderTypemaps.i" #include "SauvReader.hxx" #include "SauvWriter.hxx" @@ -63,6 +64,11 @@ using namespace ParaMEDMEM; $result=convertMEDFileField1TS($1,$owner); } +%typemap(out) ParaMEDMEM::MEDMeshMultiLev* +{ + $result=convertMEDMeshMultiLev($1,$owner); +} + %newobject MEDLoader::ReadUMeshFromFamilies; %newobject MEDLoader::ReadUMeshFromGroups; %newobject MEDLoader::ReadUMeshFromFile; @@ -175,6 +181,11 @@ using namespace ParaMEDMEM; %newobject ParaMEDMEM::SauvReader::New; %newobject ParaMEDMEM::SauvReader::loadInMEDFileDS; +%newobject ParaMEDMEM::MEDFileMeshStruct::New; +%newobject ParaMEDMEM::MEDMeshMultiLev::buildDataArray; +%newobject ParaMEDMEM::MEDFileFastCellSupportComparator::New; +%newobject ParaMEDMEM::MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport; + %feature("unref") MEDFileMesh "$this->decrRef();" %feature("unref") MEDFileUMesh "$this->decrRef();" %feature("unref") MEDFileCMesh "$this->decrRef();" @@ -196,6 +207,11 @@ using namespace ParaMEDMEM; %feature("unref") MEDFileData "$this->decrRef();" %feature("unref") SauvReader "$this->decrRef();" %feature("unref") SauvWriter "$this->decrRef();" +%feature("unref") MEDFileFastCellSupportComparator "$this->decrRef();" +%feature("unref") MEDMeshMultiLev "$this->decrRef();" +%feature("unref") MEDUMeshMultiLev "$this->decrRef();" +%feature("unref") MEDCMeshMultiLev "$this->decrRef();" +%feature("unref") MEDCurveLinearMeshMultiLev "$this->decrRef();" class MEDLoader { @@ -2756,5 +2772,112 @@ namespace ParaMEDMEM void setMEDFileDS(const MEDFileData* medData, unsigned meshIndex = 0) throw(INTERP_KERNEL::Exception); void write(const char* fileName) throw(INTERP_KERNEL::Exception); }; + + /////////////// + + class MEDFileMeshStruct; + + class MEDFileField1TSStructItem + { + public: + static MEDFileField1TSStructItem BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt); + }; + + class MEDFileMeshStruct : public RefCountObject + { + public: + static MEDFileMeshStruct *New(const MEDFileMesh *mesh); + private: + ~MEDFileMeshStruct(); + }; + + class MEDMeshMultiLev : public RefCountObject + { + public: + DataArray *buildDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const throw(INTERP_KERNEL::Exception); + private: + ~MEDMeshMultiLev(); + }; + + class MEDUMeshMultiLev : public MEDMeshMultiLev + { + private: + ~MEDUMeshMultiLev(); + public: + %extend + { + PyObject *buildVTUArrays() const throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *coords(0); DataArrayByte *types(0); DataArrayInt *cellLocations(0),*cells(0),*faceLocations(0),*faces(0); + self->buildVTUArrays(coords,types,cellLocations,cells,faceLocations,faces); + PyObject *ret=PyTuple_New(6); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(coords),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(types),SWIGTYPE_p_ParaMEDMEM__DataArrayByte, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(cellLocations),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(cells),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(faceLocations),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,5,SWIG_NewPointerObj(SWIG_as_voidptr(faces),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + } + }; + + class MEDStructuredMeshMultiLev : public MEDMeshMultiLev + { + private: + ~MEDStructuredMeshMultiLev(); + }; + + class MEDCMeshMultiLev : public MEDStructuredMeshMultiLev + { + private: + ~MEDCMeshMultiLev(); + public: + %extend + { + PyObject *buildVTUArrays() const throw(INTERP_KERNEL::Exception) + { + std::vector< DataArrayDouble * > objs(self->buildVTUArrays()); + std::size_t sz(objs.size()); + PyObject *ret=PyList_New(sz); + for(std::size_t i=0;i& nodeStrct) const throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *ret0(0); + std::vector ret1; + self->buildVTUArrays(ret0,ret1); + std::size_t sz(ret1.size()); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyObject *ret1Py=PyList_New(sz); + for(std::size_t i=0;i -static PyObject* convertMEDFileMesh(ParaMEDMEM::MEDFileMesh* mesh, int owner) throw(INTERP_KERNEL::Exception) +static PyObject *convertMEDFileMesh(ParaMEDMEM::MEDFileMesh* mesh, int owner) throw(INTERP_KERNEL::Exception) { PyObject *ret=0; if(!mesh) @@ -39,7 +39,7 @@ static PyObject* convertMEDFileMesh(ParaMEDMEM::MEDFileMesh* mesh, int owner) th return ret; } -static PyObject* convertMEDFileParameter1TS(ParaMEDMEM::MEDFileParameter1TS* p1ts, int owner) throw(INTERP_KERNEL::Exception) +static PyObject *convertMEDFileParameter1TS(ParaMEDMEM::MEDFileParameter1TS* p1ts, int owner) throw(INTERP_KERNEL::Exception) { PyObject *ret=0; if(!p1ts) @@ -56,7 +56,7 @@ static PyObject* convertMEDFileParameter1TS(ParaMEDMEM::MEDFileParameter1TS* p1t return ret; } -static PyObject* convertMEDFileField1TS(ParaMEDMEM::MEDFileAnyTypeField1TS *p, int owner) throw(INTERP_KERNEL::Exception) +static PyObject *convertMEDFileField1TS(ParaMEDMEM::MEDFileAnyTypeField1TS *p, int owner) throw(INTERP_KERNEL::Exception) { PyObject *ret=0; if(!p) @@ -73,7 +73,7 @@ static PyObject* convertMEDFileField1TS(ParaMEDMEM::MEDFileAnyTypeField1TS *p, i return ret; } -static PyObject* convertMEDFileFieldMultiTS(ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *p, int owner) throw(INTERP_KERNEL::Exception) +static PyObject *convertMEDFileFieldMultiTS(ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *p, int owner) throw(INTERP_KERNEL::Exception) { PyObject *ret=0; if(!p) @@ -90,6 +90,25 @@ static PyObject* convertMEDFileFieldMultiTS(ParaMEDMEM::MEDFileAnyTypeFieldMulti return ret; } +static PyObject *convertMEDMeshMultiLev(ParaMEDMEM::MEDMeshMultiLev *p, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!p) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast(p)) + ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDUMeshMultiLev,owner); + if(dynamic_cast(p)) + ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDCMeshMultiLev,owner); + if(dynamic_cast(p)) + ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDStructuredMeshMultiLev,owner); + if(!ret) + throw INTERP_KERNEL::Exception("Not recognized type of MEDMeshMultiLev on downcast !"); + return ret; +} + static std::vector > convertTimePairIdsFromPy(PyObject *pyLi) throw(INTERP_KERNEL::Exception) { std::vector > ret;