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)*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 ParaMEDMEM::MEDCouplingIMesh instance too).
927 * The user intend that the nodes are the same, so by construction of ParaMEDMEM::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::checkCoherency() const
938 checkSpaceDimension();
939 for(int i=0;i<_space_dim;i++)
942 std::ostringstream oss; oss << "MEDCouplingIMesh::checkCoherency : 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::checkCoherency1(double eps) const
952 void MEDCouplingIMesh::checkCoherency2(double eps) const
954 checkCoherency1(eps);
957 void MEDCouplingIMesh::getNodeGridStructure(int *res) const
959 checkSpaceDimension();
960 std::copy(_structure,_structure+_space_dim,res);
963 std::vector<int> MEDCouplingIMesh::getNodeGridStructure() const
965 checkSpaceDimension();
966 std::vector<int> ret(_structure,_structure+_space_dim);
970 MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
973 int dim(getSpaceDimension());
974 if(dim!=(int)cellPart.size())
976 std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !";
977 throw INTERP_KERNEL::Exception(oss.str().c_str());
979 double retOrigin[3]={0.,0.,0.};
980 int retStruct[3]={0,0,0};
981 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(dynamic_cast<MEDCouplingIMesh *>(deepCpy()));
982 for(int i=0;i<dim;i++)
984 int startNode(cellPart[i].first),endNode(cellPart[i].second+1);
985 int myDelta(endNode-startNode);
986 if(startNode<0 || startNode>=_structure[i])
988 std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : At dimension #" << i << " the start node id is " << startNode << " it should be in [0," << _structure[i] << ") !";
989 throw INTERP_KERNEL::Exception(oss.str().c_str());
991 if(myDelta<0 || myDelta>_structure[i])
993 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;
994 throw INTERP_KERNEL::Exception(oss.str().c_str());
996 retOrigin[i]=_origin[i]+startNode*_dxyz[i];
997 retStruct[i]=myDelta;
999 ret->setNodeStruct(retStruct,retStruct+dim);
1000 ret->setOrigin(retOrigin,retOrigin+dim);
1001 ret->checkCoherency();
1006 * Return the space dimension of \a this.
1008 int MEDCouplingIMesh::getSpaceDimension() const
1013 void MEDCouplingIMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
1016 int spaceDim(getSpaceDimension());
1017 getSplitNodeValues(tmp);
1019 GetPosFromId(nodeId,spaceDim,tmp,tmp2);
1020 for(int j=0;j<spaceDim;j++)
1021 coo.push_back(_origin[j]+_dxyz[j]*tmp2[j]);
1024 std::string MEDCouplingIMesh::simpleRepr() const
1026 std::ostringstream ret;
1027 ret << "Image grid with name : \"" << getName() << "\"\n";
1028 ret << "Description of mesh : \"" << getDescription() << "\"\n";
1030 double tt(getTime(tmpp1,tmpp2));
1031 int spaceDim(_space_dim);
1032 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
1033 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
1034 ret << "Space dimension : " << spaceDim << "\n";
1035 if(spaceDim<0 || spaceDim>3)
1037 ret << "The nodal structure is : "; std::copy(_structure,_structure+spaceDim,std::ostream_iterator<int>(ret," ")); ret << "\n";
1038 ret << "The origin position is [" << _axis_unit << "]: ";
1039 std::copy(_origin,_origin+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
1040 ret << "The intervals along axis are : ";
1041 std::copy(_dxyz,_dxyz+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
1045 std::string MEDCouplingIMesh::advancedRepr() const
1047 return simpleRepr();
1050 void MEDCouplingIMesh::getBoundingBox(double *bbox) const
1053 int dim(getSpaceDimension());
1054 for(int idim=0; idim<dim; idim++)
1056 bbox[2*idim]=_origin[idim];
1057 int coeff(_structure[idim]);
1058 if(_structure[idim]<0)
1060 std::ostringstream oss; oss << "MEDCouplingIMesh::getBoundingBox : on axis #" << idim << " number of nodes in structure is < 0 !";
1061 throw INTERP_KERNEL::Exception(oss.str().c_str());
1063 if(_structure[idim]>1)
1064 coeff=_structure[idim]-1;
1065 bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*coeff;
1070 * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
1072 * For 1D cells, the returned field contains lengths.<br>
1073 * For 2D cells, the returned field contains areas.<br>
1074 * For 3D cells, the returned field contains volumes.
1075 * \param [in] isAbs - a not used parameter.
1076 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
1077 * and one time . The caller is to delete this field using decrRef() as it is no
1080 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureField(bool isAbs) const
1083 std::string name="MeasureOfMesh_";
1085 int nbelem(getNumberOfCells());
1086 MEDCouplingFieldDouble *field(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
1087 field->setName(name);
1088 DataArrayDouble* array(DataArrayDouble::New());
1089 array->alloc(nbelem,1);
1090 array->fillWithValue(getMeasureOfAnyCell());
1091 field->setArray(array) ;
1093 field->setMesh(const_cast<MEDCouplingIMesh *>(this));
1094 field->synchronizeTimeWithMesh();
1099 * not implemented yet !
1101 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureFieldOnNode(bool isAbs) const
1103 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::getMeasureFieldOnNode : not implemented yet !");
1107 int MEDCouplingIMesh::getCellContainingPoint(const double *pos, double eps) const
1109 int dim(getSpaceDimension()),ret(0),coeff(1);
1110 for(int i=0;i<dim;i++)
1112 int nbOfCells(_structure[i]-1);
1114 int tmp((int)((ref-_origin[i])/_dxyz[i]));
1115 if(tmp>=0 && tmp<nbOfCells)
1126 void MEDCouplingIMesh::rotate(const double *center, const double *vector, double angle)
1128 throw INTERP_KERNEL::Exception("No rotation available on IMesh : Traduce it to unstructured mesh to apply it !");
1132 * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
1133 * component of the \a vector to all node coordinates of a corresponding axis.
1134 * \param [in] vector - the translation vector whose size must be not less than \a
1135 * this->getSpaceDimension().
1137 void MEDCouplingIMesh::translate(const double *vector)
1139 checkSpaceDimension();
1140 int dim(getSpaceDimension());
1141 std::transform(_origin,_origin+dim,vector,_origin,std::plus<double>());
1146 * Applies scaling transformation to all nodes of \a this mesh.
1147 * \param [in] point - coordinates of a scaling center. This array is to be of
1148 * size \a this->getSpaceDimension() at least.
1149 * \param [in] factor - a scale factor.
1151 void MEDCouplingIMesh::scale(const double *point, double factor)
1153 checkSpaceDimension();
1154 int dim(getSpaceDimension());
1155 std::transform(_origin,_origin+dim,point,_origin,std::minus<double>());
1156 std::transform(_origin,_origin+dim,_origin,std::bind2nd(std::multiplies<double>(),factor));
1157 std::transform(_dxyz,_dxyz+dim,_dxyz,std::bind2nd(std::multiplies<double>(),factor));
1158 std::transform(_origin,_origin+dim,point,_origin,std::plus<double>());
1162 MEDCouplingMesh *MEDCouplingIMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
1164 //not implemented yet !
1169 * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
1170 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1171 * this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
1172 * components. The caller is to delete this array using decrRef() as it is
1175 DataArrayDouble *MEDCouplingIMesh::getCoordinatesAndOwner() const
1178 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1179 int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
1180 ret->alloc(nbNodes,spaceDim);
1181 double *pt(ret->getPointer());
1182 ret->setInfoOnComponents(buildInfoOnComponents());
1184 getSplitNodeValues(tmp);
1185 for(int i=0;i<nbNodes;i++)
1187 GetPosFromId(i,spaceDim,tmp,tmp2);
1188 for(int j=0;j<spaceDim;j++)
1189 pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+_origin[j];
1195 * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
1196 * computed by averaging coordinates of cell nodes.
1197 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1198 * this->getNumberOfCells() tuples per \a this->getSpaceDimension()
1199 * components. The caller is to delete this array using decrRef() as it is
1202 DataArrayDouble *MEDCouplingIMesh::getBarycenterAndOwner() const
1205 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1206 int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()),tmp[3],tmp2[3];
1207 ret->alloc(nbCells,spaceDim);
1208 double *pt(ret->getPointer()),shiftOrigin[3];
1209 std::transform(_dxyz,_dxyz+spaceDim,shiftOrigin,std::bind2nd(std::multiplies<double>(),0.5));
1210 std::transform(_origin,_origin+spaceDim,shiftOrigin,shiftOrigin,std::plus<double>());
1211 getSplitCellValues(tmp);
1212 ret->setInfoOnComponents(buildInfoOnComponents());
1213 for(int i=0;i<nbCells;i++)
1215 GetPosFromId(i,spaceDim,tmp,tmp2);
1216 for(int j=0;j<spaceDim;j++)
1217 pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+shiftOrigin[j];
1222 DataArrayDouble *MEDCouplingIMesh::computeIsoBarycenterOfNodesPerCell() const
1224 return MEDCouplingIMesh::getBarycenterAndOwner();
1227 void MEDCouplingIMesh::renumberCells(const int *old2NewBg, bool check)
1229 throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for IMesh !");
1232 void MEDCouplingIMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1235 double time(getTime(it,order));
1238 littleStrings.clear();
1239 littleStrings.push_back(getName());
1240 littleStrings.push_back(getDescription());
1241 littleStrings.push_back(getTimeUnit());
1242 littleStrings.push_back(getAxisUnit());
1243 tinyInfo.push_back(it);
1244 tinyInfo.push_back(order);
1245 tinyInfo.push_back(_space_dim);
1246 tinyInfo.insert(tinyInfo.end(),_structure,_structure+3);
1247 tinyInfoD.push_back(time);
1248 tinyInfoD.insert(tinyInfoD.end(),_dxyz,_dxyz+3);
1249 tinyInfoD.insert(tinyInfoD.end(),_origin,_origin+3);
1252 void MEDCouplingIMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1258 void MEDCouplingIMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1260 a1=DataArrayInt::New();
1262 a2=DataArrayDouble::New();
1266 void MEDCouplingIMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1267 const std::vector<std::string>& littleStrings)
1269 setName(littleStrings[0]);
1270 setDescription(littleStrings[1]);
1271 setTimeUnit(littleStrings[2]);
1272 setAxisUnit(littleStrings[3]);
1273 setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]);
1274 _space_dim=tinyInfo[2];
1275 _structure[0]=tinyInfo[3]; _structure[1]=tinyInfo[4]; _structure[2]=tinyInfo[5];
1276 _dxyz[0]=tinyInfoD[1]; _dxyz[1]=tinyInfoD[2]; _dxyz[2]=tinyInfoD[3];
1277 _origin[0]=tinyInfoD[4]; _origin[1]=tinyInfoD[5]; _origin[2]=tinyInfoD[6];
1281 void MEDCouplingIMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
1284 std::ostringstream extent,origin,spacing;
1285 for(int i=0;i<3;i++)
1288 { extent << "0 " << _structure[i]-1 << " "; origin << _origin[i] << " "; spacing << _dxyz[i] << " "; }
1290 { extent << "0 0 "; origin << "0 "; spacing << "0 "; }
1292 ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\" Origin=\"" << origin.str() << "\" Spacing=\"" << spacing.str() << "\">\n";
1293 ofs << " <Piece Extent=\"" << extent.str() << "\">\n";
1294 ofs << " <PointData>\n" << pointData << std::endl;
1295 ofs << " </PointData>\n";
1296 ofs << " <CellData>\n" << cellData << std::endl;
1297 ofs << " </CellData>\n";
1298 ofs << " <Coordinates>\n";
1299 ofs << " </Coordinates>\n";
1300 ofs << " </Piece>\n";
1301 ofs << " </" << getVTKDataSetType() << ">\n";
1304 void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const
1306 stream << "MEDCouplingIMesh C++ instance at " << this << ". Name : \"" << getName() << "\". Space dimension : " << _space_dim << ".";
1307 if(_space_dim<0 || _space_dim>3)
1310 std::ostringstream stream0,stream1;
1311 int nbNodes(1),nbCells(0);
1313 for(int i=0;i<_space_dim;i++)
1316 int tmpNodes(_structure[i]);
1317 stream1 << "- Axis " << tmp << " : " << tmpNodes << " nodes (orig=" << _origin[i] << ", inter=" << _dxyz[i] << ").";
1319 stream1 << std::endl;
1325 nbCells=nbCells==0?tmpNodes-1:nbCells*(tmpNodes-1);
1329 stream0 << "Number of cells : " << nbCells << ", Number of nodes : " << nbNodes;
1330 stream << stream0.str();
1332 stream << std::endl;
1334 stream << stream1.str();
1337 std::string MEDCouplingIMesh::getVTKFileExtension() const
1339 return std::string("vti");
1342 std::string MEDCouplingIMesh::getVTKDataSetType() const
1344 return std::string("ImageData");
1347 std::vector<std::string> MEDCouplingIMesh::buildInfoOnComponents() const
1349 checkSpaceDimension();
1350 int dim(getSpaceDimension());
1351 std::vector<std::string> ret(dim);
1352 for(int i=0;i<dim;i++)
1354 std::ostringstream oss;
1355 char tmp('X'+i); oss << tmp;
1356 ret[i]=DataArray::BuildInfoFromVarAndUnit(oss.str(),_axis_unit);
1361 void MEDCouplingIMesh::checkSpaceDimension() const
1363 CheckSpaceDimension(_space_dim);
1366 void MEDCouplingIMesh::CheckSpaceDimension(int spaceDim)
1368 if(spaceDim<0 || spaceDim>3)
1369 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CheckSpaceDimension : input spaceDim must be in [0,1,2,3] !");
1372 int MEDCouplingIMesh::FindIntRoot(int val, int order)
1377 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : input val is < 0 ! Not possible to compute a root !");
1380 if(order!=2 && order!=3)
1381 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the order available are 0,1,2 or 3 !");
1382 double valf((double)val);
1385 double retf(sqrt(valf));
1388 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect square root !");
1393 double retf(std::pow(val,0.3333333333333333));
1394 int ret((int)retf),ret2(ret+1);
1395 if(ret*ret*ret!=val && ret2*ret2*ret2!=val)
1396 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect cublic root !");
1397 if(ret*ret*ret==val)
1404 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)
1406 double *outPtrWork(outPtr);
1407 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
1408 int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
1409 int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
1410 for(int jg=0;jg<ghostSize;jg++)
1412 for(int ig=0;ig<ghostSize;ig++)
1413 outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1415 for(int ig=0;ig<dims[0];ig++,kk0++)
1416 for(int ifact=0;ifact<fact0;ifact++)
1417 outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1418 for(int ik=0;ik<ghostSize;ik++)
1419 outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1421 for(int j=0;j<dims[1];j++)
1423 kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
1424 for(int jfact=0;jfact<fact1;jfact++)
1426 for(int ig=0;ig<ghostSize;ig++)
1427 outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1428 int kk0(kk+1);//1 not ghost. We make the hypothesis that factors is >= ghostlev
1429 for(int i=0;i<dims[0];i++,kk0++)
1431 const double *loc(inPtr+kk0*nbCompo);
1432 for(int ifact=0;ifact<fact0;ifact++)
1433 outPtrWork=std::copy(loc,loc+nbCompo,outPtrWork);
1435 for(int ig=0;ig<ghostSize;ig++)
1436 outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1439 kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
1440 for(int jg=0;jg<ghostSize;jg++)
1442 for(int ig=0;ig<ghostSize;ig++)
1443 outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1445 for(int ig=0;ig<dims[0];ig++,kk0++)
1446 for(int ifact=0;ifact<fact0;ifact++)
1447 outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1448 for(int ik=0;ik<ghostSize;ik++)
1449 outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1453 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)
1455 double *outPtr2(outPtr);
1456 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
1457 int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
1458 int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
1459 for(int jg=0;jg<ghostSize;jg++)
1461 for(int ig=0;ig<ghostSize;ig++)
1462 outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2);
1464 for(int ig=0;ig<dims[0];ig++,kk0++)
1465 for(int ifact=0;ifact<fact0;ifact++)
1466 outPtr2=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
1467 for(int ik=0;ik<ghostSize;ik++)
1468 outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
1470 for(int j=0;j<dims[1];j++)
1472 kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
1473 for(int jfact=0;jfact<fact1;jfact++)
1475 for(int ig=0;ig<ghostSize;ig++)
1476 outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2);
1477 int kk0(kk+1+dims[0]);//1 not ghost. We make the hypothesis that factors is >= ghostlev
1478 outPtr2+=fact0*nbCompo*dims[0];
1479 for(int ig=0;ig<ghostSize;ig++)
1480 outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
1483 kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
1484 for(int jg=0;jg<ghostSize;jg++)
1486 for(int ig=0;ig<ghostSize;ig++)
1487 outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2);
1489 for(int ig=0;ig<dims[0];ig++,kk0++)
1490 for(int ifact=0;ifact<fact0;ifact++)
1491 outPtr2=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
1492 for(int ik=0;ik<ghostSize;ik++)
1493 outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);