1 // Copyright (C) 2007-2016 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 MEDCoupling;
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 MCAuto<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 MEDCouplingIMesh *MEDCouplingIMesh::deepCopy() 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 !");
90 checkConsistencyLight();
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 MCAuto<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
173 checkConsistencyLight();
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
190 checkConsistencyLight();
191 MCAuto<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 MCAuto<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 !");
216 checkConsistencyLight();
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 checkConsistencyLight test.
243 MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const
245 checkConsistencyLight();
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 MCAuto<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)*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;
489 int nxwg(coarseSt[0]+2*ghostSize),nxywg((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize));
490 int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)+nxywg*(fineLocInCoarse[2].first+ghostSize)),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]);
491 inPtr+=(dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)*ghostSize*nbCompo;
492 for(int k=0;k<dims[2];k++)
494 for(int kfact=0;kfact<fact2;kfact++)
496 inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo;
497 for(int j=0;j<dims[1];j++)
500 for(int jfact=0;jfact<fact1;jfact++)
502 inPtr+=ghostSize*nbCompo;
503 for(int i=0;i<dims[0];i++)
505 double *loc(outPtr+(kky+kk+i)*nbCompo);
506 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
508 if(kfact!=0 || jfact!=0 || ifact!=0)
509 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
511 std::copy(inPtr,inPtr+nbCompo,loc);
514 inPtr+=ghostSize*nbCompo;
517 inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo;
524 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2, 3 supported !");
529 * This method spreads the values of coarse data \a coarseDA into \a fineDA.
531 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
532 * \param [in] coarseSt The cell structure of coarse mesh.
533 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
534 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
535 * \param [in] facts The refinement coefficient per axis.
536 * \sa SpreadCoarseToFineGhost, CondenseFineToCoarse
538 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)
540 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
541 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !");
542 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
543 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !");
544 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
545 int nbCompo(fineDA->getNumberOfComponents());
546 if(coarseDA->getNumberOfComponents()!=nbCompo)
547 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the number of components of fine DA and coarse one mismatches !");
548 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
549 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) !");
550 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
552 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
553 throw INTERP_KERNEL::Exception(oss.str().c_str());
555 int nbTuplesFine(fineDA->getNumberOfTuples());
556 if(nbTuplesFine%nbOfTuplesInFineExp!=0)
557 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : Invalid nb of tuples in fine DataArray regarding its structure !");
558 int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
559 if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
561 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
562 throw INTERP_KERNEL::Exception(oss.str().c_str());
564 // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
565 double *outPtr(fineDA->getPointer());
566 const double *inPtr(coarseDA->begin());
568 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
573 int offset(fineLocInCoarse[0].first),fact0(facts[0]);
574 for(int i=0;i<dims[0];i++)
576 const double *loc(inPtr+(offset+i)*nbCompo);
577 for(int ifact=0;ifact<fact0;ifact++)
578 outPtr=std::copy(loc,loc+nbCompo,outPtr);
584 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact0(facts[0]),fact1(facts[1]);
585 for(int j=0;j<dims[1];j++)
587 for(int jfact=0;jfact<fact1;jfact++)
589 for(int i=0;i<dims[0];i++)
591 const double *loc(inPtr+(kk+i)*nbCompo);
592 for(int ifact=0;ifact<fact0;ifact++)
593 outPtr=std::copy(loc,loc+nbCompo,outPtr);
602 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]);
603 for(int k=0;k<dims[2];k++)
605 for(int kfact=0;kfact<fact2;kfact++)
607 for(int j=0;j<dims[1];j++)
609 for(int jfact=0;jfact<fact1;jfact++)
611 for(int i=0;i<dims[0];i++)
613 const double *loc(inPtr+(kk+i+j*coarseSt[0])*nbCompo);
614 for(int ifact=0;ifact<fact0;ifact++)
615 outPtr=std::copy(loc,loc+nbCompo,outPtr);
620 kk+=coarseSt[0]*coarseSt[1];
625 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : only dimensions 1, 2 and 3 supported !");
630 * This method spreads the values of coarse data \a coarseDA into \a fineDA.
632 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
633 * \param [in] coarseSt The cell structure of coarse mesh.
634 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
635 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
636 * \param [in] facts The refinement coefficient per axis.
637 * \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.
639 * \sa CondenseFineToCoarse, SpreadCoarseToFineGhostZone
641 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)
644 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level has to be >= 0 !");
645 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
646 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !");
647 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
648 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !");
649 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
650 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
651 int nbCompo(fineDA->getNumberOfComponents());
652 if(coarseDA->getNumberOfComponents()!=nbCompo)
653 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the number of components of fine DA and coarse one mismatches !");
654 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
655 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) !");
656 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
658 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
659 throw INTERP_KERNEL::Exception(oss.str().c_str());
662 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
663 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
664 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
665 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
666 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
668 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
669 throw INTERP_KERNEL::Exception(oss.str().c_str());
672 double *outPtr(fineDA->getPointer());
673 const double *inPtr(coarseDA->begin());
679 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
680 int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
681 for(int i=0;i<ghostSize;i++)
682 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
683 offset=fineLocInCoarse[0].first+ghostSize;
684 for(int i=0;i<dims[0];i++)
686 const double *loc(inPtr+(offset+i)*nbCompo);
687 for(int ifact=0;ifact<fact0;ifact++)
688 outPtr=std::copy(loc,loc+nbCompo,outPtr);
690 offset=fineLocInCoarse[0].second+ghostSize;
691 for(int i=0;i<ghostSize;i++)
692 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
697 SpreadCoarseToFineGhost2D(inPtr,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
702 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
703 int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]);
704 int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize));
705 int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 !
706 for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
707 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
709 for(int i=0;i<dims[2];i++,offset+=nxyWgCoarse)
710 for(int j=0;j<fact2;j++,outPtr+=nxyWgFine*nbCompo)
711 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
712 for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
713 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
717 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : only dimensions 1, 2, 3 supported !");
722 * 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).
724 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
725 * \param [in] coarseSt The cell structure of coarse mesh.
726 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
727 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
728 * \param [in] facts The refinement coefficient per axis.
729 * \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.
731 * \sa SpreadCoarseToFineGhost
733 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)
736 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : ghost level has to be >= 0 !");
737 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
738 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : All input vectors (dimension) must have the same size !");
739 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
740 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the parameters 1 or 3 are NULL or not allocated !");
741 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
742 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
743 int nbCompo(fineDA->getNumberOfComponents());
744 if(coarseDA->getNumberOfComponents()!=nbCompo)
745 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the number of components of fine DA and coarse one mismatches !");
746 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
747 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) !");
748 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
750 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
751 throw INTERP_KERNEL::Exception(oss.str().c_str());
754 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
755 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
756 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
757 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
758 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
760 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
761 throw INTERP_KERNEL::Exception(oss.str().c_str());
764 double *outPtr(fineDA->getPointer());
765 const double *inPtr(coarseDA->begin());
767 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
772 int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
773 for(int i=0;i<ghostSize;i++)
774 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
775 outPtr+=nbCompo*fact0*dims[0];
776 offset=fineLocInCoarse[0].second+ghostSize;
777 for(int i=0;i<ghostSize;i++)
778 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
783 SpreadCoarseToFineGhostZone2D(inPtr,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
788 int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]);
789 int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize));
790 int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 !
791 for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
792 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
794 for(int i=0;i<dims[2];i++,offset+=nxyWgCoarse)
795 for(int j=0;j<fact2;j++,outPtr+=nxyWgFine*nbCompo)
796 SpreadCoarseToFineGhostZone2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
797 for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
798 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
802 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : only dimensions 1, 2, 3 supported !");
806 void MEDCouplingIMesh::setSpaceDimension(int spaceDim)
808 if(spaceDim==_space_dim)
810 CheckSpaceDimension(spaceDim);
815 void MEDCouplingIMesh::updateTime() const
819 std::size_t MEDCouplingIMesh::getHeapMemorySizeWithoutChildren() const
821 return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
824 std::vector<const BigMemoryObject *> MEDCouplingIMesh::getDirectChildrenWithNull() const
826 return std::vector<const BigMemoryObject *>();
830 * This method copyies all tiny strings from other (name and components name).
831 * @throw if other and this have not same mesh type.
833 void MEDCouplingIMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
835 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
837 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::copyTinyStringsFrom : meshes have not same type !");
838 MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
842 bool MEDCouplingIMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
845 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::isEqualIfNotWhy : input other pointer is null !");
846 const MEDCouplingIMesh *otherC(dynamic_cast<const MEDCouplingIMesh *>(other));
849 reason="mesh given in input is not castable in MEDCouplingIMesh !";
852 if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
854 if(!isEqualWithoutConsideringStrInternal(otherC,prec,reason))
856 if(_axis_unit!=otherC->_axis_unit)
858 reason="The units of axis are not the same !";
864 bool MEDCouplingIMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
866 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
870 return isEqualWithoutConsideringStrInternal(other,prec,tmp);
873 bool MEDCouplingIMesh::isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const
875 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
878 if(_space_dim!=otherC->_space_dim)
880 std::ostringstream oss;
881 oss << "The spaceDimension of this (" << _space_dim << ") is not equal to those of other (" << otherC->_space_dim << ") !";
884 checkSpaceDimension();
885 for(int i=0;i<_space_dim;i++)
887 if(fabs(_origin[i]-otherC->_origin[i])>prec)
889 std::ostringstream oss;
890 oss << "The origin of this and other differs at " << i << " !";
895 for(int i=0;i<_space_dim;i++)
897 if(fabs(_dxyz[i]-otherC->_dxyz[i])>prec)
899 std::ostringstream oss;
900 oss << "The delta of this and other differs at " << i << " !";
905 for(int i=0;i<_space_dim;i++)
907 if(_structure[i]!=otherC->_structure[i])
909 std::ostringstream oss;
910 oss << "The structure of this and other differs at " << i << " !";
918 void MEDCouplingIMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
919 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
921 if(!isEqualWithoutConsideringStr(other,prec))
922 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalWith : Meshes are not the same !");
926 * Nothing is done here (except to check that the other is a MEDCoupling::MEDCouplingIMesh instance too).
927 * The user intend that the nodes are the same, so by construction of MEDCoupling::MEDCouplingIMesh, \a this and \a other are the same !
929 void MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
930 DataArrayInt *&cellCor) const
932 if(!isEqualWithoutConsideringStr(other,prec))
933 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
936 void MEDCouplingIMesh::checkConsistencyLight() const
938 checkSpaceDimension();
939 for(int i=0;i<_space_dim;i++)
942 std::ostringstream oss; oss << "MEDCouplingIMesh::checkConsistencyLight : On axis " << i << "/" << _space_dim << ", number of nodes is equal to " << _structure[i] << " ! must be >=1 !";
943 throw INTERP_KERNEL::Exception(oss.str().c_str());
947 void MEDCouplingIMesh::checkConsistency(double eps) const
949 checkConsistencyLight();
952 void MEDCouplingIMesh::getNodeGridStructure(int *res) const
954 checkSpaceDimension();
955 std::copy(_structure,_structure+_space_dim,res);
958 std::vector<int> MEDCouplingIMesh::getNodeGridStructure() const
960 checkSpaceDimension();
961 std::vector<int> ret(_structure,_structure+_space_dim);
965 MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
967 checkConsistencyLight();
968 int dim(getSpaceDimension());
969 if(dim!=(int)cellPart.size())
971 std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !";
972 throw INTERP_KERNEL::Exception(oss.str().c_str());
974 double retOrigin[3]={0.,0.,0.};
975 int retStruct[3]={0,0,0};
976 MCAuto<MEDCouplingIMesh> ret(dynamic_cast<MEDCouplingIMesh *>(deepCopy()));
977 for(int i=0;i<dim;i++)
979 int startNode(cellPart[i].first),endNode(cellPart[i].second+1);
980 int myDelta(endNode-startNode);
981 if(startNode<0 || startNode>=_structure[i])
983 std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : At dimension #" << i << " the start node id is " << startNode << " it should be in [0," << _structure[i] << ") !";
984 throw INTERP_KERNEL::Exception(oss.str().c_str());
986 if(myDelta<0 || myDelta>_structure[i])
988 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;
989 throw INTERP_KERNEL::Exception(oss.str().c_str());
991 retOrigin[i]=_origin[i]+startNode*_dxyz[i];
992 retStruct[i]=myDelta;
994 ret->setNodeStruct(retStruct,retStruct+dim);
995 ret->setOrigin(retOrigin,retOrigin+dim);
996 ret->checkConsistencyLight();
1001 * Return the space dimension of \a this.
1003 int MEDCouplingIMesh::getSpaceDimension() const
1008 void MEDCouplingIMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
1011 int spaceDim(getSpaceDimension());
1012 getSplitNodeValues(tmp);
1014 GetPosFromId(nodeId,spaceDim,tmp,tmp2);
1015 for(int j=0;j<spaceDim;j++)
1016 coo.push_back(_origin[j]+_dxyz[j]*tmp2[j]);
1019 std::string MEDCouplingIMesh::simpleRepr() const
1021 std::ostringstream ret;
1022 ret << "Image grid with name : \"" << getName() << "\"\n";
1023 ret << "Description of mesh : \"" << getDescription() << "\"\n";
1025 double tt(getTime(tmpp1,tmpp2));
1026 int spaceDim(_space_dim);
1027 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
1028 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
1029 ret << "Space dimension : " << spaceDim << "\n";
1030 if(spaceDim<0 || spaceDim>3)
1032 ret << "The nodal structure is : "; std::copy(_structure,_structure+spaceDim,std::ostream_iterator<int>(ret," ")); ret << "\n";
1033 ret << "The origin position is [" << _axis_unit << "]: ";
1034 std::copy(_origin,_origin+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
1035 ret << "The intervals along axis are : ";
1036 std::copy(_dxyz,_dxyz+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
1040 std::string MEDCouplingIMesh::advancedRepr() const
1042 return simpleRepr();
1045 void MEDCouplingIMesh::getBoundingBox(double *bbox) const
1047 checkConsistencyLight();
1048 int dim(getSpaceDimension());
1049 for(int idim=0; idim<dim; idim++)
1051 bbox[2*idim]=_origin[idim];
1052 int coeff(_structure[idim]);
1053 if(_structure[idim]<0)
1055 std::ostringstream oss; oss << "MEDCouplingIMesh::getBoundingBox : on axis #" << idim << " number of nodes in structure is < 0 !";
1056 throw INTERP_KERNEL::Exception(oss.str().c_str());
1058 if(_structure[idim]>1)
1059 coeff=_structure[idim]-1;
1060 bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*coeff;
1065 * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
1067 * For 1D cells, the returned field contains lengths.<br>
1068 * For 2D cells, the returned field contains areas.<br>
1069 * For 3D cells, the returned field contains volumes.
1070 * \param [in] isAbs - a not used parameter.
1071 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
1072 * and one time . The caller is to delete this field using decrRef() as it is no
1075 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureField(bool isAbs) const
1077 checkConsistencyLight();
1078 std::string name="MeasureOfMesh_";
1080 int nbelem(getNumberOfCells());
1081 MEDCouplingFieldDouble *field(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
1082 field->setName(name);
1083 DataArrayDouble* array(DataArrayDouble::New());
1084 array->alloc(nbelem,1);
1085 array->fillWithValue(getMeasureOfAnyCell());
1086 field->setArray(array) ;
1088 field->setMesh(const_cast<MEDCouplingIMesh *>(this));
1089 field->synchronizeTimeWithMesh();
1094 * not implemented yet !
1096 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureFieldOnNode(bool isAbs) const
1098 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::getMeasureFieldOnNode : not implemented yet !");
1102 int MEDCouplingIMesh::getCellContainingPoint(const double *pos, double eps) const
1104 int dim(getSpaceDimension()),ret(0),coeff(1);
1105 for(int i=0;i<dim;i++)
1107 int nbOfCells(_structure[i]-1);
1109 int tmp((int)((ref-_origin[i])/_dxyz[i]));
1110 if(tmp>=0 && tmp<nbOfCells)
1121 void MEDCouplingIMesh::rotate(const double *center, const double *vector, double angle)
1123 throw INTERP_KERNEL::Exception("No rotation available on IMesh : Traduce it to unstructured mesh to apply it !");
1127 * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
1128 * component of the \a vector to all node coordinates of a corresponding axis.
1129 * \param [in] vector - the translation vector whose size must be not less than \a
1130 * this->getSpaceDimension().
1132 void MEDCouplingIMesh::translate(const double *vector)
1134 checkSpaceDimension();
1135 int dim(getSpaceDimension());
1136 std::transform(_origin,_origin+dim,vector,_origin,std::plus<double>());
1141 * Applies scaling transformation to all nodes of \a this mesh.
1142 * \param [in] point - coordinates of a scaling center. This array is to be of
1143 * size \a this->getSpaceDimension() at least.
1144 * \param [in] factor - a scale factor.
1146 void MEDCouplingIMesh::scale(const double *point, double factor)
1148 checkSpaceDimension();
1149 int dim(getSpaceDimension());
1150 std::transform(_origin,_origin+dim,point,_origin,std::minus<double>());
1151 std::transform(_origin,_origin+dim,_origin,std::bind2nd(std::multiplies<double>(),factor));
1152 std::transform(_dxyz,_dxyz+dim,_dxyz,std::bind2nd(std::multiplies<double>(),factor));
1153 std::transform(_origin,_origin+dim,point,_origin,std::plus<double>());
1157 MEDCouplingMesh *MEDCouplingIMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
1159 //not implemented yet !
1164 * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
1165 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1166 * this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
1167 * components. The caller is to delete this array using decrRef() as it is
1170 DataArrayDouble *MEDCouplingIMesh::getCoordinatesAndOwner() const
1172 checkConsistencyLight();
1173 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1174 int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
1175 ret->alloc(nbNodes,spaceDim);
1176 double *pt(ret->getPointer());
1177 ret->setInfoOnComponents(buildInfoOnComponents());
1179 getSplitNodeValues(tmp);
1180 for(int i=0;i<nbNodes;i++)
1182 GetPosFromId(i,spaceDim,tmp,tmp2);
1183 for(int j=0;j<spaceDim;j++)
1184 pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+_origin[j];
1190 * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
1191 * computed by averaging coordinates of cell nodes.
1192 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1193 * this->getNumberOfCells() tuples per \a this->getSpaceDimension()
1194 * components. The caller is to delete this array using decrRef() as it is
1197 DataArrayDouble *MEDCouplingIMesh::computeCellCenterOfMass() const
1199 checkConsistencyLight();
1200 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1201 int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()),tmp[3],tmp2[3];
1202 ret->alloc(nbCells,spaceDim);
1203 double *pt(ret->getPointer()),shiftOrigin[3];
1204 std::transform(_dxyz,_dxyz+spaceDim,shiftOrigin,std::bind2nd(std::multiplies<double>(),0.5));
1205 std::transform(_origin,_origin+spaceDim,shiftOrigin,shiftOrigin,std::plus<double>());
1206 getSplitCellValues(tmp);
1207 ret->setInfoOnComponents(buildInfoOnComponents());
1208 for(int i=0;i<nbCells;i++)
1210 GetPosFromId(i,spaceDim,tmp,tmp2);
1211 for(int j=0;j<spaceDim;j++)
1212 pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+shiftOrigin[j];
1217 DataArrayDouble *MEDCouplingIMesh::computeIsoBarycenterOfNodesPerCell() const
1219 return MEDCouplingIMesh::computeCellCenterOfMass();
1222 void MEDCouplingIMesh::renumberCells(const int *old2NewBg, bool check)
1224 throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for IMesh !");
1227 void MEDCouplingIMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1230 double time(getTime(it,order));
1233 littleStrings.clear();
1234 littleStrings.push_back(getName());
1235 littleStrings.push_back(getDescription());
1236 littleStrings.push_back(getTimeUnit());
1237 littleStrings.push_back(getAxisUnit());
1238 tinyInfo.push_back(it);
1239 tinyInfo.push_back(order);
1240 tinyInfo.push_back(_space_dim);
1241 tinyInfo.insert(tinyInfo.end(),_structure,_structure+3);
1242 tinyInfoD.push_back(time);
1243 tinyInfoD.insert(tinyInfoD.end(),_dxyz,_dxyz+3);
1244 tinyInfoD.insert(tinyInfoD.end(),_origin,_origin+3);
1247 void MEDCouplingIMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1253 void MEDCouplingIMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1255 a1=DataArrayInt::New();
1257 a2=DataArrayDouble::New();
1261 void MEDCouplingIMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1262 const std::vector<std::string>& littleStrings)
1264 setName(littleStrings[0]);
1265 setDescription(littleStrings[1]);
1266 setTimeUnit(littleStrings[2]);
1267 setAxisUnit(littleStrings[3]);
1268 setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]);
1269 _space_dim=tinyInfo[2];
1270 _structure[0]=tinyInfo[3]; _structure[1]=tinyInfo[4]; _structure[2]=tinyInfo[5];
1271 _dxyz[0]=tinyInfoD[1]; _dxyz[1]=tinyInfoD[2]; _dxyz[2]=tinyInfoD[3];
1272 _origin[0]=tinyInfoD[4]; _origin[1]=tinyInfoD[5]; _origin[2]=tinyInfoD[6];
1276 void MEDCouplingIMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
1278 checkConsistencyLight();
1279 std::ostringstream extent,origin,spacing;
1280 for(int i=0;i<3;i++)
1283 { extent << "0 " << _structure[i]-1 << " "; origin << _origin[i] << " "; spacing << _dxyz[i] << " "; }
1285 { extent << "0 0 "; origin << "0 "; spacing << "0 "; }
1287 ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\" Origin=\"" << origin.str() << "\" Spacing=\"" << spacing.str() << "\">\n";
1288 ofs << " <Piece Extent=\"" << extent.str() << "\">\n";
1289 ofs << " <PointData>\n" << pointData << std::endl;
1290 ofs << " </PointData>\n";
1291 ofs << " <CellData>\n" << cellData << std::endl;
1292 ofs << " </CellData>\n";
1293 ofs << " <Coordinates>\n";
1294 ofs << " </Coordinates>\n";
1295 ofs << " </Piece>\n";
1296 ofs << " </" << getVTKDataSetType() << ">\n";
1299 void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const
1301 stream << "MEDCouplingIMesh C++ instance at " << this << ". Name : \"" << getName() << "\". Space dimension : " << _space_dim << ".";
1302 if(_space_dim<0 || _space_dim>3)
1305 std::ostringstream stream0,stream1;
1306 int nbNodes(1),nbCells(0);
1308 for(int i=0;i<_space_dim;i++)
1311 int tmpNodes(_structure[i]);
1312 stream1 << "- Axis " << tmp << " : " << tmpNodes << " nodes (orig=" << _origin[i] << ", inter=" << _dxyz[i] << ").";
1314 stream1 << std::endl;
1320 nbCells=nbCells==0?tmpNodes-1:nbCells*(tmpNodes-1);
1324 stream0 << "Number of cells : " << nbCells << ", Number of nodes : " << nbNodes;
1325 stream << stream0.str();
1327 stream << std::endl;
1329 stream << stream1.str();
1332 std::string MEDCouplingIMesh::getVTKFileExtension() const
1334 return std::string("vti");
1337 std::string MEDCouplingIMesh::getVTKDataSetType() const
1339 return std::string("ImageData");
1342 std::vector<std::string> MEDCouplingIMesh::buildInfoOnComponents() const
1344 checkSpaceDimension();
1345 int dim(getSpaceDimension());
1346 std::vector<std::string> ret(dim);
1347 for(int i=0;i<dim;i++)
1349 std::ostringstream oss;
1350 char tmp('X'+i); oss << tmp;
1351 ret[i]=DataArray::BuildInfoFromVarAndUnit(oss.str(),_axis_unit);
1356 void MEDCouplingIMesh::checkSpaceDimension() const
1358 CheckSpaceDimension(_space_dim);
1361 void MEDCouplingIMesh::CheckSpaceDimension(int spaceDim)
1363 if(spaceDim<0 || spaceDim>3)
1364 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CheckSpaceDimension : input spaceDim must be in [0,1,2,3] !");
1367 int MEDCouplingIMesh::FindIntRoot(int val, int order)
1372 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : input val is < 0 ! Not possible to compute a root !");
1375 if(order!=2 && order!=3)
1376 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the order available are 0,1,2 or 3 !");
1377 double valf((double)val);
1380 double retf(sqrt(valf));
1383 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect square root !");
1388 double retf(std::pow(val,0.3333333333333333));
1389 int ret((int)retf),ret2(ret+1);
1390 if(ret*ret*ret!=val && ret2*ret2*ret2!=val)
1391 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect cublic root !");
1392 if(ret*ret*ret==val)
1399 void MEDCouplingIMesh::SpreadCoarseToFineGhost2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector<int>& coarseSt, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
1401 double *outPtrWork(outPtr);
1402 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
1403 int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
1404 int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
1405 for(int jg=0;jg<ghostSize;jg++)
1407 for(int ig=0;ig<ghostSize;ig++)
1408 outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1410 for(int ig=0;ig<dims[0];ig++,kk0++)
1411 for(int ifact=0;ifact<fact0;ifact++)
1412 outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1413 for(int ik=0;ik<ghostSize;ik++)
1414 outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1416 for(int j=0;j<dims[1];j++)
1418 kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
1419 for(int jfact=0;jfact<fact1;jfact++)
1421 for(int ig=0;ig<ghostSize;ig++)
1422 outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1423 int kk0(kk+1);//1 not ghost. We make the hypothesis that factors is >= ghostlev
1424 for(int i=0;i<dims[0];i++,kk0++)
1426 const double *loc(inPtr+kk0*nbCompo);
1427 for(int ifact=0;ifact<fact0;ifact++)
1428 outPtrWork=std::copy(loc,loc+nbCompo,outPtrWork);
1430 for(int ig=0;ig<ghostSize;ig++)
1431 outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1434 kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
1435 for(int jg=0;jg<ghostSize;jg++)
1437 for(int ig=0;ig<ghostSize;ig++)
1438 outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1440 for(int ig=0;ig<dims[0];ig++,kk0++)
1441 for(int ifact=0;ifact<fact0;ifact++)
1442 outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1443 for(int ik=0;ik<ghostSize;ik++)
1444 outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1448 void MEDCouplingIMesh::SpreadCoarseToFineGhostZone2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector<int>& coarseSt, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
1450 double *outPtr2(outPtr);
1451 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
1452 int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
1453 int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
1454 for(int jg=0;jg<ghostSize;jg++)
1456 for(int ig=0;ig<ghostSize;ig++)
1457 outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2);
1459 for(int ig=0;ig<dims[0];ig++,kk0++)
1460 for(int ifact=0;ifact<fact0;ifact++)
1461 outPtr2=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
1462 for(int ik=0;ik<ghostSize;ik++)
1463 outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
1465 for(int j=0;j<dims[1];j++)
1467 kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
1468 for(int jfact=0;jfact<fact1;jfact++)
1470 for(int ig=0;ig<ghostSize;ig++)
1471 outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2);
1472 int kk0(kk+1+dims[0]);//1 not ghost. We make the hypothesis that factors is >= ghostlev
1473 outPtr2+=fact0*nbCompo*dims[0];
1474 for(int ig=0;ig<ghostSize;ig++)
1475 outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
1478 kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
1479 for(int jg=0;jg<ghostSize;jg++)
1481 for(int ig=0;ig<ghostSize;ig++)
1482 outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2);
1484 for(int ig=0;ig<dims[0];ig++,kk0++)
1485 for(int ifact=0;ifact<fact0;ifact++)
1486 outPtr2=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
1487 for(int ik=0;ik<ghostSize;ik++)
1488 outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);