1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay
21 #include "MEDCouplingCartesianAMRMesh.hxx"
22 #include "MEDCouplingIMesh.hxx"
23 #include "MEDCouplingUMesh.hxx"
28 using namespace ParaMEDMEM;
33 * \param [in] mesh not null pointer of refined mesh replacing the cell range of \a father defined by the bottom left and top right just after.
34 * \param [in] bottomLeftTopRight a vector equal to the space dimension of \a mesh that specifies for each dimension, the included cell start of the range for the first element of the pair,
35 * a the end cell (\b excluded) of the range for the second element of the pair.
37 MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMesh *mesh, const std::vector< std::pair<int,int> >& bottomLeftTopRight)
40 throw INTERP_KERNEL::Exception("EDCouplingCartesianAMRPatch constructor : input mesh is NULL !");
41 _mesh=mesh; _mesh->incrRef();
42 int dim((int)bottomLeftTopRight.size());
43 if(dim!=_mesh->getSpaceDimension())
44 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch constructor : space dimension of father and input bottomLeft/topRight size mismatches !");
45 _bl_tr=bottomLeftTopRight;
48 int MEDCouplingCartesianAMRPatch::getNumberOfCellsRecursiveWithOverlap() const
50 return _mesh->getNumberOfCellsRecursiveWithOverlap();
53 int MEDCouplingCartesianAMRPatch::getNumberOfCellsRecursiveWithoutOverlap() const
55 return _mesh->getNumberOfCellsRecursiveWithoutOverlap();
58 int MEDCouplingCartesianAMRPatch::getMaxNumberOfLevelsRelativeToThis() const
60 return _mesh->getMaxNumberOfLevelsRelativeToThis();
63 void MEDCouplingCartesianAMRPatch::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, int factor)
65 return _mesh->addPatch(bottomLeftTopRight,factor);
68 int MEDCouplingCartesianAMRPatch::getNumberOfOverlapedCellsForFather() const
70 return MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(_bl_tr);
73 std::size_t MEDCouplingCartesianAMRPatch::getHeapMemorySizeWithoutChildren() const
75 std::size_t ret(sizeof(MEDCouplingCartesianAMRPatch));
76 ret+=_bl_tr.capacity()*sizeof(std::pair<int,int>);
80 std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRPatch::getDirectChildren() const
82 std::vector<const BigMemoryObject *> ret;
83 if((const MEDCouplingCartesianAMRMesh *)_mesh)
84 ret.push_back((const MEDCouplingCartesianAMRMesh *)_mesh);
91 MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
92 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop)
94 return new MEDCouplingCartesianAMRMesh(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop);
97 int MEDCouplingCartesianAMRMesh::getSpaceDimension() const
99 return _mesh->getSpaceDimension();
102 int MEDCouplingCartesianAMRMesh::getMaxNumberOfLevelsRelativeToThis() const
105 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
106 ret=std::max(ret,(*it)->getMaxNumberOfLevelsRelativeToThis()+1);
110 int MEDCouplingCartesianAMRMesh::getNumberOfCellsAtCurrentLevel() const
112 return _mesh->getNumberOfCells();
115 int MEDCouplingCartesianAMRMesh::getNumberOfCellsRecursiveWithOverlap() const
117 int ret(_mesh->getNumberOfCells());
118 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
120 ret+=(*it)->getNumberOfCellsRecursiveWithOverlap();
125 int MEDCouplingCartesianAMRMesh::getNumberOfCellsRecursiveWithoutOverlap() const
127 int ret(_mesh->getNumberOfCells());
128 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
130 ret-=(*it)->getNumberOfOverlapedCellsForFather();
131 ret+=(*it)->getNumberOfCellsRecursiveWithoutOverlap();
136 const MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::getFather() const
141 const MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::getGodFather() const
146 return _father->getGodFather();
149 void MEDCouplingCartesianAMRMesh::detachFromFather()
155 * \param [in] bottomLeftTopRight a vector equal to the space dimension of \a mesh that specifies for each dimension, the included cell start of the range for the first element of the pair,
156 * a the end cell (\b excluded) of the range for the second element of the pair.
157 * \param [in] factor The != 0 factor of refinement.
159 void MEDCouplingCartesianAMRMesh::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, int factor)
161 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> mesh(static_cast<MEDCouplingIMesh *>(_mesh->buildStructuredSubPart(bottomLeftTopRight)));
162 mesh->refineWithFactor(factor);
163 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRMesh> zeMesh(new MEDCouplingCartesianAMRMesh(this,mesh));
164 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> elt(new MEDCouplingCartesianAMRPatch(zeMesh,bottomLeftTopRight));
165 _patches.push_back(elt);
168 void MEDCouplingCartesianAMRMesh::removePatch(int patchId)
170 checkPatchId(patchId);
171 int sz((int)_patches.size()),j(0);
172 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> > patches(sz-1);
173 for(int i=0;i<sz;i++)
175 patches[j++]=_patches[i];
176 (const_cast<MEDCouplingCartesianAMRMesh *>(_patches[patchId]->getMesh()))->detachFromFather();
181 int MEDCouplingCartesianAMRMesh::getNumberOfPatches() const
183 return (int)_patches.size();
186 const MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRMesh::getPatch(int patchId) const
188 checkPatchId(patchId);
189 return _patches[patchId];
192 MEDCouplingUMesh *MEDCouplingCartesianAMRMesh::buildUnstructured() const
194 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> part(_mesh->buildUnstructured());
195 std::vector<bool> bs(_mesh->getNumberOfCells(),false);
196 std::vector<int> cgs(_mesh->getCellGridStructure());
197 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > msSafe(_patches.size()+1);
199 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++)
201 MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs);
202 msSafe[ii+1]=(*it)->getMesh()->buildUnstructured();
204 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs));
205 msSafe[0]=static_cast<MEDCouplingUMesh *>(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false));
206 std::vector< const MEDCouplingUMesh * > ms(msSafe.size());
207 for(std::size_t i=0;i<msSafe.size();i++)
209 return MEDCouplingUMesh::MergeUMeshes(ms);
212 MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
213 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop):_father(0)
215 _mesh=MEDCouplingIMesh::New(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop);
218 MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(MEDCouplingCartesianAMRMesh *father, MEDCouplingIMesh *mesh):_father(father)
221 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh(MEDCouplingIMesh *mesh) constructor : empty father !");
223 throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh(MEDCouplingIMesh *mesh) constructor : The input mesh is null !");
224 mesh->checkCoherency();
225 _mesh=mesh; _mesh->incrRef();
228 void MEDCouplingCartesianAMRMesh::checkPatchId(int patchId) const
230 int sz(getNumberOfPatches());
231 if(patchId<0 || patchId>=sz)
233 std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::checkPatchId : invalid patchId (" << patchId << ") ! Must be in [0," << sz << ") !";
234 throw INTERP_KERNEL::Exception(oss.str().c_str());
238 std::size_t MEDCouplingCartesianAMRMesh::getHeapMemorySizeWithoutChildren() const
240 return sizeof(MEDCouplingCartesianAMRMesh);
243 std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRMesh::getDirectChildren() const
245 std::vector<const BigMemoryObject *> ret;
246 if((const MEDCouplingIMesh *)_mesh)
247 ret.push_back((const MEDCouplingIMesh *)_mesh);
248 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
250 if((const MEDCouplingCartesianAMRPatch*)*it)
251 ret.push_back((const MEDCouplingCartesianAMRPatch*)*it);
256 void MEDCouplingCartesianAMRMesh::updateTime() const
258 if((const MEDCouplingIMesh *)_mesh)
259 updateTimeWith(*_mesh);
260 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
262 const MEDCouplingCartesianAMRPatch *elt(*it);
265 const MEDCouplingCartesianAMRMesh *mesh(elt->getMesh());
267 updateTimeWith(*mesh);