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 (CEA/DEN)
21 #include "MEDCouplingIMesh.hxx"
22 #include "MEDCouplingCMesh.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingFieldDouble.hxx"
31 using namespace ParaMEDMEM;
33 MEDCouplingIMesh::MEDCouplingIMesh():_space_dim(-1)
35 _origin[0]=0.; _origin[1]=0.; _origin[2]=0.;
36 _dxyz[0]=0.; _dxyz[1]=0.; _dxyz[2]=0.;
37 _structure[0]=0; _structure[1]=0; _structure[2]=0;
40 MEDCouplingIMesh::MEDCouplingIMesh(const MEDCouplingIMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy),_space_dim(other._space_dim),_axis_unit(other._axis_unit)
42 _origin[0]=other._origin[0]; _origin[1]=other._origin[1]; _origin[2]=other._origin[2];
43 _dxyz[0]=other._dxyz[0]; _dxyz[1]=other._dxyz[1]; _dxyz[2]=other._dxyz[2];
44 _structure[0]=other._structure[0]; _structure[1]=other._structure[1]; _structure[2]=other._structure[2];
47 MEDCouplingIMesh::~MEDCouplingIMesh()
51 MEDCouplingIMesh *MEDCouplingIMesh::New()
53 return new MEDCouplingIMesh;
56 MEDCouplingIMesh *MEDCouplingIMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
57 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop)
59 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(new MEDCouplingIMesh);
60 ret->setName(meshName);
61 ret->setSpaceDimension(spaceDim);
62 ret->setNodeStruct(nodeStrctStart,nodeStrctStop);
63 ret->setOrigin(originStart,originStop);
64 ret->setDXYZ(dxyzStart,dxyzStop);
68 MEDCouplingMesh *MEDCouplingIMesh::deepCpy() const
73 MEDCouplingIMesh *MEDCouplingIMesh::clone(bool recDeepCpy) const
75 return new MEDCouplingIMesh(*this,recDeepCpy);
79 * This method creates a copy of \a this enlarged by \a ghostLev cells on each axis.
80 * If \a ghostLev equal to 0 this method behaves as MEDCouplingIMesh::clone.
82 * \param [in] ghostLev - the ghost level expected
83 * \return MEDCouplingIMesh * - a newly alloacted object to be managed by the caller.
84 * \throw if \a ghostLev < 0.
86 MEDCouplingIMesh *MEDCouplingIMesh::buildWithGhost(int ghostLev) const
89 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::buildWithGhost : the ghostLev must be >= 0 !");
91 int spaceDim(getSpaceDimension());
92 double origin[3],dxyz[3];
94 for(int i=0;i<spaceDim;i++)
96 origin[i]=_origin[i]-ghostLev*_dxyz[i];
98 structure[i]=_structure[i]+2*ghostLev;
100 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),spaceDim,structure,structure+spaceDim,origin,origin+spaceDim,dxyz,dxyz+spaceDim));
101 ret->copyTinyInfoFrom(this);
105 void MEDCouplingIMesh::setNodeStruct(const int *nodeStrctStart, const int *nodeStrctStop)
107 checkSpaceDimension();
108 int sz((int)std::distance(nodeStrctStart,nodeStrctStop));
110 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setNodeStruct : input vector of node structure has not the right size ! Or change space dimension before calling it !");
111 std::copy(nodeStrctStart,nodeStrctStop,_structure);
115 std::vector<int> MEDCouplingIMesh::getNodeStruct() const
117 checkSpaceDimension();
118 return std::vector<int>(_structure,_structure+_space_dim);
121 void MEDCouplingIMesh::setOrigin(const double *originStart, const double *originStop)
123 checkSpaceDimension();
124 int sz((int)std::distance(originStart,originStop));
126 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setOrigin : input vector of origin vector has not the right size ! Or change space dimension before calling it !");
127 std::copy(originStart,originStop,_origin);
131 std::vector<double> MEDCouplingIMesh::getOrigin() const
133 checkSpaceDimension();
134 return std::vector<double>(_origin,_origin+_space_dim);
137 void MEDCouplingIMesh::setDXYZ(const double *dxyzStart, const double *dxyzStop)
139 checkSpaceDimension();
140 int sz((int)std::distance(dxyzStart,dxyzStop));
142 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setDXYZ : input vector of dxyz vector has not the right size ! Or change space dimension before calling it !");
143 std::copy(dxyzStart,dxyzStop,_dxyz);
147 std::vector<double> MEDCouplingIMesh::getDXYZ() const
149 checkSpaceDimension();
150 return std::vector<double>(_dxyz,_dxyz+_space_dim);
153 void MEDCouplingIMesh::setAxisUnit(const std::string& unitName)
159 std::string MEDCouplingIMesh::getAxisUnit() const
165 * This method returns the measure of any cell in \a this.
166 * This specific method of image grid mesh utilizes the fact that any cell in \a this have the same measure.
167 * The value returned by this method is those used to feed the returned field in the MEDCouplingIMesh::getMeasureField.
169 * \sa getMeasureField
171 double MEDCouplingIMesh::getMeasureOfAnyCell() const
174 int dim(getSpaceDimension());
176 for(int i=0;i<dim;i++)
182 * This method is allows to convert \a this into MEDCouplingCMesh instance.
183 * This method is the middle level between MEDCouplingIMesh and the most general MEDCouplingUMesh.
184 * This method is useful for MED writers that do not have still the image grid support.
186 * \sa MEDCouplingMesh::buildUnstructured
188 MEDCouplingCMesh *MEDCouplingIMesh::convertToCartesian() const
191 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> ret(MEDCouplingCMesh::New());
193 { ret->copyTinyInfoFrom(this); }
194 catch(INTERP_KERNEL::Exception& ) { }
195 int spaceDim(getSpaceDimension());
196 std::vector<std::string> infos(buildInfoOnComponents());
197 for(int i=0;i<spaceDim;i++)
199 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(DataArrayDouble::New()); arr->alloc(_structure[i],1); arr->setInfoOnComponent(0,infos[i]);
200 arr->iota(); arr->applyLin(_dxyz[i],_origin[i]);
201 ret->setCoordsAt(i,arr);
207 * This method refines \a this uniformaly along all of its dimensions. In case of success the space covered by \a this will remain
208 * the same before the invocation except that the number of cells will be multiplied by \a factor ^ this->getMeshDimension().
209 * The origin of \a this will be not touched only spacing and node structure will be changed.
210 * This method can be useful for AMR users.
212 void MEDCouplingIMesh::refineWithFactor(const std::vector<int>& factors)
214 if((int)factors.size()!=_space_dim)
215 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::refineWithFactor : refinement factors must have size equal to spaceDim !");
217 std::vector<int> structure(_structure,_structure+3);
218 std::vector<double> dxyz(_dxyz,_dxyz+3);
219 for(int i=0;i<_space_dim;i++)
223 std::ostringstream oss; oss << "MEDCouplingIMesh::refineWithFactor : factor for axis #" << i << " (" << factors[i] << ")is invalid ! Must be > 0 !";
224 throw INTERP_KERNEL::Exception(oss.str().c_str());
226 int factAbs(std::abs(factors[i]));
227 double fact2(1./(double)factors[i]);
228 structure[i]=(_structure[i]-1)*factAbs+1;
229 dxyz[i]=fact2*_dxyz[i];
231 std::copy(structure.begin(),structure.end(),_structure);
232 std::copy(dxyz.begin(),dxyz.end(),_dxyz);
237 * This method returns a newly created mesh containing a single cell in it. This returned cell covers exactly the space covered by \a this.
239 * \return MEDCouplingIMesh * - A newly created object (to be managed by the caller with decrRef) containing simply one cell.
241 * \throw if \a this does not pass the \c checkCoherency test.
243 MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const
246 int spaceDim(getSpaceDimension()),nodeSt[3];
248 for(int i=0;i<spaceDim;i++)
253 dxyz[i]=(_structure[i]-1)*_dxyz[i];
257 nodeSt[i]=_structure[i];
261 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),getSpaceDimension(),nodeSt,nodeSt+spaceDim,_origin,_origin+spaceDim,dxyz,dxyz+spaceDim));
262 ret->copyTinyInfoFrom(this);
267 * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example)
268 * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh
269 * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged.
271 * \param [in] coarseSt The cell structure of coarse mesh.
272 * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh
273 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
274 * \param [in] facts The refinement coefficient per axis.
275 * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
277 * \sa CondenseFineToCoarseGhost,SpreadCoarseToFine
279 void MEDCouplingIMesh::CondenseFineToCoarse(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA)
281 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
282 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : All input vectors (dimension) must have the same size !");
283 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
284 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the parameters 1 or 3 are NULL or not allocated !");
285 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
286 int nbCompo(fineDA->getNumberOfComponents());
287 if(coarseDA->getNumberOfComponents()!=nbCompo)
288 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the number of components of fine DA and coarse one mismatches !");
289 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
290 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
291 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
293 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
294 throw INTERP_KERNEL::Exception(oss.str().c_str());
296 int nbTuplesFine(fineDA->getNumberOfTuples());
297 if(nbOfTuplesInFineExp==0)
302 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Nothing to condense considering the range specified ! But DataArray is not empty !");
304 if(nbTuplesFine%nbOfTuplesInFineExp!=0)
305 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Invalid nb of tuples in fine DataArray regarding its structure !");
306 int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
307 if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
309 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
310 throw INTERP_KERNEL::Exception(oss.str().c_str());
312 // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
313 double *outPtr(coarseDA->getPointer());
314 const double *inPtr(fineDA->begin());
316 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
321 int offset(fineLocInCoarse[0].first),fact0(facts[0]);
322 for(int i=0;i<dims[0];i++)
324 double *loc(outPtr+(offset+i)*nbCompo);
325 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
328 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
330 std::copy(inPtr,inPtr+nbCompo,loc);
337 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact1(facts[1]),fact0(facts[0]);
338 for(int j=0;j<dims[1];j++)
340 for(int jfact=0;jfact<fact1;jfact++)
342 for(int i=0;i<dims[0];i++)
344 double *loc(outPtr+(kk+i)*nbCompo);
345 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
347 if(jfact!=0 || ifact!=0)
348 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
350 std::copy(inPtr,inPtr+nbCompo,loc);
360 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first+coarseSt[0]*coarseSt[1]*fineLocInCoarse[2].first),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]);
361 for(int k=0;k<dims[2];k++)
363 for(int kfact=0;kfact<fact2;kfact++)
365 for(int j=0;j<dims[1];j++)
367 for(int jfact=0;jfact<fact1;jfact++)
369 for(int i=0;i<dims[0];i++)
371 double *loc(outPtr+(kk+i+j*coarseSt[0])*nbCompo);
372 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
374 if(kfact!=0 || jfact!=0 || ifact!=0)
375 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
377 std::copy(inPtr,inPtr+nbCompo,loc);
383 kk+=coarseSt[0]*coarseSt[1];
388 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : only dimensions 1, 2 and 3 supported !");
393 * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example)
394 * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh
395 * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged.
397 * \param [in] coarseSt The cell structure of coarse mesh.
398 * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh
399 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
400 * \param [in] facts The refinement coefficient per axis.
401 * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
402 * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
404 * \sa CondenseFineToCoarse,SpreadCoarseToFineGhost
406 void MEDCouplingIMesh::CondenseFineToCoarseGhost(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA, int ghostSize)
409 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : ghost level has to be >= 0 !");
410 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
411 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : All input vectors (dimension) must have the same size !");
412 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
413 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the parameters 1 or 3 are NULL or not allocated !");
414 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
415 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
416 int nbCompo(fineDA->getNumberOfComponents());
417 if(coarseDA->getNumberOfComponents()!=nbCompo)
418 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the number of components of fine DA and coarse one mismatches !");
419 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
420 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
421 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
423 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples in coarse DataArray having " << coarseDA->getNumberOfTuples() << " !";
424 throw INTERP_KERNEL::Exception(oss.str().c_str());
427 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
428 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
429 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
430 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
431 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
433 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
434 throw INTERP_KERNEL::Exception(oss.str().c_str());
437 double *outPtr(coarseDA->getPointer());
438 const double *inPtr(fineDA->begin());
440 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
445 int offset(fineLocInCoarse[0].first+ghostSize),fact0(facts[0]);
446 inPtr+=ghostSize*nbCompo;
447 for(int i=0;i<dims[0];i++)
449 double *loc(outPtr+(offset+i)*nbCompo);
450 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
453 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
455 std::copy(inPtr,inPtr+nbCompo,loc);
462 int nxwg(coarseSt[0]+2*ghostSize);
463 int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)),fact1(facts[1]),fact0(facts[0]);
464 inPtr+=(dims[0]*fact0+2*ghostSize)*nbCompo;
465 for(int j=0;j<dims[1];j++)
467 for(int jfact=0;jfact<fact1;jfact++)
469 inPtr+=ghostSize*nbCompo;
470 for(int i=0;i<dims[0];i++)
472 double *loc(outPtr+(kk+i)*nbCompo);
473 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
475 if(jfact!=0 || ifact!=0)
476 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
478 std::copy(inPtr,inPtr+nbCompo,loc);
481 inPtr+=ghostSize*nbCompo;
488 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2 supported !");
493 * This method spreads the values of coarse data \a coarseDA into \a fineDA.
495 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
496 * \param [in] coarseSt The cell structure of coarse mesh.
497 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
498 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
499 * \param [in] facts The refinement coefficient per axis.
500 * \sa SpreadCoarseToFineGhost, CondenseFineToCoarse
502 void MEDCouplingIMesh::SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts)
504 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
505 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !");
506 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
507 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !");
508 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
509 int nbCompo(fineDA->getNumberOfComponents());
510 if(coarseDA->getNumberOfComponents()!=nbCompo)
511 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the number of components of fine DA and coarse one mismatches !");
512 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
513 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
514 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
516 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
517 throw INTERP_KERNEL::Exception(oss.str().c_str());
519 int nbTuplesFine(fineDA->getNumberOfTuples());
520 if(nbTuplesFine%nbOfTuplesInFineExp!=0)
521 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : Invalid nb of tuples in fine DataArray regarding its structure !");
522 int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
523 if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
525 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
526 throw INTERP_KERNEL::Exception(oss.str().c_str());
528 // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
529 double *outPtr(fineDA->getPointer());
530 const double *inPtr(coarseDA->begin());
532 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
537 int offset(fineLocInCoarse[0].first),fact0(facts[0]);
538 for(int i=0;i<dims[0];i++)
540 const double *loc(inPtr+(offset+i)*nbCompo);
541 for(int ifact=0;ifact<fact0;ifact++)
542 outPtr=std::copy(loc,loc+nbCompo,outPtr);
548 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact0(facts[0]),fact1(facts[1]);
549 for(int j=0;j<dims[1];j++)
551 for(int jfact=0;jfact<fact1;jfact++)
553 for(int i=0;i<dims[0];i++)
555 const double *loc(inPtr+(kk+i)*nbCompo);
556 for(int ifact=0;ifact<fact0;ifact++)
557 outPtr=std::copy(loc,loc+nbCompo,outPtr);
566 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first+coarseSt[0]*coarseSt[1]*fineLocInCoarse[2].first),fact0(facts[0]),fact1(facts[2]),fact2(facts[2]);
567 for(int k=0;k<dims[2];k++)
569 for(int kfact=0;kfact<fact2;kfact++)
571 for(int j=0;j<dims[1];j++)
573 for(int jfact=0;jfact<fact1;jfact++)
575 for(int i=0;i<dims[0];i++)
577 const double *loc(inPtr+(kk+i+j*coarseSt[0])*nbCompo);
578 for(int ifact=0;ifact<fact0;ifact++)
579 outPtr=std::copy(loc,loc+nbCompo,outPtr);
584 kk+=coarseSt[0]*coarseSt[1];
589 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : only dimensions 1, 2 and 3 supported !");
594 * This method spreads the values of coarse data \a coarseDA into \a fineDA.
596 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
597 * \param [in] coarseSt The cell structure of coarse mesh.
598 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
599 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
600 * \param [in] facts The refinement coefficient per axis.
601 * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
603 * \sa CondenseFineToCoarse, SpreadCoarseToFineGhostZone
605 void MEDCouplingIMesh::SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
608 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level has to be >= 0 !");
609 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
610 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !");
611 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
612 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !");
613 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
614 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
615 int nbCompo(fineDA->getNumberOfComponents());
616 if(coarseDA->getNumberOfComponents()!=nbCompo)
617 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the number of components of fine DA and coarse one mismatches !");
618 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
619 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
620 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
622 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
623 throw INTERP_KERNEL::Exception(oss.str().c_str());
626 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
627 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
628 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
629 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
630 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
632 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
633 throw INTERP_KERNEL::Exception(oss.str().c_str());
636 double *outPtr(fineDA->getPointer());
637 const double *inPtr(coarseDA->begin());
639 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
644 int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
645 for(int i=0;i<ghostSize;i++)
646 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
647 offset=fineLocInCoarse[0].first+ghostSize;
648 for(int i=0;i<dims[0];i++)
650 const double *loc(inPtr+(offset+i)*nbCompo);
651 for(int ifact=0;ifact<fact0;ifact++)
652 outPtr=std::copy(loc,loc+nbCompo,outPtr);
654 offset=fineLocInCoarse[0].second+ghostSize;
655 for(int i=0;i<ghostSize;i++)
656 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
661 int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
662 int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
663 for(int jg=0;jg<ghostSize;jg++)
665 for(int ig=0;ig<ghostSize;ig++)
666 outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
668 for(int ig=0;ig<dims[0];ig++,kk0++)
669 for(int ifact=0;ifact<fact0;ifact++)
670 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
671 for(int ik=0;ik<ghostSize;ik++)
672 outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
674 for(int j=0;j<dims[1];j++)
676 kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
677 for(int jfact=0;jfact<fact1;jfact++)
679 for(int ig=0;ig<ghostSize;ig++)
680 outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
681 int kk0(kk+1);//1 not ghost. We make the hypothesis that factors is >= ghostlev
682 for(int i=0;i<dims[0];i++,kk0++)
684 const double *loc(inPtr+kk0*nbCompo);
685 for(int ifact=0;ifact<fact0;ifact++)
686 outPtr=std::copy(loc,loc+nbCompo,outPtr);
688 for(int ig=0;ig<ghostSize;ig++)
689 outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
692 kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
693 for(int jg=0;jg<ghostSize;jg++)
695 for(int ig=0;ig<ghostSize;ig++)
696 outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
698 for(int ig=0;ig<dims[0];ig++,kk0++)
699 for(int ifact=0;ifact<fact0;ifact++)
700 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
701 for(int ik=0;ik<ghostSize;ik++)
702 outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
707 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : only dimensions 1, 2 supported !");
712 * This method spreads the values of coarse data \a coarseDA into \a fineDA \b ONLY \b in \b the \b ghost \b zone (contrary to SpreadCoarseToFineGhost that spread the values everywhere).
714 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
715 * \param [in] coarseSt The cell structure of coarse mesh.
716 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
717 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
718 * \param [in] facts The refinement coefficient per axis.
719 * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
721 * \sa SpreadCoarseToFineGhost
723 void MEDCouplingIMesh::SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
726 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : ghost level has to be >= 0 !");
727 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
728 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : All input vectors (dimension) must have the same size !");
729 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
730 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the parameters 1 or 3 are NULL or not allocated !");
731 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
732 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
733 int nbCompo(fineDA->getNumberOfComponents());
734 if(coarseDA->getNumberOfComponents()!=nbCompo)
735 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the number of components of fine DA and coarse one mismatches !");
736 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
737 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
738 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
740 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
741 throw INTERP_KERNEL::Exception(oss.str().c_str());
744 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
745 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
746 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
747 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
748 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
750 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
751 throw INTERP_KERNEL::Exception(oss.str().c_str());
754 double *outPtr(fineDA->getPointer());
755 const double *inPtr(coarseDA->begin());
757 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
762 int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
763 for(int i=0;i<ghostSize;i++)
764 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
765 outPtr+=nbCompo*fact0*dims[0];
766 offset=fineLocInCoarse[0].second+ghostSize;
767 for(int i=0;i<ghostSize;i++)
768 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
773 int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
774 int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
775 for(int jg=0;jg<ghostSize;jg++)
777 for(int ig=0;ig<ghostSize;ig++)
778 outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
780 for(int ig=0;ig<dims[0];ig++,kk0++)
781 for(int ifact=0;ifact<fact0;ifact++)
782 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
783 for(int ik=0;ik<ghostSize;ik++)
784 outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
786 for(int j=0;j<dims[1];j++)
788 kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
789 for(int jfact=0;jfact<fact1;jfact++)
791 for(int ig=0;ig<ghostSize;ig++)
792 outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
793 int kk0(kk+1+dims[0]);//1 not ghost. We make the hypothesis that factors is >= ghostlev
794 outPtr+=fact0*nbCompo*dims[0];
795 for(int ig=0;ig<ghostSize;ig++)
796 outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
799 kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
800 for(int jg=0;jg<ghostSize;jg++)
802 for(int ig=0;ig<ghostSize;ig++)
803 outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
805 for(int ig=0;ig<dims[0];ig++,kk0++)
806 for(int ifact=0;ifact<fact0;ifact++)
807 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
808 for(int ik=0;ik<ghostSize;ik++)
809 outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
814 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : only dimensions 1, 2 supported !");
818 void MEDCouplingIMesh::setSpaceDimension(int spaceDim)
820 if(spaceDim==_space_dim)
822 CheckSpaceDimension(spaceDim);
827 void MEDCouplingIMesh::updateTime() const
831 std::size_t MEDCouplingIMesh::getHeapMemorySizeWithoutChildren() const
833 return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
836 std::vector<const BigMemoryObject *> MEDCouplingIMesh::getDirectChildren() const
838 return std::vector<const BigMemoryObject *>();
842 * This method copyies all tiny strings from other (name and components name).
843 * @throw if other and this have not same mesh type.
845 void MEDCouplingIMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
847 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
849 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::copyTinyStringsFrom : meshes have not same type !");
850 MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
854 bool MEDCouplingIMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
857 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::isEqualIfNotWhy : input other pointer is null !");
858 const MEDCouplingIMesh *otherC(dynamic_cast<const MEDCouplingIMesh *>(other));
861 reason="mesh given in input is not castable in MEDCouplingIMesh !";
864 if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
866 if(!isEqualWithoutConsideringStrInternal(otherC,prec,reason))
868 if(_axis_unit!=otherC->_axis_unit)
870 reason="The units of axis are not the same !";
876 bool MEDCouplingIMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
878 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
882 return isEqualWithoutConsideringStrInternal(other,prec,tmp);
885 bool MEDCouplingIMesh::isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const
887 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
890 if(_space_dim!=otherC->_space_dim)
892 std::ostringstream oss;
893 oss << "The spaceDimension of this (" << _space_dim << ") is not equal to those of other (" << otherC->_space_dim << ") !";
896 checkSpaceDimension();
897 for(int i=0;i<_space_dim;i++)
899 if(fabs(_origin[i]-otherC->_origin[i])>prec)
901 std::ostringstream oss;
902 oss << "The origin of this and other differs at " << i << " !";
907 for(int i=0;i<_space_dim;i++)
909 if(fabs(_dxyz[i]-otherC->_dxyz[i])>prec)
911 std::ostringstream oss;
912 oss << "The delta of this and other differs at " << i << " !";
917 for(int i=0;i<_space_dim;i++)
919 if(_structure[i]!=otherC->_structure[i])
921 std::ostringstream oss;
922 oss << "The structure of this and other differs at " << i << " !";
930 void MEDCouplingIMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
931 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
933 if(!isEqualWithoutConsideringStr(other,prec))
934 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalWith : Meshes are not the same !");
938 * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingIMesh instance too).
939 * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingIMesh, \a this and \a other are the same !
941 void MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
942 DataArrayInt *&cellCor) const
944 if(!isEqualWithoutConsideringStr(other,prec))
945 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
948 void MEDCouplingIMesh::checkCoherency() const
950 checkSpaceDimension();
951 for(int i=0;i<_space_dim;i++)
954 std::ostringstream oss; oss << "MEDCouplingIMesh::checkCoherency : On axis " << i << "/" << _space_dim << ", number of nodes is equal to " << _structure[i] << " ! must be >=1 !";
955 throw INTERP_KERNEL::Exception(oss.str().c_str());
959 void MEDCouplingIMesh::checkCoherency1(double eps) const
964 void MEDCouplingIMesh::checkCoherency2(double eps) const
966 checkCoherency1(eps);
969 void MEDCouplingIMesh::getNodeGridStructure(int *res) const
971 checkSpaceDimension();
972 std::copy(_structure,_structure+_space_dim,res);
975 std::vector<int> MEDCouplingIMesh::getNodeGridStructure() const
977 checkSpaceDimension();
978 std::vector<int> ret(_structure,_structure+_space_dim);
982 MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
985 int dim(getSpaceDimension());
986 if(dim!=(int)cellPart.size())
988 std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !";
989 throw INTERP_KERNEL::Exception(oss.str().c_str());
991 double retOrigin[3]={0.,0.,0.};
992 int retStruct[3]={0,0,0};
993 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(dynamic_cast<MEDCouplingIMesh *>(deepCpy()));
994 for(int i=0;i<dim;i++)
996 int startNode(cellPart[i].first),endNode(cellPart[i].second+1);
997 int myDelta(endNode-startNode);
998 if(startNode<0 || startNode>=_structure[i])
1000 std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : At dimension #" << i << " the start node id is " << startNode << " it should be in [0," << _structure[i] << ") !";
1001 throw INTERP_KERNEL::Exception(oss.str().c_str());
1003 if(myDelta<0 || myDelta>_structure[i])
1005 std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : Along dimension #" << i << " the number of nodes is " << _structure[i] << ", and you are requesting for " << myDelta << " nodes wide range !" << std::endl;
1006 throw INTERP_KERNEL::Exception(oss.str().c_str());
1008 retOrigin[i]=_origin[i]+startNode*_dxyz[i];
1009 retStruct[i]=myDelta;
1011 ret->setNodeStruct(retStruct,retStruct+dim);
1012 ret->setOrigin(retOrigin,retOrigin+dim);
1013 ret->checkCoherency();
1018 * Return the space dimension of \a this.
1020 int MEDCouplingIMesh::getSpaceDimension() const
1025 void MEDCouplingIMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
1028 int spaceDim(getSpaceDimension());
1029 getSplitNodeValues(tmp);
1031 GetPosFromId(nodeId,spaceDim,tmp,tmp2);
1032 for(int j=0;j<spaceDim;j++)
1033 coo.push_back(_origin[j]+_dxyz[j]*tmp2[j]);
1036 std::string MEDCouplingIMesh::simpleRepr() const
1038 std::ostringstream ret;
1039 ret << "Image grid with name : \"" << getName() << "\"\n";
1040 ret << "Description of mesh : \"" << getDescription() << "\"\n";
1042 double tt(getTime(tmpp1,tmpp2));
1043 int spaceDim(_space_dim);
1044 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
1045 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
1046 ret << "Space dimension : " << spaceDim << "\n";
1047 if(spaceDim<0 || spaceDim>3)
1049 ret << "The nodal structure is : "; std::copy(_structure,_structure+spaceDim,std::ostream_iterator<int>(ret," ")); ret << "\n";
1050 ret << "The origin position is [" << _axis_unit << "]: ";
1051 std::copy(_origin,_origin+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
1052 ret << "The intervals along axis are : ";
1053 std::copy(_dxyz,_dxyz+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
1057 std::string MEDCouplingIMesh::advancedRepr() const
1059 return simpleRepr();
1062 void MEDCouplingIMesh::getBoundingBox(double *bbox) const
1065 int dim(getSpaceDimension());
1066 for(int idim=0; idim<dim; idim++)
1068 bbox[2*idim]=_origin[idim];
1069 int coeff(_structure[idim]);
1070 if(_structure[idim]<0)
1072 std::ostringstream oss; oss << "MEDCouplingIMesh::getBoundingBox : on axis #" << idim << " number of nodes in structure is < 0 !";
1073 throw INTERP_KERNEL::Exception(oss.str().c_str());
1075 if(_structure[idim]>1)
1076 coeff=_structure[idim]-1;
1077 bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*coeff;
1082 * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
1084 * For 1D cells, the returned field contains lengths.<br>
1085 * For 2D cells, the returned field contains areas.<br>
1086 * For 3D cells, the returned field contains volumes.
1087 * \param [in] isAbs - a not used parameter.
1088 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
1089 * and one time . The caller is to delete this field using decrRef() as it is no
1092 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureField(bool isAbs) const
1095 std::string name="MeasureOfMesh_";
1097 int nbelem(getNumberOfCells());
1098 MEDCouplingFieldDouble *field(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
1099 field->setName(name);
1100 DataArrayDouble* array(DataArrayDouble::New());
1101 array->alloc(nbelem,1);
1102 array->fillWithValue(getMeasureOfAnyCell());
1103 field->setArray(array) ;
1105 field->setMesh(const_cast<MEDCouplingIMesh *>(this));
1106 field->synchronizeTimeWithMesh();
1111 * not implemented yet !
1113 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureFieldOnNode(bool isAbs) const
1115 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::getMeasureFieldOnNode : not implemented yet !");
1119 int MEDCouplingIMesh::getCellContainingPoint(const double *pos, double eps) const
1121 int dim(getSpaceDimension()),ret(0),coeff(1);
1122 for(int i=0;i<dim;i++)
1124 int nbOfCells(_structure[i]-1);
1126 int tmp((int)((ref-_origin[i])/_dxyz[i]));
1127 if(tmp>=0 && tmp<nbOfCells)
1138 void MEDCouplingIMesh::rotate(const double *center, const double *vector, double angle)
1140 throw INTERP_KERNEL::Exception("No rotation available on IMesh : Traduce it to unstructured mesh to apply it !");
1144 * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
1145 * component of the \a vector to all node coordinates of a corresponding axis.
1146 * \param [in] vector - the translation vector whose size must be not less than \a
1147 * this->getSpaceDimension().
1149 void MEDCouplingIMesh::translate(const double *vector)
1151 checkSpaceDimension();
1152 int dim(getSpaceDimension());
1153 std::transform(_origin,_origin+dim,vector,_origin,std::plus<double>());
1158 * Applies scaling transformation to all nodes of \a this mesh.
1159 * \param [in] point - coordinates of a scaling center. This array is to be of
1160 * size \a this->getSpaceDimension() at least.
1161 * \param [in] factor - a scale factor.
1163 void MEDCouplingIMesh::scale(const double *point, double factor)
1165 checkSpaceDimension();
1166 int dim(getSpaceDimension());
1167 std::transform(_origin,_origin+dim,point,_origin,std::minus<double>());
1168 std::transform(_origin,_origin+dim,_origin,std::bind2nd(std::multiplies<double>(),factor));
1169 std::transform(_dxyz,_dxyz+dim,_dxyz,std::bind2nd(std::multiplies<double>(),factor));
1170 std::transform(_origin,_origin+dim,point,_origin,std::plus<double>());
1174 MEDCouplingMesh *MEDCouplingIMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
1176 //not implemented yet !
1181 * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
1182 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1183 * this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
1184 * components. The caller is to delete this array using decrRef() as it is
1187 DataArrayDouble *MEDCouplingIMesh::getCoordinatesAndOwner() const
1190 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1191 int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
1192 ret->alloc(nbNodes,spaceDim);
1193 double *pt(ret->getPointer());
1194 ret->setInfoOnComponents(buildInfoOnComponents());
1196 getSplitNodeValues(tmp);
1197 for(int i=0;i<nbNodes;i++)
1199 GetPosFromId(i,spaceDim,tmp,tmp2);
1200 for(int j=0;j<spaceDim;j++)
1201 pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+_origin[j];
1207 * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
1208 * computed by averaging coordinates of cell nodes.
1209 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1210 * this->getNumberOfCells() tuples per \a this->getSpaceDimension()
1211 * components. The caller is to delete this array using decrRef() as it is
1214 DataArrayDouble *MEDCouplingIMesh::getBarycenterAndOwner() const
1217 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1218 int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()),tmp[3],tmp2[3];
1219 ret->alloc(nbCells,spaceDim);
1220 double *pt(ret->getPointer()),shiftOrigin[3];
1221 std::transform(_dxyz,_dxyz+spaceDim,shiftOrigin,std::bind2nd(std::multiplies<double>(),0.5));
1222 std::transform(_origin,_origin+spaceDim,shiftOrigin,shiftOrigin,std::plus<double>());
1223 getSplitCellValues(tmp);
1224 ret->setInfoOnComponents(buildInfoOnComponents());
1225 for(int i=0;i<nbCells;i++)
1227 GetPosFromId(i,spaceDim,tmp,tmp2);
1228 for(int j=0;j<spaceDim;j++)
1229 pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+shiftOrigin[j];
1234 DataArrayDouble *MEDCouplingIMesh::computeIsoBarycenterOfNodesPerCell() const
1236 return MEDCouplingIMesh::getBarycenterAndOwner();
1239 void MEDCouplingIMesh::renumberCells(const int *old2NewBg, bool check)
1241 throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for IMesh !");
1244 void MEDCouplingIMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1247 double time(getTime(it,order));
1250 littleStrings.clear();
1251 littleStrings.push_back(getName());
1252 littleStrings.push_back(getDescription());
1253 littleStrings.push_back(getTimeUnit());
1254 littleStrings.push_back(getAxisUnit());
1255 tinyInfo.push_back(it);
1256 tinyInfo.push_back(order);
1257 tinyInfo.push_back(_space_dim);
1258 tinyInfo.insert(tinyInfo.end(),_structure,_structure+3);
1259 tinyInfoD.push_back(time);
1260 tinyInfoD.insert(tinyInfoD.end(),_dxyz,_dxyz+3);
1261 tinyInfoD.insert(tinyInfoD.end(),_origin,_origin+3);
1264 void MEDCouplingIMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1270 void MEDCouplingIMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1272 a1=DataArrayInt::New();
1274 a2=DataArrayDouble::New();
1278 void MEDCouplingIMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1279 const std::vector<std::string>& littleStrings)
1281 setName(littleStrings[0]);
1282 setDescription(littleStrings[1]);
1283 setTimeUnit(littleStrings[2]);
1284 setAxisUnit(littleStrings[3]);
1285 setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]);
1286 _space_dim=tinyInfo[2];
1287 _structure[0]=tinyInfo[3]; _structure[1]=tinyInfo[4]; _structure[2]=tinyInfo[5];
1288 _dxyz[0]=tinyInfoD[1]; _dxyz[1]=tinyInfoD[2]; _dxyz[2]=tinyInfoD[3];
1289 _origin[0]=tinyInfoD[4]; _origin[1]=tinyInfoD[5]; _origin[2]=tinyInfoD[6];
1293 void MEDCouplingIMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
1296 std::ostringstream extent,origin,spacing;
1297 for(int i=0;i<3;i++)
1300 { extent << "0 " << _structure[i]-1 << " "; origin << _origin[i] << " "; spacing << _dxyz[i] << " "; }
1302 { extent << "0 0 "; origin << "0 "; spacing << "0 "; }
1304 ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\" Origin=\"" << origin.str() << "\" Spacing=\"" << spacing.str() << "\">\n";
1305 ofs << " <Piece Extent=\"" << extent.str() << "\">\n";
1306 ofs << " <PointData>\n" << pointData << std::endl;
1307 ofs << " </PointData>\n";
1308 ofs << " <CellData>\n" << cellData << std::endl;
1309 ofs << " </CellData>\n";
1310 ofs << " <Coordinates>\n";
1311 ofs << " </Coordinates>\n";
1312 ofs << " </Piece>\n";
1313 ofs << " </" << getVTKDataSetType() << ">\n";
1316 void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const
1318 stream << "MEDCouplingIMesh C++ instance at " << this << ". Name : \"" << getName() << "\". Space dimension : " << _space_dim << ".";
1319 if(_space_dim<0 || _space_dim>3)
1322 std::ostringstream stream0,stream1;
1323 int nbNodes(1),nbCells(0);
1325 for(int i=0;i<_space_dim;i++)
1328 int tmpNodes(_structure[i]);
1329 stream1 << "- Axis " << tmp << " : " << tmpNodes << " nodes (orig=" << _origin[i] << ", inter=" << _dxyz[i] << ").";
1331 stream1 << std::endl;
1337 nbCells=nbCells==0?tmpNodes-1:nbCells*(tmpNodes-1);
1341 stream0 << "Number of cells : " << nbCells << ", Number of nodes : " << nbNodes;
1342 stream << stream0.str();
1344 stream << std::endl;
1346 stream << stream1.str();
1349 std::string MEDCouplingIMesh::getVTKDataSetType() const
1351 return std::string("ImageData");
1354 std::vector<std::string> MEDCouplingIMesh::buildInfoOnComponents() const
1356 checkSpaceDimension();
1357 int dim(getSpaceDimension());
1358 std::vector<std::string> ret(dim);
1359 for(int i=0;i<dim;i++)
1361 std::ostringstream oss;
1362 char tmp('X'+i); oss << tmp;
1363 ret[i]=DataArray::BuildInfoFromVarAndUnit(oss.str(),_axis_unit);
1368 void MEDCouplingIMesh::checkSpaceDimension() const
1370 CheckSpaceDimension(_space_dim);
1373 void MEDCouplingIMesh::CheckSpaceDimension(int spaceDim)
1375 if(spaceDim<0 || spaceDim>3)
1376 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CheckSpaceDimension : input spaceDim must be in [0,1,2,3] !");
1379 int MEDCouplingIMesh::FindIntRoot(int val, int order)
1384 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : input val is < 0 ! Not possible to compute a root !");
1387 if(order!=2 && order!=3)
1388 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the order available are 0,1,2 or 3 !");
1389 double valf((double)val);
1392 double retf(sqrt(valf));
1395 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect square root !");
1400 double retf(std::pow(val,0.3333333333333333));
1401 int ret((int)retf),ret2(ret+1);
1402 if(ret*ret*ret!=val && ret2*ret2*ret2!=val)
1403 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect cublic root !");
1404 if(ret*ret*ret==val)