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(nbTuplesFine%nbOfTuplesInFineExp!=0)
298 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Invalid nb of tuples in fine DataArray regarding its structure !");
299 int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
300 if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
302 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
303 throw INTERP_KERNEL::Exception(oss.str().c_str());
305 // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
306 double *outPtr(coarseDA->getPointer());
307 const double *inPtr(fineDA->begin());
309 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
314 int offset(fineLocInCoarse[0].first),fact0(facts[0]);
315 for(int i=0;i<dims[0];i++)
317 double *loc(outPtr+(offset+i)*nbCompo);
318 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
321 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
323 std::copy(inPtr,inPtr+nbCompo,loc);
330 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact1(facts[1]),fact0(facts[0]);
331 for(int j=0;j<dims[1];j++)
333 for(int jfact=0;jfact<fact1;jfact++)
335 for(int i=0;i<dims[0];i++)
337 double *loc(outPtr+(kk+i)*nbCompo);
338 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
340 if(jfact!=0 || ifact!=0)
341 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
343 std::copy(inPtr,inPtr+nbCompo,loc);
353 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]);
354 for(int k=0;k<dims[2];k++)
356 for(int kfact=0;kfact<fact2;kfact++)
358 for(int j=0;j<dims[1];j++)
360 for(int jfact=0;jfact<fact1;jfact++)
362 for(int i=0;i<dims[0];i++)
364 double *loc(outPtr+(kk+i+j*coarseSt[0])*nbCompo);
365 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
367 if(kfact!=0 || jfact!=0 || ifact!=0)
368 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
370 std::copy(inPtr,inPtr+nbCompo,loc);
376 kk+=coarseSt[0]*coarseSt[1];
381 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : only dimensions 1, 2 and 3 supported !");
386 * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example)
387 * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh
388 * 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.
390 * \param [in] coarseSt The cell structure of coarse mesh.
391 * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh
392 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
393 * \param [in] facts The refinement coefficient per axis.
394 * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
395 * \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.
397 * \sa CondenseFineToCoarse,SpreadCoarseToFineGhost
399 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)
402 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : ghost level has to be >= 0 !");
403 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
404 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : All input vectors (dimension) must have the same size !");
405 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
406 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the parameters 1 or 3 are NULL or not allocated !");
407 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
408 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
409 int nbCompo(fineDA->getNumberOfComponents());
410 if(coarseDA->getNumberOfComponents()!=nbCompo)
411 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the number of components of fine DA and coarse one mismatches !");
412 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
413 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) !");
414 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
416 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples in coarse DataArray having " << coarseDA->getNumberOfTuples() << " !";
417 throw INTERP_KERNEL::Exception(oss.str().c_str());
420 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
421 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
422 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
423 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
424 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
426 std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
427 throw INTERP_KERNEL::Exception(oss.str().c_str());
430 double *outPtr(coarseDA->getPointer());
431 const double *inPtr(fineDA->begin());
433 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
438 int offset(fineLocInCoarse[0].first+ghostSize),fact0(facts[0]);
439 inPtr+=ghostSize*nbCompo;
440 for(int i=0;i<dims[0];i++)
442 double *loc(outPtr+(offset+i)*nbCompo);
443 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
446 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
448 std::copy(inPtr,inPtr+nbCompo,loc);
455 int nxwg(coarseSt[0]+2*ghostSize);
456 int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)),fact1(facts[1]),fact0(facts[0]);
457 inPtr+=(dims[0]*fact0+2*ghostSize)*nbCompo;
458 for(int j=0;j<dims[1];j++)
460 for(int jfact=0;jfact<fact1;jfact++)
462 inPtr+=ghostSize*nbCompo;
463 for(int i=0;i<dims[0];i++)
465 double *loc(outPtr+(kk+i)*nbCompo);
466 for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
468 if(jfact!=0 || ifact!=0)
469 std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
471 std::copy(inPtr,inPtr+nbCompo,loc);
474 inPtr+=ghostSize*nbCompo;
481 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2 supported !");
486 * This method spreads the values of coarse data \a coarseDA into \a fineDA.
488 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
489 * \param [in] coarseSt The cell structure of coarse mesh.
490 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
491 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
492 * \param [in] facts The refinement coefficient per axis.
493 * \sa SpreadCoarseToFineGhost, CondenseFineToCoarse
495 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)
497 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
498 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !");
499 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
500 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !");
501 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
502 int nbCompo(fineDA->getNumberOfComponents());
503 if(coarseDA->getNumberOfComponents()!=nbCompo)
504 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the number of components of fine DA and coarse one mismatches !");
505 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
506 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) !");
507 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
509 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
510 throw INTERP_KERNEL::Exception(oss.str().c_str());
512 int nbTuplesFine(fineDA->getNumberOfTuples());
513 if(nbTuplesFine%nbOfTuplesInFineExp!=0)
514 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : Invalid nb of tuples in fine DataArray regarding its structure !");
515 int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
516 if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
518 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
519 throw INTERP_KERNEL::Exception(oss.str().c_str());
521 // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
522 double *outPtr(fineDA->getPointer());
523 const double *inPtr(coarseDA->begin());
525 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
530 int offset(fineLocInCoarse[0].first),fact0(facts[0]);
531 for(int i=0;i<dims[0];i++)
533 const double *loc(inPtr+(offset+i)*nbCompo);
534 for(int ifact=0;ifact<fact0;ifact++)
535 outPtr=std::copy(loc,loc+nbCompo,outPtr);
541 int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact0(facts[0]),fact1(facts[1]);
542 for(int j=0;j<dims[1];j++)
544 for(int jfact=0;jfact<fact1;jfact++)
546 for(int i=0;i<dims[0];i++)
548 const double *loc(inPtr+(kk+i)*nbCompo);
549 for(int ifact=0;ifact<fact0;ifact++)
550 outPtr=std::copy(loc,loc+nbCompo,outPtr);
559 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]);
560 for(int k=0;k<dims[2];k++)
562 for(int kfact=0;kfact<fact2;kfact++)
564 for(int j=0;j<dims[1];j++)
566 for(int jfact=0;jfact<fact1;jfact++)
568 for(int i=0;i<dims[0];i++)
570 const double *loc(inPtr+(kk+i+j*coarseSt[0])*nbCompo);
571 for(int ifact=0;ifact<fact0;ifact++)
572 outPtr=std::copy(loc,loc+nbCompo,outPtr);
577 kk+=coarseSt[0]*coarseSt[1];
582 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : only dimensions 1, 2 and 3 supported !");
587 * This method spreads the values of coarse data \a coarseDA into \a fineDA.
589 * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
590 * \param [in] coarseSt The cell structure of coarse mesh.
591 * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
592 * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
593 * \param [in] facts The refinement coefficient per axis.
594 * \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.
595 * \sa CondenseFineToCoarse
597 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)
600 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level has to be >= 0 !");
601 if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
602 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !");
603 if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
604 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !");
605 std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
606 int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
607 int nbCompo(fineDA->getNumberOfComponents());
608 if(coarseDA->getNumberOfComponents()!=nbCompo)
609 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the number of components of fine DA and coarse one mismatches !");
610 if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
611 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) !");
612 if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
614 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
615 throw INTERP_KERNEL::Exception(oss.str().c_str());
618 std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
619 std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
620 std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
621 int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
622 if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
624 std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
625 throw INTERP_KERNEL::Exception(oss.str().c_str());
628 double *outPtr(fineDA->getPointer());
629 const double *inPtr(coarseDA->begin());
631 std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
636 int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
637 for(int i=0;i<ghostSize;i++)
638 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
639 offset=fineLocInCoarse[0].first+ghostSize;
640 for(int i=0;i<dims[0];i++)
642 const double *loc(inPtr+(offset+i)*nbCompo);
643 for(int ifact=0;ifact<fact0;ifact++)
644 outPtr=std::copy(loc,loc+nbCompo,outPtr);
646 offset=fineLocInCoarse[0].second+ghostSize;
647 for(int i=0;i<ghostSize;i++)
648 outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
653 int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
654 int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
655 for(int jg=0;jg<ghostSize;jg++)
657 for(int ig=0;ig<ghostSize;ig++)
658 outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
660 for(int ig=0;ig<dims[0];ig++,kk0++)
661 for(int ifact=0;ifact<fact0;ifact++)
662 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
663 for(int ik=0;ik<ghostSize;ik++)
664 outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
666 for(int j=0;j<dims[1];j++)
668 kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
669 for(int jfact=0;jfact<fact1;jfact++)
671 for(int ig=0;ig<ghostSize;ig++)
672 outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
674 for(int i=0;i<dims[0];i++,kk0++)
676 const double *loc(inPtr+kk0*nbCompo);
677 for(int ifact=0;ifact<fact0;ifact++)
678 outPtr=std::copy(loc,loc+nbCompo,outPtr);
680 for(int ig=0;ig<ghostSize;ig++)
681 outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
684 kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
685 for(int jg=0;jg<ghostSize;jg++)
687 for(int ig=0;ig<ghostSize;ig++)
688 outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
690 for(int ig=0;ig<dims[0];ig++,kk0++)
691 for(int ifact=0;ifact<fact0;ifact++)
692 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
693 for(int ik=0;ik<ghostSize;ik++)
694 outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
699 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : only dimensions 1, 2 supported !");
703 void MEDCouplingIMesh::setSpaceDimension(int spaceDim)
705 if(spaceDim==_space_dim)
707 CheckSpaceDimension(spaceDim);
712 void MEDCouplingIMesh::updateTime() const
716 std::size_t MEDCouplingIMesh::getHeapMemorySizeWithoutChildren() const
718 return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
721 std::vector<const BigMemoryObject *> MEDCouplingIMesh::getDirectChildren() const
723 return std::vector<const BigMemoryObject *>();
727 * This method copyies all tiny strings from other (name and components name).
728 * @throw if other and this have not same mesh type.
730 void MEDCouplingIMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
732 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
734 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::copyTinyStringsFrom : meshes have not same type !");
735 MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
739 bool MEDCouplingIMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
742 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::isEqualIfNotWhy : input other pointer is null !");
743 const MEDCouplingIMesh *otherC(dynamic_cast<const MEDCouplingIMesh *>(other));
746 reason="mesh given in input is not castable in MEDCouplingIMesh !";
749 if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
751 if(!isEqualWithoutConsideringStrInternal(otherC,prec,reason))
753 if(_axis_unit!=otherC->_axis_unit)
755 reason="The units of axis are not the same !";
761 bool MEDCouplingIMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
763 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
767 return isEqualWithoutConsideringStrInternal(other,prec,tmp);
770 bool MEDCouplingIMesh::isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const
772 const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
775 if(_space_dim!=otherC->_space_dim)
777 std::ostringstream oss;
778 oss << "The spaceDimension of this (" << _space_dim << ") is not equal to those of other (" << otherC->_space_dim << ") !";
781 checkSpaceDimension();
782 for(int i=0;i<_space_dim;i++)
784 if(fabs(_origin[i]-otherC->_origin[i])>prec)
786 std::ostringstream oss;
787 oss << "The origin of this and other differs at " << i << " !";
792 for(int i=0;i<_space_dim;i++)
794 if(fabs(_dxyz[i]-otherC->_dxyz[i])>prec)
796 std::ostringstream oss;
797 oss << "The delta of this and other differs at " << i << " !";
802 for(int i=0;i<_space_dim;i++)
804 if(_structure[i]!=otherC->_structure[i])
806 std::ostringstream oss;
807 oss << "The structure of this and other differs at " << i << " !";
815 void MEDCouplingIMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
816 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
818 if(!isEqualWithoutConsideringStr(other,prec))
819 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalWith : Meshes are not the same !");
823 * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingIMesh instance too).
824 * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingIMesh, \a this and \a other are the same !
826 void MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
827 DataArrayInt *&cellCor) const
829 if(!isEqualWithoutConsideringStr(other,prec))
830 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
833 void MEDCouplingIMesh::checkCoherency() const
835 checkSpaceDimension();
836 for(int i=0;i<_space_dim;i++)
839 std::ostringstream oss; oss << "MEDCouplingIMesh::checkCoherency : On axis " << i << "/" << _space_dim << ", number of nodes is equal to " << _structure[i] << " ! must be >=1 !";
840 throw INTERP_KERNEL::Exception(oss.str().c_str());
844 void MEDCouplingIMesh::checkCoherency1(double eps) const
849 void MEDCouplingIMesh::checkCoherency2(double eps) const
851 checkCoherency1(eps);
854 void MEDCouplingIMesh::getNodeGridStructure(int *res) const
856 checkSpaceDimension();
857 std::copy(_structure,_structure+_space_dim,res);
860 std::vector<int> MEDCouplingIMesh::getNodeGridStructure() const
862 checkSpaceDimension();
863 std::vector<int> ret(_structure,_structure+_space_dim);
867 MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
870 int dim(getSpaceDimension());
871 if(dim!=(int)cellPart.size())
873 std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !";
874 throw INTERP_KERNEL::Exception(oss.str().c_str());
876 double retOrigin[3]={0.,0.,0.};
877 int retStruct[3]={0,0,0};
878 MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(dynamic_cast<MEDCouplingIMesh *>(deepCpy()));
879 for(int i=0;i<dim;i++)
881 int startNode(cellPart[i].first),endNode(cellPart[i].second+1);
882 int myDelta(endNode-startNode);
883 if(startNode<0 || startNode>=_structure[i])
885 std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : At dimension #" << i << " the start node id is " << startNode << " it should be in [0," << _structure[i] << ") !";
886 throw INTERP_KERNEL::Exception(oss.str().c_str());
888 if(myDelta<0 || myDelta>_structure[i])
890 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;
891 throw INTERP_KERNEL::Exception(oss.str().c_str());
893 retOrigin[i]=_origin[i]+startNode*_dxyz[i];
894 retStruct[i]=myDelta;
896 ret->setNodeStruct(retStruct,retStruct+dim);
897 ret->setOrigin(retOrigin,retOrigin+dim);
898 ret->checkCoherency();
903 * Return the space dimension of \a this.
905 int MEDCouplingIMesh::getSpaceDimension() const
910 void MEDCouplingIMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
913 int spaceDim(getSpaceDimension());
914 getSplitNodeValues(tmp);
916 GetPosFromId(nodeId,spaceDim,tmp,tmp2);
917 for(int j=0;j<spaceDim;j++)
918 coo.push_back(_origin[j]+_dxyz[j]*tmp2[j]);
921 std::string MEDCouplingIMesh::simpleRepr() const
923 std::ostringstream ret;
924 ret << "Image grid with name : \"" << getName() << "\"\n";
925 ret << "Description of mesh : \"" << getDescription() << "\"\n";
927 double tt(getTime(tmpp1,tmpp2));
928 int spaceDim(_space_dim);
929 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
930 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
931 ret << "Space dimension : " << spaceDim << "\n";
932 if(spaceDim<0 || spaceDim>3)
934 ret << "The nodal structure is : "; std::copy(_structure,_structure+spaceDim,std::ostream_iterator<int>(ret," ")); ret << "\n";
935 ret << "The origin position is [" << _axis_unit << "]: ";
936 std::copy(_origin,_origin+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
937 ret << "The intervals along axis are : ";
938 std::copy(_dxyz,_dxyz+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
942 std::string MEDCouplingIMesh::advancedRepr() const
947 void MEDCouplingIMesh::getBoundingBox(double *bbox) const
950 int dim(getSpaceDimension());
951 for(int idim=0; idim<dim; idim++)
953 bbox[2*idim]=_origin[idim];
954 int coeff(_structure[idim]);
955 if(_structure[idim]<0)
957 std::ostringstream oss; oss << "MEDCouplingIMesh::getBoundingBox : on axis #" << idim << " number of nodes in structure is < 0 !";
958 throw INTERP_KERNEL::Exception(oss.str().c_str());
960 if(_structure[idim]>1)
961 coeff=_structure[idim]-1;
962 bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*coeff;
967 * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
969 * For 1D cells, the returned field contains lengths.<br>
970 * For 2D cells, the returned field contains areas.<br>
971 * For 3D cells, the returned field contains volumes.
972 * \param [in] isAbs - a not used parameter.
973 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
974 * and one time . The caller is to delete this field using decrRef() as it is no
977 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureField(bool isAbs) const
980 std::string name="MeasureOfMesh_";
982 int nbelem(getNumberOfCells());
983 MEDCouplingFieldDouble *field(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
984 field->setName(name);
985 DataArrayDouble* array(DataArrayDouble::New());
986 array->alloc(nbelem,1);
987 array->fillWithValue(getMeasureOfAnyCell());
988 field->setArray(array) ;
990 field->setMesh(const_cast<MEDCouplingIMesh *>(this));
991 field->synchronizeTimeWithMesh();
996 * not implemented yet !
998 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureFieldOnNode(bool isAbs) const
1000 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::getMeasureFieldOnNode : not implemented yet !");
1004 int MEDCouplingIMesh::getCellContainingPoint(const double *pos, double eps) const
1006 int dim(getSpaceDimension()),ret(0),coeff(1);
1007 for(int i=0;i<dim;i++)
1009 int nbOfCells(_structure[i]-1);
1011 int tmp((int)((ref-_origin[i])/_dxyz[i]));
1012 if(tmp>=0 && tmp<nbOfCells)
1023 void MEDCouplingIMesh::rotate(const double *center, const double *vector, double angle)
1025 throw INTERP_KERNEL::Exception("No rotation available on IMesh : Traduce it to unstructured mesh to apply it !");
1029 * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
1030 * component of the \a vector to all node coordinates of a corresponding axis.
1031 * \param [in] vector - the translation vector whose size must be not less than \a
1032 * this->getSpaceDimension().
1034 void MEDCouplingIMesh::translate(const double *vector)
1036 checkSpaceDimension();
1037 int dim(getSpaceDimension());
1038 std::transform(_origin,_origin+dim,vector,_origin,std::plus<double>());
1043 * Applies scaling transformation to all nodes of \a this mesh.
1044 * \param [in] point - coordinates of a scaling center. This array is to be of
1045 * size \a this->getSpaceDimension() at least.
1046 * \param [in] factor - a scale factor.
1048 void MEDCouplingIMesh::scale(const double *point, double factor)
1050 checkSpaceDimension();
1051 int dim(getSpaceDimension());
1052 std::transform(_origin,_origin+dim,point,_origin,std::minus<double>());
1053 std::transform(_origin,_origin+dim,_origin,std::bind2nd(std::multiplies<double>(),factor));
1054 std::transform(_dxyz,_dxyz+dim,_dxyz,std::bind2nd(std::multiplies<double>(),factor));
1055 std::transform(_origin,_origin+dim,point,_origin,std::plus<double>());
1059 MEDCouplingMesh *MEDCouplingIMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
1061 //not implemented yet !
1066 * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
1067 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1068 * this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
1069 * components. The caller is to delete this array using decrRef() as it is
1072 DataArrayDouble *MEDCouplingIMesh::getCoordinatesAndOwner() const
1075 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1076 int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
1077 ret->alloc(nbNodes,spaceDim);
1078 double *pt(ret->getPointer());
1079 ret->setInfoOnComponents(buildInfoOnComponents());
1081 getSplitNodeValues(tmp);
1082 for(int i=0;i<nbNodes;i++)
1084 GetPosFromId(i,spaceDim,tmp,tmp2);
1085 for(int j=0;j<spaceDim;j++)
1086 pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+_origin[j];
1092 * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
1093 * computed by averaging coordinates of cell nodes.
1094 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1095 * this->getNumberOfCells() tuples per \a this->getSpaceDimension()
1096 * components. The caller is to delete this array using decrRef() as it is
1099 DataArrayDouble *MEDCouplingIMesh::getBarycenterAndOwner() const
1102 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1103 int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()),tmp[3],tmp2[3];
1104 ret->alloc(nbCells,spaceDim);
1105 double *pt(ret->getPointer()),shiftOrigin[3];
1106 std::transform(_dxyz,_dxyz+spaceDim,shiftOrigin,std::bind2nd(std::multiplies<double>(),0.5));
1107 std::transform(_origin,_origin+spaceDim,shiftOrigin,shiftOrigin,std::plus<double>());
1108 getSplitCellValues(tmp);
1109 ret->setInfoOnComponents(buildInfoOnComponents());
1110 for(int i=0;i<nbCells;i++)
1112 GetPosFromId(i,spaceDim,tmp,tmp2);
1113 for(int j=0;j<spaceDim;j++)
1114 pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+shiftOrigin[j];
1119 DataArrayDouble *MEDCouplingIMesh::computeIsoBarycenterOfNodesPerCell() const
1121 return MEDCouplingIMesh::getBarycenterAndOwner();
1124 void MEDCouplingIMesh::renumberCells(const int *old2NewBg, bool check)
1126 throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for IMesh !");
1129 void MEDCouplingIMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1132 double time(getTime(it,order));
1135 littleStrings.clear();
1136 littleStrings.push_back(getName());
1137 littleStrings.push_back(getDescription());
1138 littleStrings.push_back(getTimeUnit());
1139 littleStrings.push_back(getAxisUnit());
1140 tinyInfo.push_back(it);
1141 tinyInfo.push_back(order);
1142 tinyInfo.push_back(_space_dim);
1143 tinyInfo.insert(tinyInfo.end(),_structure,_structure+3);
1144 tinyInfoD.push_back(time);
1145 tinyInfoD.insert(tinyInfoD.end(),_dxyz,_dxyz+3);
1146 tinyInfoD.insert(tinyInfoD.end(),_origin,_origin+3);
1149 void MEDCouplingIMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1155 void MEDCouplingIMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1157 a1=DataArrayInt::New();
1159 a2=DataArrayDouble::New();
1163 void MEDCouplingIMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1164 const std::vector<std::string>& littleStrings)
1166 setName(littleStrings[0]);
1167 setDescription(littleStrings[1]);
1168 setTimeUnit(littleStrings[2]);
1169 setAxisUnit(littleStrings[3]);
1170 setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]);
1171 _space_dim=tinyInfo[2];
1172 _structure[0]=tinyInfo[3]; _structure[1]=tinyInfo[4]; _structure[2]=tinyInfo[5];
1173 _dxyz[0]=tinyInfoD[1]; _dxyz[1]=tinyInfoD[2]; _dxyz[2]=tinyInfoD[3];
1174 _origin[0]=tinyInfoD[4]; _origin[1]=tinyInfoD[5]; _origin[2]=tinyInfoD[6];
1178 void MEDCouplingIMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
1181 std::ostringstream extent,origin,spacing;
1182 for(int i=0;i<3;i++)
1185 { extent << "0 " << _structure[i]-1 << " "; origin << _origin[i] << " "; spacing << _dxyz[i] << " "; }
1187 { extent << "0 0 "; origin << "0 "; spacing << "0 "; }
1189 ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\" Origin=\"" << origin.str() << "\" Spacing=\"" << spacing.str() << "\">\n";
1190 ofs << " <Piece Extent=\"" << extent.str() << "\">\n";
1191 ofs << " <PointData>\n" << pointData << std::endl;
1192 ofs << " </PointData>\n";
1193 ofs << " <CellData>\n" << cellData << std::endl;
1194 ofs << " </CellData>\n";
1195 ofs << " <Coordinates>\n";
1196 ofs << " </Coordinates>\n";
1197 ofs << " </Piece>\n";
1198 ofs << " </" << getVTKDataSetType() << ">\n";
1201 void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const
1203 stream << "MEDCouplingIMesh C++ instance at " << this << ". Name : \"" << getName() << "\". Space dimension : " << _space_dim << ".";
1204 if(_space_dim<0 || _space_dim>3)
1207 std::ostringstream stream0,stream1;
1208 int nbNodes(1),nbCells(0);
1210 for(int i=0;i<_space_dim;i++)
1213 int tmpNodes(_structure[i]);
1214 stream1 << "- Axis " << tmp << " : " << tmpNodes << " nodes (orig=" << _origin[i] << ", inter=" << _dxyz[i] << ").";
1216 stream1 << std::endl;
1222 nbCells=nbCells==0?tmpNodes-1:nbCells*(tmpNodes-1);
1226 stream0 << "Number of cells : " << nbCells << ", Number of nodes : " << nbNodes;
1227 stream << stream0.str();
1229 stream << std::endl;
1231 stream << stream1.str();
1234 std::string MEDCouplingIMesh::getVTKDataSetType() const
1236 return std::string("ImageData");
1239 std::vector<std::string> MEDCouplingIMesh::buildInfoOnComponents() const
1241 checkSpaceDimension();
1242 int dim(getSpaceDimension());
1243 std::vector<std::string> ret(dim);
1244 for(int i=0;i<dim;i++)
1246 std::ostringstream oss;
1247 char tmp('X'+i); oss << tmp;
1248 ret[i]=DataArray::BuildInfoFromVarAndUnit(oss.str(),_axis_unit);
1253 void MEDCouplingIMesh::checkSpaceDimension() const
1255 CheckSpaceDimension(_space_dim);
1258 void MEDCouplingIMesh::CheckSpaceDimension(int spaceDim)
1260 if(spaceDim<0 || spaceDim>3)
1261 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CheckSpaceDimension : input spaceDim must be in [0,1,2,3] !");
1264 int MEDCouplingIMesh::FindIntRoot(int val, int order)
1269 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : input val is < 0 ! Not possible to compute a root !");
1272 if(order!=2 && order!=3)
1273 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the order available are 0,1,2 or 3 !");
1274 double valf((double)val);
1277 double retf(sqrt(valf));
1280 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect square root !");
1285 double retf(std::pow(val,0.3333333333333333));
1286 int ret((int)retf),ret2(ret+1);
1287 if(ret*ret*ret!=val && ret2*ret2*ret2!=val)
1288 throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect cublic root !");
1289 if(ret*ret*ret==val)