1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCouplingIMesh.hxx"
22 #include "MEDCouplingCMesh.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingFieldDouble.hxx"
31 using namespace ParaMEDMEM;
33 MEDCouplingIMesh::MEDCouplingIMesh():_space_dim(-1)
35 _origin[0]=0.; _origin[1]=0.; _origin[2]=0.;
36 _dxyz[0]=0.; _dxyz[1]=0.; _dxyz[2]=0.;
37 _structure[0]=0; _structure[1]=0; _structure[2]=0;
40 MEDCouplingIMesh::MEDCouplingIMesh(const MEDCouplingIMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy),_space_dim(other._space_dim),_axis_unit(other._axis_unit)
42 _origin[0]=other._origin[0]; _origin[1]=other._origin[1]; _origin[2]=other._origin[2];
43 _dxyz[0]=other._dxyz[0]; _dxyz[1]=other._dxyz[1]; _dxyz[2]=other._dxyz[2];
44 _structure[0]=other._structure[0]; _structure[1]=other._structure[1]; _structure[2]=other._structure[2];
47 MEDCouplingIMesh::~MEDCouplingIMesh()
51 MEDCouplingIMesh *MEDCouplingIMesh::New()
53 return new MEDCouplingIMesh;
56 MEDCouplingIMesh *MEDCouplingIMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
57 const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop)
59 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(new MEDCouplingIMesh);
60 ret->setName(meshName);
61 ret->setSpaceDimension(spaceDim);
62 ret->setNodeStruct(nodeStrctStart,nodeStrctStop);
63 ret->setOrigin(originStart,originStop);
64 ret->setDXYZ(dxyzStart,dxyzStop);
68 MEDCouplingMesh *MEDCouplingIMesh::deepCpy() const
73 MEDCouplingIMesh *MEDCouplingIMesh::clone(bool recDeepCpy) const
75 return new MEDCouplingIMesh(*this,recDeepCpy);
79 * This method creates a copy of \a this enlarged by \a ghostLev cells on each axis.
80 * If \a ghostLev equal to 0 this method behaves as MEDCouplingIMesh::clone.
82 * \param [in] ghostLev - the ghost level expected
83 * \return MEDCouplingIMesh * - a newly alloacted object to be managed by the caller.
84 * \throw if \a ghostLev < 0.
86 MEDCouplingIMesh *MEDCouplingIMesh::buildWithGhost(int ghostLev) const
89 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::buildWithGhost : the ghostLev must be >= 0 !");
91 int spaceDim(getSpaceDimension());
92 double origin[3],dxyz[3];
94 for(int i=0;i<spaceDim;i++)
96 origin[i]=_origin[i]-ghostLev*_dxyz[i];
98 structure[i]=_structure[i]+2*ghostLev;
100 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),spaceDim,structure,structure+spaceDim,origin,origin+spaceDim,dxyz,dxyz+spaceDim));
101 ret->copyTinyInfoFrom(this);
105 void MEDCouplingIMesh::setNodeStruct(const int *nodeStrctStart, const int *nodeStrctStop)
107 checkSpaceDimension();
108 int sz((int)std::distance(nodeStrctStart,nodeStrctStop));
110 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setNodeStruct : input vector of node structure has not the right size ! Or change space dimension before calling it !");
111 std::copy(nodeStrctStart,nodeStrctStop,_structure);
115 std::vector<int> MEDCouplingIMesh::getNodeStruct() const
117 checkSpaceDimension();
118 return std::vector<int>(_structure,_structure+_space_dim);
121 void MEDCouplingIMesh::setOrigin(const double *originStart, const double *originStop)
123 checkSpaceDimension();
124 int sz((int)std::distance(originStart,originStop));
126 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setOrigin : input vector of origin vector has not the right size ! Or change space dimension before calling it !");
127 std::copy(originStart,originStop,_origin);
131 std::vector<double> MEDCouplingIMesh::getOrigin() const
133 checkSpaceDimension();
134 return std::vector<double>(_origin,_origin+_space_dim);
137 void MEDCouplingIMesh::setDXYZ(const double *dxyzStart, const double *dxyzStop)
139 checkSpaceDimension();
140 int sz((int)std::distance(dxyzStart,dxyzStop));
142 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setDXYZ : input vector of dxyz vector has not the right size ! Or change space dimension before calling it !");
143 std::copy(dxyzStart,dxyzStop,_dxyz);
147 std::vector<double> MEDCouplingIMesh::getDXYZ() const
149 checkSpaceDimension();
150 return std::vector<double>(_dxyz,_dxyz+_space_dim);
153 void MEDCouplingIMesh::setAxisUnit(const std::string& unitName)
159 std::string MEDCouplingIMesh::getAxisUnit() const
165 * This method returns the measure of any cell in \a this.
166 * This specific method of image grid mesh utilizes the fact that any cell in \a this have the same measure.
167 * The value returned by this method is those used to feed the returned field in the MEDCouplingIMesh::getMeasureField.
169 * \sa getMeasureField
171 double MEDCouplingIMesh::getMeasureOfAnyCell() const
174 int dim(getSpaceDimension());
176 for(int i=0;i<dim;i++)
182 * This method is allows to convert \a this into MEDCouplingCMesh instance.
183 * This method is the middle level between MEDCouplingIMesh and the most general MEDCouplingUMesh.
184 * This method is useful for MED writers that do not have still the image grid support.
186 * \sa MEDCouplingMesh::buildUnstructured
188 MEDCouplingCMesh *MEDCouplingIMesh::convertToCartesian() const
191 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> ret(MEDCouplingCMesh::New());
193 { ret->copyTinyInfoFrom(this); }
194 catch(INTERP_KERNEL::Exception& ) { }
195 int spaceDim(getSpaceDimension());
196 std::vector<std::string> infos(buildInfoOnComponents());
197 for(int i=0;i<spaceDim;i++)
199 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(DataArrayDouble::New()); arr->alloc(_structure[i],1); arr->setInfoOnComponent(0,infos[i]);
200 arr->iota(); arr->applyLin(_dxyz[i],_origin[i]);
201 ret->setCoordsAt(i,arr);
207 * This method refines \a this uniformaly along all of its dimensions. In case of success the space covered by \a this will remain
208 * the same before the invocation except that the number of cells will be multiplied by \a factor ^ this->getMeshDimension().
209 * The origin of \a this will be not touched only spacing and node structure will be changed.
210 * This method can be useful for AMR users.
212 void MEDCouplingIMesh::refineWithFactor(const std::vector<int>& factors)
214 if((int)factors.size()!=_space_dim)
215 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::refineWithFactor : refinement factors must have size equal to spaceDim !");
217 std::vector<int> structure(_structure,_structure+3);
218 std::vector<double> dxyz(_dxyz,_dxyz+3);
219 for(int i=0;i<_space_dim;i++)
223 std::ostringstream oss; oss << "MEDCouplingIMesh::refineWithFactor : factor for axis #" << i << " (" << factors[i] << ")is invalid ! Must be > 0 !";
224 throw INTERP_KERNEL::Exception(oss.str().c_str());
226 int factAbs(std::abs(factors[i]));
227 double fact2(1./(double)factors[i]);
228 structure[i]=(_structure[i]-1)*factAbs+1;
229 dxyz[i]=fact2*_dxyz[i];
231 std::copy(structure.begin(),structure.end(),_structure);
232 std::copy(dxyz.begin(),dxyz.end(),_dxyz);
237 * This method returns a newly created mesh containing a single cell in it. This returned cell covers exactly the space covered by \a this.
239 * \return MEDCouplingIMesh * - A newly created object (to be managed by the caller with decrRef) containing simply one cell.
241 * \throw if \a this does not pass the \c checkCoherency test.
243 MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const
246 int spaceDim(getSpaceDimension()),nodeSt[3];
248 for(int i=0;i<spaceDim;i++)
253 dxyz[i]=(_structure[i]-1)*_dxyz[i];
257 nodeSt[i]=_structure[i];
261 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),getSpaceDimension(),nodeSt,nodeSt+spaceDim,_origin,_origin+spaceDim,dxyz,dxyz+spaceDim));
262 ret->copyTinyInfoFrom(this);
267 * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example)
268 * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh
269 * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged.
271 * \param [in] coarseSt The cell structure of coarse mesh.
272 * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh
273 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
274 * \param [in] facts The refinement coefficient per axis.
275 * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
277 * \sa CondenseFineToCoarseGhost,SpreadCoarseToFine
279 void MEDCouplingIMesh::CondenseFineToCoarse(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA)
281 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
282 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : All input vectors (dimension) must have the same size !");
283 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
284 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the parameters 1 or 3 are NULL or not allocated !");
285 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
286 int nbCompo(fineDA->getNumberOfComponents());
287 if(coarseDA->getNumberOfComponents()!=nbCompo)
288 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the number of components of fine DA and coarse one mismatches !");
289 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
290 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
291 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
293 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
294 throw INTERP_KERNEL::Exception(oss.str().c_str());
296 int nbTuplesFine(fineDA->getNumberOfTuples());
297 if(nbOfTuplesInFineExp==0)
302 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Nothing to condense considering the range specified ! But DataArray is not empty !");
304 if(nbTuplesFine%nbOfTuplesInFineExp!=0)
305 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Invalid nb of tuples in fine DataArray regarding its structure !");
306 int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
307 if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
309 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
310 throw INTERP_KERNEL::Exception(oss.str().c_str());
312 // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
313 double *outPtr(coarseDA->getPointer());
314 const double *inPtr(fineDA->begin());
316 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
321 int offset(fineLocInCoarse[0].first),fact0(facts[0]);
322 for(int i=0;i<dims[0];i++)
324 double *loc(outPtr+(offset+i)*nbCompo);
325 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
328 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
330 std::copy(inPtr,inPtr+nbCompo,loc);
337 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact1(facts[1]),fact0(facts[0]);
338 for(int j=0;j<dims[1];j++)
340 for(int jfact=0;jfact<fact1;jfact++)
342 for(int i=0;i<dims[0];i++)
344 double *loc(outPtr+(kk+i)*nbCompo);
345 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
347 if(jfact!=0 || ifact!=0)
348 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
350 std::copy(inPtr,inPtr+nbCompo,loc);
360 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first+coarseSt[0]*coarseSt[1]*fineLocInCoarse[2].first),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]);
361 for(int k=0;k<dims[2];k++)
363 for(int kfact=0;kfact<fact2;kfact++)
365 for(int j=0;j<dims[1];j++)
367 for(int jfact=0;jfact<fact1;jfact++)
369 for(int i=0;i<dims[0];i++)
371 double *loc(outPtr+(kk+i+j*coarseSt[0])*nbCompo);
372 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
374 if(kfact!=0 || jfact!=0 || ifact!=0)
375 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
377 std::copy(inPtr,inPtr+nbCompo,loc);
383 kk+=coarseSt[0]*coarseSt[1];
388 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : only dimensions 1, 2 and 3 supported !");
393 * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example)
394 * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh
395 * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged.
397 * \param [in] coarseSt The cell structure of coarse mesh.
398 * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh
399 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
400 * \param [in] facts The refinement coefficient per axis.
401 * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
402 * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
404 * \sa CondenseFineToCoarse,SpreadCoarseToFineGhost
406 void MEDCouplingIMesh::CondenseFineToCoarseGhost(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA, int ghostSize)
409 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : ghost level has to be >= 0 !");
410 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
411 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : All input vectors (dimension) must have the same size !");
412 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
413 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the parameters 1 or 3 are NULL or not allocated !");
414 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
415 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
416 int nbCompo(fineDA->getNumberOfComponents());
417 if(coarseDA->getNumberOfComponents()!=nbCompo)
418 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the number of components of fine DA and coarse one mismatches !");
419 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
420 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
421 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
423 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples in coarse DataArray having " << coarseDA->getNumberOfTuples() << " !";
424 throw INTERP_KERNEL::Exception(oss.str().c_str());
427 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
428 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
429 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
430 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
431 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
433 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
434 throw INTERP_KERNEL::Exception(oss.str().c_str());
437 double *outPtr(coarseDA->getPointer());
438 const double *inPtr(fineDA->begin());
440 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
445 int offset(fineLocInCoarse[0].first+ghostSize),fact0(facts[0]);
446 inPtr+=ghostSize*nbCompo;
447 for(int i=0;i<dims[0];i++)
449 double *loc(outPtr+(offset+i)*nbCompo);
450 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
453 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
455 std::copy(inPtr,inPtr+nbCompo,loc);
462 int nxwg(coarseSt[0]+2*ghostSize);
463 int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)),fact1(facts[1]),fact0(facts[0]);
464 inPtr+=(dims[0]*fact0+2*ghostSize)*ghostSize*nbCompo;
465 for(int j=0;j<dims[1];j++)
467 for(int jfact=0;jfact<fact1;jfact++)
469 inPtr+=ghostSize*nbCompo;
470 for(int i=0;i<dims[0];i++)
472 double *loc(outPtr+(kk+i)*nbCompo);
473 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
475 if(jfact!=0 || ifact!=0)
476 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
478 std::copy(inPtr,inPtr+nbCompo,loc);
481 inPtr+=ghostSize*nbCompo;
489 int nxwg(coarseSt[0]+2*ghostSize),nxywg((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize));
490 int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)+nxywg*(fineLocInCoarse[2].first+ghostSize)),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]);
491 inPtr+=(dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)*ghostSize*nbCompo;
492 for(int k=0;k<dims[2];k++)
494 for(int kfact=0;kfact<fact2;kfact++)
496 inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo;
497 for(int j=0;j<dims[1];j++)
500 for(int jfact=0;jfact<fact1;jfact++)
502 inPtr+=ghostSize*nbCompo;
503 for(int i=0;i<dims[0];i++)
505 double *loc(outPtr+(kky+kk+i)*nbCompo);
506 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
508 if(kfact!=0 || jfact!=0 || ifact!=0)
509 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
511 std::copy(inPtr,inPtr+nbCompo,loc);
514 inPtr+=ghostSize*nbCompo;
517 inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo;
524 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2, 3 supported !");
529 * This method spreads the values of coarse data \a coarseDA into \a fineDA.
531 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
532 * \param [in] coarseSt The cell structure of coarse mesh.
533 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
534 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
535 * \param [in] facts The refinement coefficient per axis.
536 * \sa SpreadCoarseToFineGhost, CondenseFineToCoarse
538 void MEDCouplingIMesh::SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts)
540 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
541 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !");
542 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
543 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !");
544 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
545 int nbCompo(fineDA->getNumberOfComponents());
546 if(coarseDA->getNumberOfComponents()!=nbCompo)
547 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the number of components of fine DA and coarse one mismatches !");
548 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
549 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
550 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
552 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
553 throw INTERP_KERNEL::Exception(oss.str().c_str());
555 int nbTuplesFine(fineDA->getNumberOfTuples());
556 if(nbTuplesFine%nbOfTuplesInFineExp!=0)
557 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : Invalid nb of tuples in fine DataArray regarding its structure !");
558 int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
559 if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
561 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
562 throw INTERP_KERNEL::Exception(oss.str().c_str());
564 // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
565 double *outPtr(fineDA->getPointer());
566 const double *inPtr(coarseDA->begin());
568 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
573 int offset(fineLocInCoarse[0].first),fact0(facts[0]);
574 for(int i=0;i<dims[0];i++)
576 const double *loc(inPtr+(offset+i)*nbCompo);
577 for(int ifact=0;ifact<fact0;ifact++)
578 outPtr=std::copy(loc,loc+nbCompo,outPtr);
584 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact0(facts[0]),fact1(facts[1]);
585 for(int j=0;j<dims[1];j++)
587 for(int jfact=0;jfact<fact1;jfact++)
589 for(int i=0;i<dims[0];i++)
591 const double *loc(inPtr+(kk+i)*nbCompo);
592 for(int ifact=0;ifact<fact0;ifact++)
593 outPtr=std::copy(loc,loc+nbCompo,outPtr);
602 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first+coarseSt[0]*coarseSt[1]*fineLocInCoarse[2].first),fact0(facts[0]),fact1(facts[2]),fact2(facts[2]);
603 for(int k=0;k<dims[2];k++)
605 for(int kfact=0;kfact<fact2;kfact++)
607 for(int j=0;j<dims[1];j++)
609 for(int jfact=0;jfact<fact1;jfact++)
611 for(int i=0;i<dims[0];i++)
613 const double *loc(inPtr+(kk+i+j*coarseSt[0])*nbCompo);
614 for(int ifact=0;ifact<fact0;ifact++)
615 outPtr=std::copy(loc,loc+nbCompo,outPtr);
620 kk+=coarseSt[0]*coarseSt[1];
625 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : only dimensions 1, 2 and 3 supported !");
630 * This method spreads the values of coarse data \a coarseDA into \a fineDA.
632 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
633 * \param [in] coarseSt The cell structure of coarse mesh.
634 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
635 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
636 * \param [in] facts The refinement coefficient per axis.
637 * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
639 * \sa CondenseFineToCoarse, SpreadCoarseToFineGhostZone
641 void MEDCouplingIMesh::SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
644 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level has to be >= 0 !");
645 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
646 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !");
647 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
648 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !");
649 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
650 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
651 int nbCompo(fineDA->getNumberOfComponents());
652 if(coarseDA->getNumberOfComponents()!=nbCompo)
653 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the number of components of fine DA and coarse one mismatches !");
654 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
655 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
656 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
658 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
659 throw INTERP_KERNEL::Exception(oss.str().c_str());
662 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
663 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
664 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
665 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
666 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
668 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
669 throw INTERP_KERNEL::Exception(oss.str().c_str());
672 double *outPtr(fineDA->getPointer());
673 const double *inPtr(coarseDA->begin());
679 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
680 int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
681 for(int i=0;i<ghostSize;i++)
682 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
683 offset=fineLocInCoarse[0].first+ghostSize;
684 for(int i=0;i<dims[0];i++)
686 const double *loc(inPtr+(offset+i)*nbCompo);
687 for(int ifact=0;ifact<fact0;ifact++)
688 outPtr=std::copy(loc,loc+nbCompo,outPtr);
690 offset=fineLocInCoarse[0].second+ghostSize;
691 for(int i=0;i<ghostSize;i++)
692 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
697 SpreadCoarseToFineGhost2D(inPtr,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
702 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
703 int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]);
704 int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize));
705 int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 !
706 for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
707 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
709 for(int i=0;i<dims[2];i++,offset+=nxyWgCoarse)
710 for(int j=0;j<fact2;j++,outPtr+=nxyWgFine*nbCompo)
711 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
712 for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
713 SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
717 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : only dimensions 1, 2, 3 supported !");
722 * This method spreads the values of coarse data \a coarseDA into \a fineDA \b ONLY \b in \b the \b ghost \b zone (contrary to SpreadCoarseToFineGhost that spread the values everywhere).
724 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
725 * \param [in] coarseSt The cell structure of coarse mesh.
726 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
727 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
728 * \param [in] facts The refinement coefficient per axis.
729 * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
731 * \sa SpreadCoarseToFineGhost
733 void MEDCouplingIMesh::SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
736 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : ghost level has to be >= 0 !");
737 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
738 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : All input vectors (dimension) must have the same size !");
739 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
740 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the parameters 1 or 3 are NULL or not allocated !");
741 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
742 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
743 int nbCompo(fineDA->getNumberOfComponents());
744 if(coarseDA->getNumberOfComponents()!=nbCompo)
745 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the number of components of fine DA and coarse one mismatches !");
746 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
747 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
748 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
750 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
751 throw INTERP_KERNEL::Exception(oss.str().c_str());
754 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
755 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
756 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
757 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
758 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
760 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
761 throw INTERP_KERNEL::Exception(oss.str().c_str());
764 double *outPtr(fineDA->getPointer());
765 const double *inPtr(coarseDA->begin());
767 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
772 int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
773 for(int i=0;i<ghostSize;i++)
774 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
775 outPtr+=nbCompo*fact0*dims[0];
776 offset=fineLocInCoarse[0].second+ghostSize;
777 for(int i=0;i<ghostSize;i++)
778 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
783 int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
784 int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
785 for(int jg=0;jg<ghostSize;jg++)
787 for(int ig=0;ig<ghostSize;ig++)
788 outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
790 for(int ig=0;ig<dims[0];ig++,kk0++)
791 for(int ifact=0;ifact<fact0;ifact++)
792 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
793 for(int ik=0;ik<ghostSize;ik++)
794 outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
796 for(int j=0;j<dims[1];j++)
798 kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
799 for(int jfact=0;jfact<fact1;jfact++)
801 for(int ig=0;ig<ghostSize;ig++)
802 outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
803 int kk0(kk+1+dims[0]);//1 not ghost. We make the hypothesis that factors is >= ghostlev
804 outPtr+=fact0*nbCompo*dims[0];
805 for(int ig=0;ig<ghostSize;ig++)
806 outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
809 kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
810 for(int jg=0;jg<ghostSize;jg++)
812 for(int ig=0;ig<ghostSize;ig++)
813 outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
815 for(int ig=0;ig<dims[0];ig++,kk0++)
816 for(int ifact=0;ifact<fact0;ifact++)
817 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
818 for(int ik=0;ik<ghostSize;ik++)
819 outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
824 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : only dimensions 1, 2 supported !");
828 void MEDCouplingIMesh::setSpaceDimension(int spaceDim)
830 if(spaceDim==_space_dim)
832 CheckSpaceDimension(spaceDim);
837 void MEDCouplingIMesh::updateTime() const
841 std::size_t MEDCouplingIMesh::getHeapMemorySizeWithoutChildren() const
843 return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
846 std::vector<const BigMemoryObject *> MEDCouplingIMesh::getDirectChildren() const
848 return std::vector<const BigMemoryObject *>();
852 * This method copyies all tiny strings from other (name and components name).
853 * @throw if other and this have not same mesh type.
855 void MEDCouplingIMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
857 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
859 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::copyTinyStringsFrom : meshes have not same type !");
860 MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
864 bool MEDCouplingIMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
867 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::isEqualIfNotWhy : input other pointer is null !");
868 const MEDCouplingIMesh *otherC(dynamic_cast<const MEDCouplingIMesh *>(other));
871 reason="mesh given in input is not castable in MEDCouplingIMesh !";
874 if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
876 if(!isEqualWithoutConsideringStrInternal(otherC,prec,reason))
878 if(_axis_unit!=otherC->_axis_unit)
880 reason="The units of axis are not the same !";
886 bool MEDCouplingIMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
888 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
892 return isEqualWithoutConsideringStrInternal(other,prec,tmp);
895 bool MEDCouplingIMesh::isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const
897 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
900 if(_space_dim!=otherC->_space_dim)
902 std::ostringstream oss;
903 oss << "The spaceDimension of this (" << _space_dim << ") is not equal to those of other (" << otherC->_space_dim << ") !";
906 checkSpaceDimension();
907 for(int i=0;i<_space_dim;i++)
909 if(fabs(_origin[i]-otherC->_origin[i])>prec)
911 std::ostringstream oss;
912 oss << "The origin of this and other differs at " << i << " !";
917 for(int i=0;i<_space_dim;i++)
919 if(fabs(_dxyz[i]-otherC->_dxyz[i])>prec)
921 std::ostringstream oss;
922 oss << "The delta of this and other differs at " << i << " !";
927 for(int i=0;i<_space_dim;i++)
929 if(_structure[i]!=otherC->_structure[i])
931 std::ostringstream oss;
932 oss << "The structure of this and other differs at " << i << " !";
940 void MEDCouplingIMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
941 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
943 if(!isEqualWithoutConsideringStr(other,prec))
944 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalWith : Meshes are not the same !");
948 * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingIMesh instance too).
949 * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingIMesh, \a this and \a other are the same !
951 void MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
952 DataArrayInt *&cellCor) const
954 if(!isEqualWithoutConsideringStr(other,prec))
955 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
958 void MEDCouplingIMesh::checkCoherency() const
960 checkSpaceDimension();
961 for(int i=0;i<_space_dim;i++)
964 std::ostringstream oss; oss << "MEDCouplingIMesh::checkCoherency : On axis " << i << "/" << _space_dim << ", number of nodes is equal to " << _structure[i] << " ! must be >=1 !";
965 throw INTERP_KERNEL::Exception(oss.str().c_str());
969 void MEDCouplingIMesh::checkCoherency1(double eps) const
974 void MEDCouplingIMesh::checkCoherency2(double eps) const
976 checkCoherency1(eps);
979 void MEDCouplingIMesh::getNodeGridStructure(int *res) const
981 checkSpaceDimension();
982 std::copy(_structure,_structure+_space_dim,res);
985 std::vector<int> MEDCouplingIMesh::getNodeGridStructure() const
987 checkSpaceDimension();
988 std::vector<int> ret(_structure,_structure+_space_dim);
992 MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
995 int dim(getSpaceDimension());
996 if(dim!=(int)cellPart.size())
998 std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !";
999 throw INTERP_KERNEL::Exception(oss.str().c_str());
1001 double retOrigin[3]={0.,0.,0.};
1002 int retStruct[3]={0,0,0};
1003 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(dynamic_cast<MEDCouplingIMesh *>(deepCpy()));
1004 for(int i=0;i<dim;i++)
1006 int startNode(cellPart[i].first),endNode(cellPart[i].second+1);
1007 int myDelta(endNode-startNode);
1008 if(startNode<0 || startNode>=_structure[i])
1010 std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : At dimension #" << i << " the start node id is " << startNode << " it should be in [0," << _structure[i] << ") !";
1011 throw INTERP_KERNEL::Exception(oss.str().c_str());
1013 if(myDelta<0 || myDelta>_structure[i])
1015 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;
1016 throw INTERP_KERNEL::Exception(oss.str().c_str());
1018 retOrigin[i]=_origin[i]+startNode*_dxyz[i];
1019 retStruct[i]=myDelta;
1021 ret->setNodeStruct(retStruct,retStruct+dim);
1022 ret->setOrigin(retOrigin,retOrigin+dim);
1023 ret->checkCoherency();
1028 * Return the space dimension of \a this.
1030 int MEDCouplingIMesh::getSpaceDimension() const
1035 void MEDCouplingIMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
1038 int spaceDim(getSpaceDimension());
1039 getSplitNodeValues(tmp);
1041 GetPosFromId(nodeId,spaceDim,tmp,tmp2);
1042 for(int j=0;j<spaceDim;j++)
1043 coo.push_back(_origin[j]+_dxyz[j]*tmp2[j]);
1046 std::string MEDCouplingIMesh::simpleRepr() const
1048 std::ostringstream ret;
1049 ret << "Image grid with name : \"" << getName() << "\"\n";
1050 ret << "Description of mesh : \"" << getDescription() << "\"\n";
1052 double tt(getTime(tmpp1,tmpp2));
1053 int spaceDim(_space_dim);
1054 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
1055 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
1056 ret << "Space dimension : " << spaceDim << "\n";
1057 if(spaceDim<0 || spaceDim>3)
1059 ret << "The nodal structure is : "; std::copy(_structure,_structure+spaceDim,std::ostream_iterator<int>(ret," ")); ret << "\n";
1060 ret << "The origin position is [" << _axis_unit << "]: ";
1061 std::copy(_origin,_origin+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
1062 ret << "The intervals along axis are : ";
1063 std::copy(_dxyz,_dxyz+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
1067 std::string MEDCouplingIMesh::advancedRepr() const
1069 return simpleRepr();
1072 void MEDCouplingIMesh::getBoundingBox(double *bbox) const
1075 int dim(getSpaceDimension());
1076 for(int idim=0; idim<dim; idim++)
1078 bbox[2*idim]=_origin[idim];
1079 int coeff(_structure[idim]);
1080 if(_structure[idim]<0)
1082 std::ostringstream oss; oss << "MEDCouplingIMesh::getBoundingBox : on axis #" << idim << " number of nodes in structure is < 0 !";
1083 throw INTERP_KERNEL::Exception(oss.str().c_str());
1085 if(_structure[idim]>1)
1086 coeff=_structure[idim]-1;
1087 bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*coeff;
1092 * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
1094 * For 1D cells, the returned field contains lengths.<br>
1095 * For 2D cells, the returned field contains areas.<br>
1096 * For 3D cells, the returned field contains volumes.
1097 * \param [in] isAbs - a not used parameter.
1098 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
1099 * and one time . The caller is to delete this field using decrRef() as it is no
1102 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureField(bool isAbs) const
1105 std::string name="MeasureOfMesh_";
1107 int nbelem(getNumberOfCells());
1108 MEDCouplingFieldDouble *field(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
1109 field->setName(name);
1110 DataArrayDouble* array(DataArrayDouble::New());
1111 array->alloc(nbelem,1);
1112 array->fillWithValue(getMeasureOfAnyCell());
1113 field->setArray(array) ;
1115 field->setMesh(const_cast<MEDCouplingIMesh *>(this));
1116 field->synchronizeTimeWithMesh();
1121 * not implemented yet !
1123 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureFieldOnNode(bool isAbs) const
1125 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::getMeasureFieldOnNode : not implemented yet !");
1129 int MEDCouplingIMesh::getCellContainingPoint(const double *pos, double eps) const
1131 int dim(getSpaceDimension()),ret(0),coeff(1);
1132 for(int i=0;i<dim;i++)
1134 int nbOfCells(_structure[i]-1);
1136 int tmp((int)((ref-_origin[i])/_dxyz[i]));
1137 if(tmp>=0 && tmp<nbOfCells)
1148 void MEDCouplingIMesh::rotate(const double *center, const double *vector, double angle)
1150 throw INTERP_KERNEL::Exception("No rotation available on IMesh : Traduce it to unstructured mesh to apply it !");
1154 * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
1155 * component of the \a vector to all node coordinates of a corresponding axis.
1156 * \param [in] vector - the translation vector whose size must be not less than \a
1157 * this->getSpaceDimension().
1159 void MEDCouplingIMesh::translate(const double *vector)
1161 checkSpaceDimension();
1162 int dim(getSpaceDimension());
1163 std::transform(_origin,_origin+dim,vector,_origin,std::plus<double>());
1168 * Applies scaling transformation to all nodes of \a this mesh.
1169 * \param [in] point - coordinates of a scaling center. This array is to be of
1170 * size \a this->getSpaceDimension() at least.
1171 * \param [in] factor - a scale factor.
1173 void MEDCouplingIMesh::scale(const double *point, double factor)
1175 checkSpaceDimension();
1176 int dim(getSpaceDimension());
1177 std::transform(_origin,_origin+dim,point,_origin,std::minus<double>());
1178 std::transform(_origin,_origin+dim,_origin,std::bind2nd(std::multiplies<double>(),factor));
1179 std::transform(_dxyz,_dxyz+dim,_dxyz,std::bind2nd(std::multiplies<double>(),factor));
1180 std::transform(_origin,_origin+dim,point,_origin,std::plus<double>());
1184 MEDCouplingMesh *MEDCouplingIMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
1186 //not implemented yet !
1191 * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
1192 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1193 * this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
1194 * components. The caller is to delete this array using decrRef() as it is
1197 DataArrayDouble *MEDCouplingIMesh::getCoordinatesAndOwner() const
1200 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1201 int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
1202 ret->alloc(nbNodes,spaceDim);
1203 double *pt(ret->getPointer());
1204 ret->setInfoOnComponents(buildInfoOnComponents());
1206 getSplitNodeValues(tmp);
1207 for(int i=0;i<nbNodes;i++)
1209 GetPosFromId(i,spaceDim,tmp,tmp2);
1210 for(int j=0;j<spaceDim;j++)
1211 pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+_origin[j];
1217 * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
1218 * computed by averaging coordinates of cell nodes.
1219 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1220 * this->getNumberOfCells() tuples per \a this->getSpaceDimension()
1221 * components. The caller is to delete this array using decrRef() as it is
1224 DataArrayDouble *MEDCouplingIMesh::getBarycenterAndOwner() const
1227 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1228 int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()),tmp[3],tmp2[3];
1229 ret->alloc(nbCells,spaceDim);
1230 double *pt(ret->getPointer()),shiftOrigin[3];
1231 std::transform(_dxyz,_dxyz+spaceDim,shiftOrigin,std::bind2nd(std::multiplies<double>(),0.5));
1232 std::transform(_origin,_origin+spaceDim,shiftOrigin,shiftOrigin,std::plus<double>());
1233 getSplitCellValues(tmp);
1234 ret->setInfoOnComponents(buildInfoOnComponents());
1235 for(int i=0;i<nbCells;i++)
1237 GetPosFromId(i,spaceDim,tmp,tmp2);
1238 for(int j=0;j<spaceDim;j++)
1239 pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+shiftOrigin[j];
1244 DataArrayDouble *MEDCouplingIMesh::computeIsoBarycenterOfNodesPerCell() const
1246 return MEDCouplingIMesh::getBarycenterAndOwner();
1249 void MEDCouplingIMesh::renumberCells(const int *old2NewBg, bool check)
1251 throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for IMesh !");
1254 void MEDCouplingIMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1257 double time(getTime(it,order));
1260 littleStrings.clear();
1261 littleStrings.push_back(getName());
1262 littleStrings.push_back(getDescription());
1263 littleStrings.push_back(getTimeUnit());
1264 littleStrings.push_back(getAxisUnit());
1265 tinyInfo.push_back(it);
1266 tinyInfo.push_back(order);
1267 tinyInfo.push_back(_space_dim);
1268 tinyInfo.insert(tinyInfo.end(),_structure,_structure+3);
1269 tinyInfoD.push_back(time);
1270 tinyInfoD.insert(tinyInfoD.end(),_dxyz,_dxyz+3);
1271 tinyInfoD.insert(tinyInfoD.end(),_origin,_origin+3);
1274 void MEDCouplingIMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1280 void MEDCouplingIMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1282 a1=DataArrayInt::New();
1284 a2=DataArrayDouble::New();
1288 void MEDCouplingIMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1289 const std::vector<std::string>& littleStrings)
1291 setName(littleStrings[0]);
1292 setDescription(littleStrings[1]);
1293 setTimeUnit(littleStrings[2]);
1294 setAxisUnit(littleStrings[3]);
1295 setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]);
1296 _space_dim=tinyInfo[2];
1297 _structure[0]=tinyInfo[3]; _structure[1]=tinyInfo[4]; _structure[2]=tinyInfo[5];
1298 _dxyz[0]=tinyInfoD[1]; _dxyz[1]=tinyInfoD[2]; _dxyz[2]=tinyInfoD[3];
1299 _origin[0]=tinyInfoD[4]; _origin[1]=tinyInfoD[5]; _origin[2]=tinyInfoD[6];
1303 void MEDCouplingIMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
1306 std::ostringstream extent,origin,spacing;
1307 for(int i=0;i<3;i++)
1310 { extent << "0 " << _structure[i]-1 << " "; origin << _origin[i] << " "; spacing << _dxyz[i] << " "; }
1312 { extent << "0 0 "; origin << "0 "; spacing << "0 "; }
1314 ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\" Origin=\"" << origin.str() << "\" Spacing=\"" << spacing.str() << "\">\n";
1315 ofs << " <Piece Extent=\"" << extent.str() << "\">\n";
1316 ofs << " <PointData>\n" << pointData << std::endl;
1317 ofs << " </PointData>\n";
1318 ofs << " <CellData>\n" << cellData << std::endl;
1319 ofs << " </CellData>\n";
1320 ofs << " <Coordinates>\n";
1321 ofs << " </Coordinates>\n";
1322 ofs << " </Piece>\n";
1323 ofs << " </" << getVTKDataSetType() << ">\n";
1326 void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const
1328 stream << "MEDCouplingIMesh C++ instance at " << this << ". Name : \"" << getName() << "\". Space dimension : " << _space_dim << ".";
1329 if(_space_dim<0 || _space_dim>3)
1332 std::ostringstream stream0,stream1;
1333 int nbNodes(1),nbCells(0);
1335 for(int i=0;i<_space_dim;i++)
1338 int tmpNodes(_structure[i]);
1339 stream1 << "- Axis " << tmp << " : " << tmpNodes << " nodes (orig=" << _origin[i] << ", inter=" << _dxyz[i] << ").";
1341 stream1 << std::endl;
1347 nbCells=nbCells==0?tmpNodes-1:nbCells*(tmpNodes-1);
1351 stream0 << "Number of cells : " << nbCells << ", Number of nodes : " << nbNodes;
1352 stream << stream0.str();
1354 stream << std::endl;
1356 stream << stream1.str();
1359 std::string MEDCouplingIMesh::getVTKDataSetType() const
1361 return std::string("ImageData");
1364 std::vector<std::string> MEDCouplingIMesh::buildInfoOnComponents() const
1366 checkSpaceDimension();
1367 int dim(getSpaceDimension());
1368 std::vector<std::string> ret(dim);
1369 for(int i=0;i<dim;i++)
1371 std::ostringstream oss;
1372 char tmp('X'+i); oss << tmp;
1373 ret[i]=DataArray::BuildInfoFromVarAndUnit(oss.str(),_axis_unit);
1378 void MEDCouplingIMesh::checkSpaceDimension() const
1380 CheckSpaceDimension(_space_dim);
1383 void MEDCouplingIMesh::CheckSpaceDimension(int spaceDim)
1385 if(spaceDim<0 || spaceDim>3)
1386 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CheckSpaceDimension : input spaceDim must be in [0,1,2,3] !");
1389 int MEDCouplingIMesh::FindIntRoot(int val, int order)
1394 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : input val is < 0 ! Not possible to compute a root !");
1397 if(order!=2 && order!=3)
1398 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the order available are 0,1,2 or 3 !");
1399 double valf((double)val);
1402 double retf(sqrt(valf));
1405 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect square root !");
1410 double retf(std::pow(val,0.3333333333333333));
1411 int ret((int)retf),ret2(ret+1);
1412 if(ret*ret*ret!=val && ret2*ret2*ret2!=val)
1413 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect cublic root !");
1414 if(ret*ret*ret==val)
1421 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)
1423 double *outPtrWork(outPtr);
1424 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
1425 int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
1426 int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
1427 for(int jg=0;jg<ghostSize;jg++)
1429 for(int ig=0;ig<ghostSize;ig++)
1430 outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1432 for(int ig=0;ig<dims[0];ig++,kk0++)
1433 for(int ifact=0;ifact<fact0;ifact++)
1434 outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1435 for(int ik=0;ik<ghostSize;ik++)
1436 outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1438 for(int j=0;j<dims[1];j++)
1440 kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
1441 for(int jfact=0;jfact<fact1;jfact++)
1443 for(int ig=0;ig<ghostSize;ig++)
1444 outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1445 int kk0(kk+1);//1 not ghost. We make the hypothesis that factors is >= ghostlev
1446 for(int i=0;i<dims[0];i++,kk0++)
1448 const double *loc(inPtr+kk0*nbCompo);
1449 for(int ifact=0;ifact<fact0;ifact++)
1450 outPtrWork=std::copy(loc,loc+nbCompo,outPtrWork);
1452 for(int ig=0;ig<ghostSize;ig++)
1453 outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1456 kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
1457 for(int jg=0;jg<ghostSize;jg++)
1459 for(int ig=0;ig<ghostSize;ig++)
1460 outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1462 for(int ig=0;ig<dims[0];ig++,kk0++)
1463 for(int ifact=0;ifact<fact0;ifact++)
1464 outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1465 for(int ik=0;ik<ghostSize;ik++)
1466 outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);