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);
78 const DataArrayDouble *MEDCouplingIMesh::getDirectAccessOfCoordsArrIfInStructure() const
80 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::getDirectAccessOfCoordsArrIfInStructure : MEDCouplingIMesh does not aggregate array of coordinates !");
84 * This method creates a copy of \a this enlarged by \a ghostLev cells on each axis.
85 * If \a ghostLev equal to 0 this method behaves as MEDCouplingIMesh::clone.
87 * \param [in] ghostLev - the ghost level expected
88 * \return MEDCouplingIMesh * - a newly alloacted object to be managed by the caller.
89 * \throw if \a ghostLev < 0.
91 MEDCouplingIMesh *MEDCouplingIMesh::buildWithGhost(int ghostLev) const
94 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::buildWithGhost : the ghostLev must be >= 0 !");
95 checkConsistencyLight();
96 int spaceDim(getSpaceDimension());
97 double origin[3],dxyz[3];
99 for(int i=0;i<spaceDim;i++)
101 origin[i]=_origin[i]-ghostLev*_dxyz[i];
103 structure[i]=_structure[i]+2*ghostLev;
105 MCAuto<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),spaceDim,structure,structure+spaceDim,origin,origin+spaceDim,dxyz,dxyz+spaceDim));
106 ret->copyTinyInfoFrom(this);
110 void MEDCouplingIMesh::setNodeStruct(const int *nodeStrctStart, const int *nodeStrctStop)
112 checkSpaceDimension();
113 int sz((int)std::distance(nodeStrctStart,nodeStrctStop));
115 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setNodeStruct : input vector of node structure has not the right size ! Or change space dimension before calling it !");
116 std::copy(nodeStrctStart,nodeStrctStop,_structure);
120 std::vector<int> MEDCouplingIMesh::getNodeStruct() const
122 checkSpaceDimension();
123 return std::vector<int>(_structure,_structure+_space_dim);
126 void MEDCouplingIMesh::setOrigin(const double *originStart, const double *originStop)
128 checkSpaceDimension();
129 int sz((int)std::distance(originStart,originStop));
131 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setOrigin : input vector of origin vector has not the right size ! Or change space dimension before calling it !");
132 std::copy(originStart,originStop,_origin);
136 std::vector<double> MEDCouplingIMesh::getOrigin() const
138 checkSpaceDimension();
139 return std::vector<double>(_origin,_origin+_space_dim);
142 void MEDCouplingIMesh::setDXYZ(const double *dxyzStart, const double *dxyzStop)
144 checkSpaceDimension();
145 int sz((int)std::distance(dxyzStart,dxyzStop));
147 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setDXYZ : input vector of dxyz vector has not the right size ! Or change space dimension before calling it !");
148 std::copy(dxyzStart,dxyzStop,_dxyz);
152 std::vector<double> MEDCouplingIMesh::getDXYZ() const
154 checkSpaceDimension();
155 return std::vector<double>(_dxyz,_dxyz+_space_dim);
158 void MEDCouplingIMesh::setAxisUnit(const std::string& unitName)
164 std::string MEDCouplingIMesh::getAxisUnit() const
170 * This method returns the measure of any cell in \a this.
171 * This specific method of image grid mesh utilizes the fact that any cell in \a this have the same measure.
172 * The value returned by this method is those used to feed the returned field in the MEDCouplingIMesh::getMeasureField.
174 * \sa getMeasureField
176 double MEDCouplingIMesh::getMeasureOfAnyCell() const
178 checkConsistencyLight();
179 int dim(getSpaceDimension());
181 for(int i=0;i<dim;i++)
187 * This method is allows to convert \a this into MEDCouplingCMesh instance.
188 * This method is the middle level between MEDCouplingIMesh and the most general MEDCouplingUMesh.
189 * This method is useful for MED writers that do not have still the image grid support.
191 * \sa MEDCouplingMesh::buildUnstructured
193 MEDCouplingCMesh *MEDCouplingIMesh::convertToCartesian() const
195 checkConsistencyLight();
196 MCAuto<MEDCouplingCMesh> ret(MEDCouplingCMesh::New());
198 { ret->copyTinyInfoFrom(this); }
199 catch(INTERP_KERNEL::Exception& ) { }
200 int spaceDim(getSpaceDimension());
201 std::vector<std::string> infos(buildInfoOnComponents());
202 for(int i=0;i<spaceDim;i++)
204 MCAuto<DataArrayDouble> arr(DataArrayDouble::New()); arr->alloc(_structure[i],1); arr->setInfoOnComponent(0,infos[i]);
205 arr->iota(); arr->applyLin(_dxyz[i],_origin[i]);
206 ret->setCoordsAt(i,arr);
212 * This method refines \a this uniformaly along all of its dimensions. In case of success the space covered by \a this will remain
213 * the same before the invocation except that the number of cells will be multiplied by \a factor ^ this->getMeshDimension().
214 * The origin of \a this will be not touched only spacing and node structure will be changed.
215 * This method can be useful for AMR users.
217 void MEDCouplingIMesh::refineWithFactor(const std::vector<int>& factors)
219 if((int)factors.size()!=_space_dim)
220 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::refineWithFactor : refinement factors must have size equal to spaceDim !");
221 checkConsistencyLight();
222 std::vector<int> structure(_structure,_structure+3);
223 std::vector<double> dxyz(_dxyz,_dxyz+3);
224 for(int i=0;i<_space_dim;i++)
228 std::ostringstream oss; oss << "MEDCouplingIMesh::refineWithFactor : factor for axis #" << i << " (" << factors[i] << ")is invalid ! Must be > 0 !";
229 throw INTERP_KERNEL::Exception(oss.str().c_str());
231 int factAbs(std::abs(factors[i]));
232 double fact2(1./(double)factors[i]);
233 structure[i]=(_structure[i]-1)*factAbs+1;
234 dxyz[i]=fact2*_dxyz[i];
236 std::copy(structure.begin(),structure.end(),_structure);
237 std::copy(dxyz.begin(),dxyz.end(),_dxyz);
242 * This method returns a newly created mesh containing a single cell in it. This returned cell covers exactly the space covered by \a this.
244 * \return MEDCouplingIMesh * - A newly created object (to be managed by the caller with decrRef) containing simply one cell.
246 * \throw if \a this does not pass the \c checkConsistencyLight test.
248 MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const
250 checkConsistencyLight();
251 int spaceDim(getSpaceDimension()),nodeSt[3];
253 for(int i=0;i<spaceDim;i++)
258 dxyz[i]=(_structure[i]-1)*_dxyz[i];
262 nodeSt[i]=_structure[i];
266 MCAuto<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),getSpaceDimension(),nodeSt,nodeSt+spaceDim,_origin,_origin+spaceDim,dxyz,dxyz+spaceDim));
267 ret->copyTinyInfoFrom(this);
272 * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example)
273 * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh
274 * 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.
276 * \param [in] coarseSt The cell structure of coarse mesh.
277 * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh
278 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
279 * \param [in] facts The refinement coefficient per axis.
280 * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
282 * \sa CondenseFineToCoarseGhost,SpreadCoarseToFine
284 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)
286 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
287 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : All input vectors (dimension) must have the same size !");
288 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
289 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the parameters 1 or 3 are NULL or not allocated !");
290 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
291 int nbCompo(fineDA->getNumberOfComponents());
292 if(coarseDA->getNumberOfComponents()!=nbCompo)
293 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the number of components of fine DA and coarse one mismatches !");
294 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
295 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) !");
296 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
298 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
299 throw INTERP_KERNEL::Exception(oss.str().c_str());
301 int nbTuplesFine(fineDA->getNumberOfTuples());
302 if(nbOfTuplesInFineExp==0)
307 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Nothing to condense considering the range specified ! But DataArray is not empty !");
309 if(nbTuplesFine%nbOfTuplesInFineExp!=0)
310 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Invalid nb of tuples in fine DataArray regarding its structure !");
311 int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
312 if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
314 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
315 throw INTERP_KERNEL::Exception(oss.str().c_str());
317 // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
318 double *outPtr(coarseDA->getPointer());
319 const double *inPtr(fineDA->begin());
321 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
326 int offset(fineLocInCoarse[0].first),fact0(facts[0]);
327 for(int i=0;i<dims[0];i++)
329 double *loc(outPtr+(offset+i)*nbCompo);
330 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
333 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
335 std::copy(inPtr,inPtr+nbCompo,loc);
342 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact1(facts[1]),fact0(facts[0]);
343 for(int j=0;j<dims[1];j++)
345 for(int jfact=0;jfact<fact1;jfact++)
347 for(int i=0;i<dims[0];i++)
349 double *loc(outPtr+(kk+i)*nbCompo);
350 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
352 if(jfact!=0 || ifact!=0)
353 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
355 std::copy(inPtr,inPtr+nbCompo,loc);
365 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]);
366 for(int k=0;k<dims[2];k++)
368 for(int kfact=0;kfact<fact2;kfact++)
370 for(int j=0;j<dims[1];j++)
372 for(int jfact=0;jfact<fact1;jfact++)
374 for(int i=0;i<dims[0];i++)
376 double *loc(outPtr+(kk+i+j*coarseSt[0])*nbCompo);
377 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
379 if(kfact!=0 || jfact!=0 || ifact!=0)
380 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
382 std::copy(inPtr,inPtr+nbCompo,loc);
388 kk+=coarseSt[0]*coarseSt[1];
393 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : only dimensions 1, 2 and 3 supported !");
398 * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example)
399 * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh
400 * 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.
402 * \param [in] coarseSt The cell structure of coarse mesh.
403 * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh
404 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
405 * \param [in] facts The refinement coefficient per axis.
406 * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
407 * \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.
409 * \sa CondenseFineToCoarse,SpreadCoarseToFineGhost
411 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)
414 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : ghost level has to be >= 0 !");
415 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
416 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : All input vectors (dimension) must have the same size !");
417 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
418 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the parameters 1 or 3 are NULL or not allocated !");
419 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
420 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
421 int nbCompo(fineDA->getNumberOfComponents());
422 if(coarseDA->getNumberOfComponents()!=nbCompo)
423 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the number of components of fine DA and coarse one mismatches !");
424 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
425 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) !");
426 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
428 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples in coarse DataArray having " << coarseDA->getNumberOfTuples() << " !";
429 throw INTERP_KERNEL::Exception(oss.str().c_str());
432 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
433 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
434 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
435 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
436 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
438 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
439 throw INTERP_KERNEL::Exception(oss.str().c_str());
442 double *outPtr(coarseDA->getPointer());
443 const double *inPtr(fineDA->begin());
445 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
450 int offset(fineLocInCoarse[0].first+ghostSize),fact0(facts[0]);
451 inPtr+=ghostSize*nbCompo;
452 for(int i=0;i<dims[0];i++)
454 double *loc(outPtr+(offset+i)*nbCompo);
455 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
458 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
460 std::copy(inPtr,inPtr+nbCompo,loc);
467 int nxwg(coarseSt[0]+2*ghostSize);
468 int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)),fact1(facts[1]),fact0(facts[0]);
469 inPtr+=(dims[0]*fact0+2*ghostSize)*ghostSize*nbCompo;
470 for(int j=0;j<dims[1];j++)
472 for(int jfact=0;jfact<fact1;jfact++)
474 inPtr+=ghostSize*nbCompo;
475 for(int i=0;i<dims[0];i++)
477 double *loc(outPtr+(kk+i)*nbCompo);
478 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
480 if(jfact!=0 || ifact!=0)
481 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
483 std::copy(inPtr,inPtr+nbCompo,loc);
486 inPtr+=ghostSize*nbCompo;
494 int nxwg(coarseSt[0]+2*ghostSize),nxywg((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize));
495 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]);
496 inPtr+=(dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)*ghostSize*nbCompo;
497 for(int k=0;k<dims[2];k++)
499 for(int kfact=0;kfact<fact2;kfact++)
501 inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo;
502 for(int j=0;j<dims[1];j++)
505 for(int jfact=0;jfact<fact1;jfact++)
507 inPtr+=ghostSize*nbCompo;
508 for(int i=0;i<dims[0];i++)
510 double *loc(outPtr+(kky+kk+i)*nbCompo);
511 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
513 if(kfact!=0 || jfact!=0 || ifact!=0)
514 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
516 std::copy(inPtr,inPtr+nbCompo,loc);
519 inPtr+=ghostSize*nbCompo;
522 inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo;
529 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2, 3 supported !");
534 * This method spreads the values of coarse data \a coarseDA into \a fineDA.
536 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
537 * \param [in] coarseSt The cell structure of coarse mesh.
538 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
539 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
540 * \param [in] facts The refinement coefficient per axis.
541 * \sa SpreadCoarseToFineGhost, CondenseFineToCoarse
543 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)
545 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
546 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !");
547 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
548 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !");
549 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
550 int nbCompo(fineDA->getNumberOfComponents());
551 if(coarseDA->getNumberOfComponents()!=nbCompo)
552 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the number of components of fine DA and coarse one mismatches !");
553 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
554 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) !");
555 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
557 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
558 throw INTERP_KERNEL::Exception(oss.str().c_str());
560 int nbTuplesFine(fineDA->getNumberOfTuples());
561 if(nbTuplesFine%nbOfTuplesInFineExp!=0)
562 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : Invalid nb of tuples in fine DataArray regarding its structure !");
563 int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
564 if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
566 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
567 throw INTERP_KERNEL::Exception(oss.str().c_str());
569 // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
570 double *outPtr(fineDA->getPointer());
571 const double *inPtr(coarseDA->begin());
573 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
578 int offset(fineLocInCoarse[0].first),fact0(facts[0]);
579 for(int i=0;i<dims[0];i++)
581 const double *loc(inPtr+(offset+i)*nbCompo);
582 for(int ifact=0;ifact<fact0;ifact++)
583 outPtr=std::copy(loc,loc+nbCompo,outPtr);
589 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact0(facts[0]),fact1(facts[1]);
590 for(int j=0;j<dims[1];j++)
592 for(int jfact=0;jfact<fact1;jfact++)
594 for(int i=0;i<dims[0];i++)
596 const double *loc(inPtr+(kk+i)*nbCompo);
597 for(int ifact=0;ifact<fact0;ifact++)
598 outPtr=std::copy(loc,loc+nbCompo,outPtr);
607 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]);
608 for(int k=0;k<dims[2];k++)
610 for(int kfact=0;kfact<fact2;kfact++)
612 for(int j=0;j<dims[1];j++)
614 for(int jfact=0;jfact<fact1;jfact++)
616 for(int i=0;i<dims[0];i++)
618 const double *loc(inPtr+(kk+i+j*coarseSt[0])*nbCompo);
619 for(int ifact=0;ifact<fact0;ifact++)
620 outPtr=std::copy(loc,loc+nbCompo,outPtr);
625 kk+=coarseSt[0]*coarseSt[1];
630 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : only dimensions 1, 2 and 3 supported !");
635 * This method spreads the values of coarse data \a coarseDA into \a fineDA.
637 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
638 * \param [in] coarseSt The cell structure of coarse mesh.
639 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
640 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
641 * \param [in] facts The refinement coefficient per axis.
642 * \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.
644 * \sa CondenseFineToCoarse, SpreadCoarseToFineGhostZone
646 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)
649 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level has to be >= 0 !");
650 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
651 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !");
652 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
653 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !");
654 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
655 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
656 int nbCompo(fineDA->getNumberOfComponents());
657 if(coarseDA->getNumberOfComponents()!=nbCompo)
658 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the number of components of fine DA and coarse one mismatches !");
659 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
660 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) !");
661 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
663 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
664 throw INTERP_KERNEL::Exception(oss.str().c_str());
667 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
668 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
669 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
670 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
671 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
673 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
674 throw INTERP_KERNEL::Exception(oss.str().c_str());
677 double *outPtr(fineDA->getPointer());
678 const double *inPtr(coarseDA->begin());
684 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
685 int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
686 for(int i=0;i<ghostSize;i++)
687 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
688 offset=fineLocInCoarse[0].first+ghostSize;
689 for(int i=0;i<dims[0];i++)
691 const double *loc(inPtr+(offset+i)*nbCompo);
692 for(int ifact=0;ifact<fact0;ifact++)
693 outPtr=std::copy(loc,loc+nbCompo,outPtr);
695 offset=fineLocInCoarse[0].second+ghostSize;
696 for(int i=0;i<ghostSize;i++)
697 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
702 SpreadCoarseToFineGhost2D(inPtr,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
707 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
708 int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]);
709 int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize));
710 int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 !
711 for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
712 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
714 for(int i=0;i<dims[2];i++,offset+=nxyWgCoarse)
715 for(int j=0;j<fact2;j++,outPtr+=nxyWgFine*nbCompo)
716 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
717 for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
718 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
722 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : only dimensions 1, 2, 3 supported !");
727 * 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).
729 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
730 * \param [in] coarseSt The cell structure of coarse mesh.
731 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
732 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
733 * \param [in] facts The refinement coefficient per axis.
734 * \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.
736 * \sa SpreadCoarseToFineGhost
738 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)
741 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : ghost level has to be >= 0 !");
742 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
743 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : All input vectors (dimension) must have the same size !");
744 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
745 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the parameters 1 or 3 are NULL or not allocated !");
746 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
747 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
748 int nbCompo(fineDA->getNumberOfComponents());
749 if(coarseDA->getNumberOfComponents()!=nbCompo)
750 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the number of components of fine DA and coarse one mismatches !");
751 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
752 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) !");
753 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
755 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
756 throw INTERP_KERNEL::Exception(oss.str().c_str());
759 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
760 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
761 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
762 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
763 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
765 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
766 throw INTERP_KERNEL::Exception(oss.str().c_str());
769 double *outPtr(fineDA->getPointer());
770 const double *inPtr(coarseDA->begin());
772 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
777 int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
778 for(int i=0;i<ghostSize;i++)
779 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
780 outPtr+=nbCompo*fact0*dims[0];
781 offset=fineLocInCoarse[0].second+ghostSize;
782 for(int i=0;i<ghostSize;i++)
783 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
788 SpreadCoarseToFineGhostZone2D(inPtr,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
793 int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]);
794 int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize));
795 int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 !
796 for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
797 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
799 for(int i=0;i<dims[2];i++,offset+=nxyWgCoarse)
800 for(int j=0;j<fact2;j++,outPtr+=nxyWgFine*nbCompo)
801 SpreadCoarseToFineGhostZone2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
802 for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
803 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
807 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : only dimensions 1, 2, 3 supported !");
811 void MEDCouplingIMesh::setSpaceDimension(int spaceDim)
813 if(spaceDim==_space_dim)
815 CheckSpaceDimension(spaceDim);
820 void MEDCouplingIMesh::updateTime() const
824 std::size_t MEDCouplingIMesh::getHeapMemorySizeWithoutChildren() const
826 return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
829 std::vector<const BigMemoryObject *> MEDCouplingIMesh::getDirectChildrenWithNull() const
831 return std::vector<const BigMemoryObject *>();
835 * This method copyies all tiny strings from other (name and components name).
836 * @throw if other and this have not same mesh type.
838 void MEDCouplingIMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
840 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
842 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::copyTinyStringsFrom : meshes have not same type !");
843 MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
847 bool MEDCouplingIMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
850 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::isEqualIfNotWhy : input other pointer is null !");
851 const MEDCouplingIMesh *otherC(dynamic_cast<const MEDCouplingIMesh *>(other));
854 reason="mesh given in input is not castable in MEDCouplingIMesh !";
857 if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
859 if(!isEqualWithoutConsideringStrInternal(otherC,prec,reason))
861 if(_axis_unit!=otherC->_axis_unit)
863 reason="The units of axis are not the same !";
869 bool MEDCouplingIMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
871 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
875 return isEqualWithoutConsideringStrInternal(other,prec,tmp);
878 bool MEDCouplingIMesh::isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const
880 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
883 if(_space_dim!=otherC->_space_dim)
885 std::ostringstream oss;
886 oss << "The spaceDimension of this (" << _space_dim << ") is not equal to those of other (" << otherC->_space_dim << ") !";
889 checkSpaceDimension();
890 for(int i=0;i<_space_dim;i++)
892 if(fabs(_origin[i]-otherC->_origin[i])>prec)
894 std::ostringstream oss;
895 oss << "The origin of this and other differs at " << i << " !";
900 for(int i=0;i<_space_dim;i++)
902 if(fabs(_dxyz[i]-otherC->_dxyz[i])>prec)
904 std::ostringstream oss;
905 oss << "The delta of this and other differs at " << i << " !";
910 for(int i=0;i<_space_dim;i++)
912 if(_structure[i]!=otherC->_structure[i])
914 std::ostringstream oss;
915 oss << "The structure of this and other differs at " << i << " !";
923 void MEDCouplingIMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
924 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
926 if(!isEqualWithoutConsideringStr(other,prec))
927 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalWith : Meshes are not the same !");
931 * Nothing is done here (except to check that the other is a MEDCoupling::MEDCouplingIMesh instance too).
932 * The user intend that the nodes are the same, so by construction of MEDCoupling::MEDCouplingIMesh, \a this and \a other are the same !
934 void MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
935 DataArrayInt *&cellCor) const
937 if(!isEqualWithoutConsideringStr(other,prec))
938 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
941 void MEDCouplingIMesh::checkConsistencyLight() const
943 checkSpaceDimension();
944 for(int i=0;i<_space_dim;i++)
947 std::ostringstream oss; oss << "MEDCouplingIMesh::checkConsistencyLight : On axis " << i << "/" << _space_dim << ", number of nodes is equal to " << _structure[i] << " ! must be >=1 !";
948 throw INTERP_KERNEL::Exception(oss.str().c_str());
952 void MEDCouplingIMesh::checkConsistency(double eps) const
954 checkConsistencyLight();
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
972 checkConsistencyLight();
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 MCAuto<MEDCouplingIMesh> ret(dynamic_cast<MEDCouplingIMesh *>(deepCopy()));
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->checkConsistencyLight();
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
1052 checkConsistencyLight();
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
1082 checkConsistencyLight();
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
1177 checkConsistencyLight();
1178 MCAuto<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::computeCellCenterOfMass() const
1204 checkConsistencyLight();
1205 MCAuto<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::computeCellCenterOfMass();
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
1283 checkConsistencyLight();
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);