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 (EDF R&D)
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 deepCpy):MEDCouplingStructuredMesh(other,deepCpy),_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((int)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((int)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((int)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((int)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((int)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::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
1128 int ret(getCellContainingPoint(pos,eps));
1129 elts.push_back(ret);
1132 void MEDCouplingIMesh::rotate(const double *center, const double *vector, double angle)
1134 throw INTERP_KERNEL::Exception("No rotation available on IMesh : Traduce it to unstructured mesh to apply it !");
1138 * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
1139 * component of the \a vector to all node coordinates of a corresponding axis.
1140 * \param [in] vector - the translation vector whose size must be not less than \a
1141 * this->getSpaceDimension().
1143 void MEDCouplingIMesh::translate(const double *vector)
1145 checkSpaceDimension();
1146 int dim(getSpaceDimension());
1147 std::transform(_origin,_origin+dim,vector,_origin,std::plus<double>());
1152 * Applies scaling transformation to all nodes of \a this mesh.
1153 * \param [in] point - coordinates of a scaling center. This array is to be of
1154 * size \a this->getSpaceDimension() at least.
1155 * \param [in] factor - a scale factor.
1157 void MEDCouplingIMesh::scale(const double *point, double factor)
1159 checkSpaceDimension();
1160 int dim(getSpaceDimension());
1161 std::transform(_origin,_origin+dim,point,_origin,std::minus<double>());
1162 std::transform(_origin,_origin+dim,_origin,std::bind2nd(std::multiplies<double>(),factor));
1163 std::transform(_dxyz,_dxyz+dim,_dxyz,std::bind2nd(std::multiplies<double>(),factor));
1164 std::transform(_origin,_origin+dim,point,_origin,std::plus<double>());
1168 MEDCouplingMesh *MEDCouplingIMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
1170 //not implemented yet !
1175 * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
1176 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1177 * this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
1178 * components. The caller is to delete this array using decrRef() as it is
1181 DataArrayDouble *MEDCouplingIMesh::getCoordinatesAndOwner() const
1183 checkConsistencyLight();
1184 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1185 int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
1186 ret->alloc(nbNodes,spaceDim);
1187 double *pt(ret->getPointer());
1188 ret->setInfoOnComponents(buildInfoOnComponents());
1190 getSplitNodeValues(tmp);
1191 for(int i=0;i<nbNodes;i++)
1193 GetPosFromId(i,spaceDim,tmp,tmp2);
1194 for(int j=0;j<spaceDim;j++)
1195 pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+_origin[j];
1201 * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
1202 * computed by averaging coordinates of cell nodes.
1203 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1204 * this->getNumberOfCells() tuples per \a this->getSpaceDimension()
1205 * components. The caller is to delete this array using decrRef() as it is
1208 DataArrayDouble *MEDCouplingIMesh::computeCellCenterOfMass() const
1210 checkConsistencyLight();
1211 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1212 int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()),tmp[3],tmp2[3];
1213 ret->alloc(nbCells,spaceDim);
1214 double *pt(ret->getPointer()),shiftOrigin[3];
1215 std::transform(_dxyz,_dxyz+spaceDim,shiftOrigin,std::bind2nd(std::multiplies<double>(),0.5));
1216 std::transform(_origin,_origin+spaceDim,shiftOrigin,shiftOrigin,std::plus<double>());
1217 getSplitCellValues(tmp);
1218 ret->setInfoOnComponents(buildInfoOnComponents());
1219 for(int i=0;i<nbCells;i++)
1221 GetPosFromId(i,spaceDim,tmp,tmp2);
1222 for(int j=0;j<spaceDim;j++)
1223 pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+shiftOrigin[j];
1228 DataArrayDouble *MEDCouplingIMesh::computeIsoBarycenterOfNodesPerCell() const
1230 return MEDCouplingIMesh::computeCellCenterOfMass();
1233 void MEDCouplingIMesh::renumberCells(const int *old2NewBg, bool check)
1235 throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for IMesh !");
1238 void MEDCouplingIMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1241 double time(getTime(it,order));
1244 littleStrings.clear();
1245 littleStrings.push_back(getName());
1246 littleStrings.push_back(getDescription());
1247 littleStrings.push_back(getTimeUnit());
1248 littleStrings.push_back(getAxisUnit());
1249 tinyInfo.push_back(it);
1250 tinyInfo.push_back(order);
1251 tinyInfo.push_back(_space_dim);
1252 tinyInfo.insert(tinyInfo.end(),_structure,_structure+3);
1253 tinyInfoD.push_back(time);
1254 tinyInfoD.insert(tinyInfoD.end(),_dxyz,_dxyz+3);
1255 tinyInfoD.insert(tinyInfoD.end(),_origin,_origin+3);
1258 void MEDCouplingIMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1264 void MEDCouplingIMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1266 a1=DataArrayInt::New();
1268 a2=DataArrayDouble::New();
1272 void MEDCouplingIMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1273 const std::vector<std::string>& littleStrings)
1275 setName(littleStrings[0]);
1276 setDescription(littleStrings[1]);
1277 setTimeUnit(littleStrings[2]);
1278 setAxisUnit(littleStrings[3]);
1279 setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]);
1280 _space_dim=tinyInfo[2];
1281 _structure[0]=tinyInfo[3]; _structure[1]=tinyInfo[4]; _structure[2]=tinyInfo[5];
1282 _dxyz[0]=tinyInfoD[1]; _dxyz[1]=tinyInfoD[2]; _dxyz[2]=tinyInfoD[3];
1283 _origin[0]=tinyInfoD[4]; _origin[1]=tinyInfoD[5]; _origin[2]=tinyInfoD[6];
1287 void MEDCouplingIMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
1289 checkConsistencyLight();
1290 std::ostringstream extent,origin,spacing;
1291 for(int i=0;i<3;i++)
1294 { extent << "0 " << _structure[i]-1 << " "; origin << _origin[i] << " "; spacing << _dxyz[i] << " "; }
1296 { extent << "0 0 "; origin << "0 "; spacing << "0 "; }
1298 ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\" Origin=\"" << origin.str() << "\" Spacing=\"" << spacing.str() << "\">\n";
1299 ofs << " <Piece Extent=\"" << extent.str() << "\">\n";
1300 ofs << " <PointData>\n" << pointData << std::endl;
1301 ofs << " </PointData>\n";
1302 ofs << " <CellData>\n" << cellData << std::endl;
1303 ofs << " </CellData>\n";
1304 ofs << " <Coordinates>\n";
1305 ofs << " </Coordinates>\n";
1306 ofs << " </Piece>\n";
1307 ofs << " </" << getVTKDataSetType() << ">\n";
1310 void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const
1312 stream << "MEDCouplingIMesh C++ instance at " << this << ". Name : \"" << getName() << "\". Space dimension : " << _space_dim << ".";
1313 if(_space_dim<0 || _space_dim>3)
1316 std::ostringstream stream0,stream1;
1317 int nbNodes(1),nbCells(0);
1319 for(int i=0;i<_space_dim;i++)
1322 int tmpNodes(_structure[i]);
1323 stream1 << "- Axis " << tmp << " : " << tmpNodes << " nodes (orig=" << _origin[i] << ", inter=" << _dxyz[i] << ").";
1325 stream1 << std::endl;
1331 nbCells=nbCells==0?tmpNodes-1:nbCells*(tmpNodes-1);
1335 stream0 << "Number of cells : " << nbCells << ", Number of nodes : " << nbNodes;
1336 stream << stream0.str();
1338 stream << std::endl;
1340 stream << stream1.str();
1343 std::string MEDCouplingIMesh::getVTKFileExtension() const
1345 return std::string("vti");
1348 std::string MEDCouplingIMesh::getVTKDataSetType() const
1350 return std::string("ImageData");
1353 std::vector<std::string> MEDCouplingIMesh::buildInfoOnComponents() const
1355 checkSpaceDimension();
1356 int dim(getSpaceDimension());
1357 std::vector<std::string> ret(dim);
1358 for(int i=0;i<dim;i++)
1360 std::ostringstream oss;
1361 char tmp('X'+i); oss << tmp;
1362 ret[i]=DataArray::BuildInfoFromVarAndUnit(oss.str(),_axis_unit);
1367 void MEDCouplingIMesh::checkSpaceDimension() const
1369 CheckSpaceDimension(_space_dim);
1372 void MEDCouplingIMesh::CheckSpaceDimension(int spaceDim)
1374 if(spaceDim<0 || spaceDim>3)
1375 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CheckSpaceDimension : input spaceDim must be in [0,1,2,3] !");
1378 int MEDCouplingIMesh::FindIntRoot(int val, int order)
1383 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : input val is < 0 ! Not possible to compute a root !");
1386 if(order!=2 && order!=3)
1387 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the order available are 0,1,2 or 3 !");
1388 double valf((double)val);
1391 double retf(sqrt(valf));
1394 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect square root !");
1399 double retf(std::pow(val,0.3333333333333333));
1400 int ret((int)retf),ret2(ret+1);
1401 if(ret*ret*ret!=val && ret2*ret2*ret2!=val)
1402 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect cublic root !");
1403 if(ret*ret*ret==val)
1410 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)
1412 double *outPtrWork(outPtr);
1413 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
1414 int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
1415 int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
1416 for(int jg=0;jg<ghostSize;jg++)
1418 for(int ig=0;ig<ghostSize;ig++)
1419 outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1421 for(int ig=0;ig<dims[0];ig++,kk0++)
1422 for(int ifact=0;ifact<fact0;ifact++)
1423 outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1424 for(int ik=0;ik<ghostSize;ik++)
1425 outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1427 for(int j=0;j<dims[1];j++)
1429 kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
1430 for(int jfact=0;jfact<fact1;jfact++)
1432 for(int ig=0;ig<ghostSize;ig++)
1433 outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1434 int kk0(kk+1);//1 not ghost. We make the hypothesis that factors is >= ghostlev
1435 for(int i=0;i<dims[0];i++,kk0++)
1437 const double *loc(inPtr+kk0*nbCompo);
1438 for(int ifact=0;ifact<fact0;ifact++)
1439 outPtrWork=std::copy(loc,loc+nbCompo,outPtrWork);
1441 for(int ig=0;ig<ghostSize;ig++)
1442 outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1445 kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
1446 for(int jg=0;jg<ghostSize;jg++)
1448 for(int ig=0;ig<ghostSize;ig++)
1449 outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1451 for(int ig=0;ig<dims[0];ig++,kk0++)
1452 for(int ifact=0;ifact<fact0;ifact++)
1453 outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1454 for(int ik=0;ik<ghostSize;ik++)
1455 outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1459 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)
1461 double *outPtr2(outPtr);
1462 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
1463 int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
1464 int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
1465 for(int jg=0;jg<ghostSize;jg++)
1467 for(int ig=0;ig<ghostSize;ig++)
1468 outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2);
1470 for(int ig=0;ig<dims[0];ig++,kk0++)
1471 for(int ifact=0;ifact<fact0;ifact++)
1472 outPtr2=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
1473 for(int ik=0;ik<ghostSize;ik++)
1474 outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
1476 for(int j=0;j<dims[1];j++)
1478 kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
1479 for(int jfact=0;jfact<fact1;jfact++)
1481 for(int ig=0;ig<ghostSize;ig++)
1482 outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2);
1483 int kk0(kk+1+dims[0]);//1 not ghost. We make the hypothesis that factors is >= ghostlev
1484 outPtr2+=fact0*nbCompo*dims[0];
1485 for(int ig=0;ig<ghostSize;ig++)
1486 outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
1489 kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
1490 for(int jg=0;jg<ghostSize;jg++)
1492 for(int ig=0;ig<ghostSize;ig++)
1493 outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2);
1495 for(int ig=0;ig<dims[0];ig++,kk0++)
1496 for(int ifact=0;ifact<fact0;ifact++)
1497 outPtr2=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);
1498 for(int ik=0;ik<ghostSize;ik++)
1499 outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2);