X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingAMRAttribute.cxx;h=4267ae29fb970c199bd7a431c1c8de90c6d717f1;hb=b7e277ad50223814bc479c5bd64cf12abe8fc959;hp=9e601b98825c7f82d9bd5017fd52759315334cbe;hpb=ee1d91dd1a7a0f9da39125e0be67ff4bbf1d95f4;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingAMRAttribute.cxx b/src/MEDCoupling/MEDCouplingAMRAttribute.cxx index 9e601b988..4267ae29f 100644 --- a/src/MEDCoupling/MEDCouplingAMRAttribute.cxx +++ b/src/MEDCoupling/MEDCouplingAMRAttribute.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -24,15 +24,17 @@ #include "MEDCouplingIMesh.hxx" #include +#include -using namespace ParaMEDMEM; +using namespace MEDCoupling; +/// @cond INTERNAL DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair >& fieldNames) { return new DataArrayDoubleCollection(fieldNames); } -DataArrayDoubleCollection *DataArrayDoubleCollection::deepCpy() const +DataArrayDoubleCollection *DataArrayDoubleCollection::deepCopy() const { return new DataArrayDoubleCollection(*this); } @@ -51,6 +53,21 @@ void DataArrayDoubleCollection::dellocTuples() _arrs[i].first->reAlloc(0); } +void DataArrayDoubleCollection::copyFrom(const DataArrayDoubleCollection& other) +{ + std::size_t sz(_arrs.size()); + if(sz!=other._arrs.size()) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : size are not the same !"); + for(std::size_t i=0;ideepCopyFrom(*otherArr); + } +} + void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector >& compNames) { std::size_t sz(_arrs.size()); @@ -75,6 +92,29 @@ void DataArrayDoubleCollection::spillNatures(const std::vector& n } } +std::vector< std::pair < std::string, std::vector > > DataArrayDoubleCollection::getInfoOnComponents() const +{ + std::size_t sz(_arrs.size()); + std::vector< std::pair < std::string, std::vector > > ret(sz); + for(std::size_t i=0;i >(elt->getName(),elt->getInfoOnComponents()); + } + return ret; +} + +std::vector DataArrayDoubleCollection::getNatures() const +{ + std::size_t sz(_arrs.size()); + std::vector ret(sz); + for(std::size_t i=0;i DataArrayDoubleCollection::retrieveFields() const { std::size_t sz(_arrs.size()); @@ -92,7 +132,7 @@ std::vector DataArrayDoubleCollection::retrieveFields() const const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const { std::vector vec; - for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) + for(std::vector< std::pair< MCAuto, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) { const DataArrayDouble *obj((*it).first); if(obj) @@ -108,6 +148,44 @@ const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::st throw INTERP_KERNEL::Exception(oss.str().c_str()); } +DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) +{ + std::vector vec; + for(std::vector< std::pair< MCAuto, NatureOfField > >::iterator it=_arrs.begin();it!=_arrs.end();it++) + { + DataArrayDouble *obj((*it).first); + if(obj) + { + if(obj->getName()==name) + return obj; + else + vec.push_back(obj->getName()); + } + } + std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName non const : fieldName \"" << name << "\" does not exist in this ! Possibilities are :"; + std::copy(vec.begin(),vec.end(),std::ostream_iterator(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +DataArrayDouble *DataArrayDoubleCollection::at(int pos) +{ + if(pos<0 || pos>=(int)_arrs.size()) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !"); + return _arrs[pos].first; +} + +const DataArrayDouble *DataArrayDoubleCollection::at(int pos) const +{ + if(pos<0 || pos>=(int)_arrs.size()) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !"); + return _arrs[pos].first; +} + +int DataArrayDoubleCollection::size() const +{ + return (int)_arrs.size(); +} + void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse) { if(!fine || !coarse) @@ -174,7 +252,9 @@ void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, for(std::size_t i=0;i_arrs[i].first); - MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first); + DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second); + bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second)); + MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative); } } @@ -216,11 +296,17 @@ DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pai for(std::size_t i=0;i& info(fieldNames[i]); + if(info.second<=0) + { + std::ostringstream oss; oss << "DataArrayDoubleCollection constructor : At pos #" << i << " the array with name \"" << info.first << "\" as a number of components equal to " << info.second; + oss << " It has to be >=1 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } _arrs[i].first=DataArrayDouble::New(); _arrs[i].first->alloc(0,info.second); _arrs[i].first->setName(info.first); names[i]=info.second; - _arrs[i].second=ConservativeVolumic; + _arrs[i].second=IntensiveMaximum; } CheckDiscriminantNames(names); } @@ -233,32 +319,28 @@ DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollec _arrs[i].second=other._arrs[i].second; const DataArrayDouble *da(other._arrs[i].first); if(da) - _arrs[i].first=da->deepCpy(); + _arrs[i].first=da->deepCopy(); } } std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const { std::size_t ret(sizeof(DataArrayDoubleCollection)); - ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); + ret+=_arrs.capacity()*sizeof(MCAuto); return ret; } -std::vector DataArrayDoubleCollection::getDirectChildren() const +std::vector DataArrayDoubleCollection::getDirectChildrenWithNull() const { std::vector ret; - for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) - { - const DataArrayDouble *pt((*it).first); - if(pt) - ret.push_back(pt); - } + for(std::vector< std::pair< MCAuto, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) + ret.push_back((const DataArrayDouble *)(*it).first); return ret; } void DataArrayDoubleCollection::updateTime() const { - for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) + for(std::vector< std::pair< MCAuto, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) { const DataArrayDouble *pt((*it).first); if(pt) @@ -276,7 +358,7 @@ void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) { int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev)); DataArrayDoubleCollection *dadc((*it).second); @@ -318,7 +400,7 @@ void MEDCouplingGridCollection::alloc(int ghostLev) void MEDCouplingGridCollection::dealloc() { - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) { DataArrayDoubleCollection *dadc((*it).second); if(dadc) @@ -330,20 +412,40 @@ void MEDCouplingGridCollection::dealloc() void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector >& compNames) { - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) (*it).second->spillInfoOnComponents(compNames); } void MEDCouplingGridCollection::spillNatures(const std::vector& nfs) { - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) (*it).second->spillNatures(nfs); } +std::vector< std::pair > > MEDCouplingGridCollection::getInfoOnComponents() const +{ + if(_map_of_dadc.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !"); + const DataArrayDoubleCollection *elt(_map_of_dadc[0].second); + if(!elt) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !"); + return elt->getInfoOnComponents(); +} + +std::vector MEDCouplingGridCollection::getNatures() const +{ + if(_map_of_dadc.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !"); + const DataArrayDoubleCollection *elt(_map_of_dadc[0].second); + if(!elt) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !"); + return elt->getNatures(); +} + bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const { int ret(0); - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++) + for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++) { if((*it).first==m) { @@ -361,18 +463,64 @@ const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) return *_map_of_dadc[pos].second; } +DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) +{ + if(pos<0 || pos>(int)_map_of_dadc.size()) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !"); + return *_map_of_dadc[pos].second; +} + +/*! + * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting + * part of fields of \a this. The fields are expected to be the same between \a other and \a this. + * This methods makes the hypothesis that \a this and \a other share two god father that are compatible each other that is to say with the same cell grid structure. + */ +void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other) +{ + for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + { + std::vector deltaThis,deltaOther; + std::vector< std::pair > rgThis((*it).first->positionRelativeToGodFather(deltaThis)); + std::vector thisSt((*it).first->getImageMesh()->getCellGridStructure()); + std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus(),2*ghostLev)); + for(std::vector< std::pair > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++) + { + std::vector< std::pair > rgOther((*it2).first->positionRelativeToGodFather(deltaOther)); + if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther)) + { + std::vector< std::pair > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther)); + std::vector< std::pair > pThis,pOther; + MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true); + MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true); + std::vector otherSt((*it2).first->getImageMesh()->getCellGridStructure()); + MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev); + MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev); + std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus(),2*ghostLev)); + int sz((*it2).second->size()); + for(int i=0;iat(i)); + DataArrayDouble *thisArr((*it).second->at(i)); + MCAuto partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther)); + MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther); + } + } + } + } +} + void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse) { if(!fine || !coarse) throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !"); - const std::vector< std::pair > >& mf(fine->_map_of_dadc); - const std::vector< std::pair > >& mc(coarse->_map_of_dadc); - for(std::vector< std::pair > >::const_iterator it=mf.begin();it!=mf.end();it++) + const std::vector< std::pair > >& mf(fine->_map_of_dadc); + const std::vector< std::pair > >& mc(coarse->_map_of_dadc); + for(std::vector< std::pair > >::const_iterator it=mf.begin();it!=mf.end();it++) { const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); bool found(false); - for(std::vector< std::pair > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) + for(std::vector< std::pair > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) { if((*it0).first==fatherOfFineMesh) { @@ -392,14 +540,14 @@ void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDC { if(!fine || !coarse) throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !"); - const std::vector< std::pair > >& mf(fine->_map_of_dadc); - const std::vector< std::pair > >& mc(coarse->_map_of_dadc); - for(std::vector< std::pair > >::const_iterator it=mf.begin();it!=mf.end();it++) + const std::vector< std::pair > >& mf(fine->_map_of_dadc); + const std::vector< std::pair > >& mc(coarse->_map_of_dadc); + for(std::vector< std::pair > >::const_iterator it=mf.begin();it!=mf.end();it++) { const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); bool found(false); - for(std::vector< std::pair > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) + for(std::vector< std::pair > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) { if((*it0).first==fatherOfFineMesh) { @@ -462,7 +610,7 @@ std::vector< std::pair > ret; std::map > m; - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) { const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); @@ -491,14 +639,14 @@ void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghost { if(!fine || !coarse) throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !"); - const std::vector< std::pair > >& mf(fine->_map_of_dadc); - const std::vector< std::pair > >& mc(coarse->_map_of_dadc); - for(std::vector< std::pair > >::const_iterator it=mf.begin();it!=mf.end();it++) + const std::vector< std::pair > >& mf(fine->_map_of_dadc); + const std::vector< std::pair > >& mc(coarse->_map_of_dadc); + for(std::vector< std::pair > >::const_iterator it=mf.begin();it!=mf.end();it++) { const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); bool found(false); - for(std::vector< std::pair > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) + for(std::vector< std::pair > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) { if((*it0).first==fatherOfFineMesh) { @@ -516,7 +664,7 @@ void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghost void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector& recurseArrs) const { - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) { const MEDCouplingCartesianAMRMeshGen *a((*it).first); if(head==a || head->isObjectInTheProgeny(a)) @@ -548,32 +696,28 @@ MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollec _map_of_dadc[i].first=newGf->getMeshAtPosition(pos); const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second); if(dac) - _map_of_dadc[i].second=dac->deepCpy(); + _map_of_dadc[i].second=dac->deepCopy(); } } std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const { std::size_t ret(sizeof(MEDCouplingGridCollection)); - ret+=_map_of_dadc.capacity()*sizeof(std::pair >); + ret+=_map_of_dadc.capacity()*sizeof(std::pair >); return ret; } -std::vector MEDCouplingGridCollection::getDirectChildren() const +std::vector MEDCouplingGridCollection::getDirectChildrenWithNull() const { std::vector ret; - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - const DataArrayDoubleCollection *col((*it).second); - if(col) - ret.push_back(col); - } + for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + ret.push_back((const DataArrayDoubleCollection *)(*it).second); return ret; } void MEDCouplingGridCollection::updateTime() const { - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) { const MEDCouplingCartesianAMRMeshGen *a((*it).first); if(a) @@ -584,11 +728,18 @@ void MEDCouplingGridCollection::updateTime() const } } +/// @endcond + MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() { return _gf; } +const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const +{ + return _gf; +} + MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf) { if(!gf) @@ -620,7 +771,7 @@ MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataFo { const MEDCouplingCartesianAMRMesh *gf(other._gf); if(gf) - _gf=gf->deepCpy(0); + _gf=gf->deepCopy(0); _tlc.keepTrackOfNewTL(_gf); } } @@ -644,7 +795,7 @@ MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMes fieldNames2[i].second=(int)fieldNames[i].second.size(); compNames[i]=fieldNames[i].second; } - MEDCouplingAutoRefCountObjectPtr ret(New(gf,fieldNames2,ghostLev)); + MCAuto ret(New(gf,fieldNames2,ghostLev)); ret->spillInfoOnComponents(compNames); return ret.retn(); } @@ -658,7 +809,7 @@ MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMes void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector >& compNames) { _tlc.checkConst(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) + for(std::vector< MCAuto >::iterator it=_levs.begin();it!=_levs.end();it++) (*it)->spillInfoOnComponents(compNames); } @@ -669,11 +820,11 @@ void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vect void MEDCouplingAMRAttribute::spillNatures(const std::vector& nfs) { _tlc.checkConst(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) + for(std::vector< MCAuto >::iterator it=_levs.begin();it!=_levs.end();it++) (*it)->spillNatures(nfs); } -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCopy() const { return new MEDCouplingAMRAttribute(*this,true); } @@ -702,7 +853,7 @@ int MEDCouplingAMRAttribute::getNumberOfLevels() const */ std::vector MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) + for(std::vector< MCAuto >::const_iterator it=_levs.begin();it!=_levs.end();it++) { int tmp(-1); if((*it)->presenceOf(mesh,tmp)) @@ -719,7 +870,7 @@ std::vector MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCoup */ const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) + for(std::vector< MCAuto >::const_iterator it=_levs.begin();it!=_levs.end();it++) { int tmp(-1); if((*it)->presenceOf(mesh,tmp)) @@ -728,7 +879,21 @@ const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianA return ddc.getFieldWithName(fieldName); } } - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldOn : the mesh specified is not in the progeny of this !"); + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !"); +} + +DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) +{ + for(std::vector< MCAuto >::iterator it=_levs.begin();it!=_levs.end();it++) + { + int tmp(-1); + if((*it)->presenceOf(mesh,tmp)) + { + DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); + return ddc.getFieldWithName(fieldName); + } + } + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !"); } /*! @@ -741,7 +906,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutO { std::vector recurseArrs; std::size_t lev(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++) + for(std::vector< MCAuto >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++) { int tmp(-1); if((*it)->presenceOf(mesh,tmp)) @@ -771,7 +936,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutO MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const { const DataArrayDouble *arr(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) + for(std::vector< MCAuto >::const_iterator it=_levs.begin();it!=_levs.end();it++) { int tmp(-1); if((*it)->presenceOf(mesh,tmp)) @@ -782,8 +947,8 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCo } if(!arr) throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !"); - MEDCouplingAutoRefCountObjectPtr im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingFieldDouble::New(ON_CELLS)); + MCAuto im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); + MCAuto ret(MEDCouplingFieldDouble::New(ON_CELLS)); ret->setMesh(im); ret->setArray(const_cast(arr)); ret->setName(arr->getName()); @@ -800,9 +965,8 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCo */ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const { - //tony const DataArrayDouble *arr(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) + for(std::vector< MCAuto >::const_iterator it=_levs.begin();it!=_levs.end();it++) { int tmp(-1); if((*it)->presenceOf(mesh,tmp)) @@ -814,9 +978,9 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(ME if(!arr) throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !"); // - MEDCouplingAutoRefCountObjectPtr im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); + MCAuto im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); std::vector cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure()); - MEDCouplingAutoRefCountObjectPtr arr2(DataArrayDouble::New()); + MCAuto arr2(DataArrayDouble::New()); arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents()); std::vector< std::pair > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs)); MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev); @@ -824,13 +988,172 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(ME MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors); arr2->copyStringInfoFrom(*arr); // - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingFieldDouble::New(ON_CELLS)); + MCAuto ret(MEDCouplingFieldDouble::New(ON_CELLS)); ret->setMesh(mesh->getImageMesh()); ret->setArray(arr2); ret->setName(arr->getName()); return ret.retn(); } + +std::string MEDCouplingAMRAttribute::writeVTHB(const std::string& fileName) const +{ + static const char EXT[]=".vthb"; + std::string baseName,extName,zeFileName; + MEDCouplingMesh::SplitExtension(fileName,baseName,extName); + if(extName==EXT) + zeFileName=fileName; + else + { zeFileName=baseName; zeFileName+=EXT; } + // + std::ofstream ofs(fileName.c_str()); + ofs << "\n"; + const MEDCouplingCartesianAMRMesh *gf(getMyGodFather()); + ofs << " getImageMesh()); + std::vector orig(gfm->getOrigin()); + std::vector spacing(gfm->getDXYZ()); + int dim((int)orig.size()); + std::copy(orig.begin(),orig.end(),std::ostream_iterator(ofs," ")); ofs << "\" grid_description=\""; + for(int i=0;i\n"; + // + int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()),kk(0); + for(int i=0;i patches(gf->retrieveGridsAt(i)); + std::size_t sz(patches.size()); + std::vector< MCAuto > patchesSafe(sz); + for(std::size_t j=0;j(ofs," ")); + ofs << "\">\n"; + if(i!=maxLev-1) + { + std::vector factors(patches[0]->getMesh()->getFactors()); + for(int k=0;k::const_iterator it=patches.begin();it!=patches.end();it++,jj++,kk++) + { + ofs << " (*it)); + const MEDCouplingCartesianAMRMeshGen *mesh((*it)->getMesh()); + if(patchCast) + { + const std::vector< std::pair >& bltr(patchCast->getBLTRRangeRelativeToGF()); + for(int pp=0;ppgetMesh()->getImageMesh()); + std::vector cgs(im->getCellGridStructure()); + for(int pp=0;pppresenceOf((*it)->getMesh(),tmp)) + { + const DataArrayDoubleCollection& ddc(_levs[i]->getFieldsAt(tmp)); + std::vector arrs(ddc.retrieveFields()); + std::size_t nbFields(arrs.size()); + std::vector< MCAuto > arrsSafe(nbFields),arrs2Safe(nbFields); + std::vector< const MEDCouplingFieldDouble *> fields(nbFields); + std::vector< MCAuto > fieldsSafe(nbFields); + for(std::size_t pp=0;pp im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); + std::vector cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure()); + arrs2Safe[pp]=DataArrayDouble::New(); + arrs2Safe[pp]->alloc(mesh->getImageMesh()->getNumberOfCells(),arrs[pp]->getNumberOfComponents()); + std::vector< std::pair > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs)); + MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev); + std::vector fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1); + MEDCouplingIMesh::SpreadCoarseToFine(arrs[pp],cgsWG,arrs2Safe[pp],cgs2,fakeFactors); + arrs2Safe[pp]->copyStringInfoFrom(*arrs[pp]); + // + fieldsSafe[pp]=MEDCouplingFieldDouble::New(ON_CELLS); fields[pp]=fieldsSafe[pp]; + fieldsSafe[pp]->setMesh(mesh->getImageMesh()); + fieldsSafe[pp]->setArray(arrs2Safe[pp]); + fieldsSafe[pp]->setName(arrs[pp]->getName()); + } + std::ostringstream vtiFileName; vtiFileName << baseName << "_" << kk << ".vti"; + MEDCouplingFieldDouble::WriteVTK(vtiFileName.str(),fields,true); + // + ofs << vtiFileName.str() << "\">\n"; + ofs << " \n \n"; + } + } + ofs << " \n"; + } + // + ofs << " \n"; + ofs << "\n"; + return zeFileName; +} + + /*! + * This method is useful just after a remesh after a time step computation to project values in \a this to the new + * mesh \a targetGF. + * + * This method performs a projection from \a this to a target AMR mesh \a targetGF. + * This method performs the projection by trying to transfer the finest information to \a targetGF. + * \b WARNING this method does not update the ghost zone, if any. + * The level0 of \a this god father must have the same structure than those of \a targetGF. + * + * This method makes checks that ghost size of \a this and \a targetGF are the same, and that + * the number of levels in \a this and in \a targetGF are also the same. + */ +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const +{ + if(!targetGF) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !"); + if(_levs.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !"); + const MEDCouplingGridCollection *lev0(_levs[0]); + if(!lev0) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !"); + std::vector< std::pair < std::string, std::vector > > fieldNames(lev0->getInfoOnComponents()); + MCAuto ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev)); + ret->spillNatures(lev0->getNatures()); + ret->alloc(); + int nbLevs(getNumberOfLevels()); + if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !"); + // first step copy level0 + if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure()) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !"); + const DataArrayDoubleCollection& col(lev0->getFieldsAt(0)); + DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0)); + colTarget.copyFrom(col); + // then go deeper and deeper + for(int i=1;isynchronizeCoarseToFineByOneLevel(i-1); + MEDCouplingGridCollection *targetCol(ret->_levs[i]); + if(!targetCol) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !"); + const MEDCouplingGridCollection *thisCol(_levs[i]); + if(!thisCol) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !"); + targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol); + } + return ret.retn(); +} + /*! * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using * MEDCouplingAMRAttribute::alloc method. @@ -957,7 +1280,13 @@ void MEDCouplingAMRAttribute::synchronizeAllGhostZones() } /*! - * This method synchronizes all direct children of \a mesh each other. + * This method works \b ONLY \b ON \b DIRECT \b SONS \b OF \a mesh. So only a part of patches at a given level is updated here. + * The ghost zone of all of these sons of \a mesh are updated using the brother patches (the patches sharing the \b SAME \a mesh). + * It is sometimes possible that a ghost zone of some sons of \a mesh are covered by a patch of same level but different father. + * For such cases, the ghost zones are \b NOT updated. If you need a more thorough (but more costly) ghost zone update use synchronizeAllGhostZonesAtASpecifiedLevel method instead. + * + * \param [in] mesh - an element in the progeny of god father in \a this, which the ghost zone of its sons will be updated each other. + * */ void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh) { @@ -979,6 +1308,42 @@ void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const ME curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync); } +/*! + * This method updates \b all the patches at level \a level each other without consideration of their father. + * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf. + */ +void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level) +{ + int maxLev(getNumberOfLevels()); + if(level<0 || level>=maxLev) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !"); + if(level==0) + return ;//at level 0 only one patch -> no need to update + // 1st step - updates all patches pairs at level \a level sharing the same father + const std::vector< std::pair >& items(_neighbors[level]); + const MEDCouplingGridCollection *curLev(_levs[level]); + if(!curLev) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !"); + curLev->synchronizeFineEachOther(_ghost_lev,items); + //2nd step - updates all patches pairs at level \a level not sharing the same father + const std::vector< std::pair >& items2(_cross_lev_neighbors[level]); + curLev->synchronizeFineEachOtherExt(_ghost_lev,items2); +} + +/*! + * This method updates ghost zones of patches at level \a level whatever their father \b using \b father \b patches \b ONLY (at level \b level - 1). + * This method is useful to propagate to the ghost zone of childhood the modification. + */ +void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level) +{ + int maxLev(getNumberOfLevels()); + if(level<=0 || level>=maxLev) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !"); + const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]); + MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine); + //_cross_lev_neighbors is not needed. +} + /*! * This method allocates all DataArrayDouble instances stored recursively in \a this. * @@ -987,7 +1352,7 @@ void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const ME void MEDCouplingAMRAttribute::alloc() { _tlc.resetState(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) + for(std::vector< MCAuto >::iterator it=_levs.begin();it!=_levs.end();it++) { MEDCouplingGridCollection *elt(*it); if(elt) @@ -1004,7 +1369,7 @@ void MEDCouplingAMRAttribute::alloc() void MEDCouplingAMRAttribute::dealloc() { _tlc.checkConst(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) + for(std::vector< MCAuto >::iterator it=_levs.begin();it!=_levs.end();it++) { MEDCouplingGridCollection *elt(*it); if(elt) @@ -1023,19 +1388,15 @@ bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf) std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const { std::size_t ret(sizeof(MEDCouplingAMRAttribute)); - ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); + ret+=_levs.capacity()*sizeof(MCAuto); return ret; } -std::vector MEDCouplingAMRAttribute::getDirectChildren() const +std::vector MEDCouplingAMRAttribute::getDirectChildrenWithNull() const { std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - { - const MEDCouplingGridCollection *elt(*it); - if(elt) - ret.push_back(elt); - } + for(std::vector< MCAuto >::const_iterator it=_levs.begin();it!=_levs.end();it++) + ret.push_back((const MEDCouplingGridCollection *)*it); return ret; } @@ -1052,7 +1413,7 @@ MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf { std::vector patches(gf->retrieveGridsAt(i)); std::size_t sz(patches.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > patchesSafe(patches.size()); + std::vector< MCAuto > patchesSafe(patches.size()); for(std::size_t j=0;j ms(sz); @@ -1099,7 +1460,7 @@ MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& const MEDCouplingGridCollection *elt(other._levs[i]); if(elt) { - _levs[i]=other._levs[i]->deepCpy(_gf,other._gf); + _levs[i]=other._levs[i]->deepCopy(_gf,other._gf); } } //_cross_lev_neighbors(other._cross_lev_neighbors) @@ -1145,7 +1506,7 @@ MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) + for(std::vector< MCAuto >::const_iterator it=_levs.begin();it!=_levs.end();it++) { const MEDCouplingGridCollection *elt(*it); if(elt)