Salome HOME
f5821c9e68e538cd53b7bc1ef49206c4fd5ef1d4
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingIMesh.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingIMesh.hxx"
22 #include "MEDCouplingCMesh.hxx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingFieldDouble.hxx"
25
26 #include <functional>
27 #include <algorithm>
28 #include <sstream>
29 #include <numeric>
30
31 using namespace ParaMEDMEM;
32
33 MEDCouplingIMesh::MEDCouplingIMesh():_space_dim(-1)
34 {
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;
38 }
39
40 MEDCouplingIMesh::MEDCouplingIMesh(const MEDCouplingIMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy),_space_dim(other._space_dim),_axis_unit(other._axis_unit)
41 {
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];
45 }
46
47 MEDCouplingIMesh::~MEDCouplingIMesh()
48 {
49 }
50
51 MEDCouplingIMesh *MEDCouplingIMesh::New()
52 {
53   return new MEDCouplingIMesh;
54 }
55
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)
58 {
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);
65   return ret.retn();
66 }
67
68 MEDCouplingMesh *MEDCouplingIMesh::deepCpy() const
69 {
70   return clone(true);
71 }
72
73 MEDCouplingIMesh *MEDCouplingIMesh::clone(bool recDeepCpy) const
74 {
75   return new MEDCouplingIMesh(*this,recDeepCpy);
76 }
77
78 /*!
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.
81  *
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.
85  */
86 MEDCouplingIMesh *MEDCouplingIMesh::buildWithGhost(int ghostLev) const
87 {
88   if(ghostLev<0)
89     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::buildWithGhost : the ghostLev must be >= 0 !");
90   checkCoherency();
91   int spaceDim(getSpaceDimension());
92   double origin[3],dxyz[3];
93   int structure[3];
94   for(int i=0;i<spaceDim;i++)
95     {
96       origin[i]=_origin[i]-ghostLev*_dxyz[i];
97       dxyz[i]=_dxyz[i];
98       structure[i]=_structure[i]+2*ghostLev;
99     }
100   MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),spaceDim,structure,structure+spaceDim,origin,origin+spaceDim,dxyz,dxyz+spaceDim));
101   ret->copyTinyInfoFrom(this);
102   return ret.retn();
103 }
104
105 void MEDCouplingIMesh::setNodeStruct(const int *nodeStrctStart, const int *nodeStrctStop)
106 {
107   checkSpaceDimension();
108   int sz((int)std::distance(nodeStrctStart,nodeStrctStop));
109   if(sz!=_space_dim)
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);
112   declareAsNew();
113 }
114
115 std::vector<int> MEDCouplingIMesh::getNodeStruct() const
116 {
117   checkSpaceDimension();
118   return std::vector<int>(_structure,_structure+_space_dim);
119 }
120
121 void MEDCouplingIMesh::setOrigin(const double *originStart, const double *originStop)
122 {
123   checkSpaceDimension();
124   int sz((int)std::distance(originStart,originStop));
125   if(sz!=_space_dim)
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);
128   declareAsNew();
129 }
130
131 std::vector<double> MEDCouplingIMesh::getOrigin() const
132 {
133   checkSpaceDimension();
134   return std::vector<double>(_origin,_origin+_space_dim);
135 }
136
137 void MEDCouplingIMesh::setDXYZ(const double *dxyzStart, const double *dxyzStop)
138 {
139   checkSpaceDimension();
140   int sz((int)std::distance(dxyzStart,dxyzStop));
141   if(sz!=_space_dim)
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);
144   declareAsNew();
145 }
146
147 std::vector<double> MEDCouplingIMesh::getDXYZ() const
148 {
149   checkSpaceDimension();
150   return std::vector<double>(_dxyz,_dxyz+_space_dim);
151 }
152
153 void MEDCouplingIMesh::setAxisUnit(const std::string& unitName)
154 {
155   _axis_unit=unitName;
156   declareAsNew();
157 }
158
159 std::string MEDCouplingIMesh::getAxisUnit() const
160 {
161   return _axis_unit;
162 }
163
164 /*!
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.
168  *
169  * \sa getMeasureField
170  */
171 double MEDCouplingIMesh::getMeasureOfAnyCell() const
172 {
173   checkCoherency();
174   int dim(getSpaceDimension());
175   double ret(1.);
176   for(int i=0;i<dim;i++)
177     ret*=fabs(_dxyz[i]);
178   return ret;
179 }
180
181 /*!
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.
185  *
186  * \sa MEDCouplingMesh::buildUnstructured
187  */
188 MEDCouplingCMesh *MEDCouplingIMesh::convertToCartesian() const
189 {
190   checkCoherency();
191   MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> ret(MEDCouplingCMesh::New());
192   try
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++)
198     {
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);
202     }
203   return ret.retn();
204 }
205
206 /*!
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.
211  */
212 void MEDCouplingIMesh::refineWithFactor(const std::vector<int>& factors)
213 {
214   if((int)factors.size()!=_space_dim)
215     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::refineWithFactor : refinement factors must have size equal to spaceDim !");
216   checkCoherency();
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++)
220     {
221       if(factors[i]<=0)
222         {
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());
225         }
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];
230     }
231   std::copy(structure.begin(),structure.end(),_structure);
232   std::copy(dxyz.begin(),dxyz.end(),_dxyz);
233   declareAsNew();
234 }
235
236 /*!
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.
238  *
239  * \return MEDCouplingIMesh * - A newly created object (to be managed by the caller with decrRef) containing simply one cell.
240  *
241  * \throw if \a this does not pass the \c checkCoherency test.
242  */
243 MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const
244 {
245   checkCoherency();
246   int spaceDim(getSpaceDimension()),nodeSt[3];
247   double dxyz[3];
248   for(int i=0;i<spaceDim;i++)
249     {
250       if(_structure[i]>=2)
251         {
252           nodeSt[i]=2;
253           dxyz[i]=(_structure[i]-1)*_dxyz[i];
254         }
255       else
256         {
257           nodeSt[i]=_structure[i];
258           dxyz[i]=_dxyz[i];
259         }
260     }
261   MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),getSpaceDimension(),nodeSt,nodeSt+spaceDim,_origin,_origin+spaceDim,dxyz,dxyz+spaceDim));
262   ret->copyTinyInfoFrom(this);
263   return ret.retn();
264 }
265
266 /*!
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.
270  *
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.
276  *
277  * \sa CondenseFineToCoarseGhost,SpreadCoarseToFine
278  */
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)
280 {
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)
292     {
293       std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
294       throw INTERP_KERNEL::Exception(oss.str().c_str());
295     }
296   int nbTuplesFine(fineDA->getNumberOfTuples());
297   if(nbOfTuplesInFineExp==0)
298     {
299       if(nbTuplesFine==0)
300         return ;
301       else
302         throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Nothing to condense considering the range specified ! But DataArray is not empty !");
303     }
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)
308     {
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());
311     }
312   // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
313   double *outPtr(coarseDA->getPointer());
314   const double *inPtr(fineDA->begin());
315   //
316   std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
317   switch(meshDim)
318   {
319     case 1:
320       {
321         int offset(fineLocInCoarse[0].first),fact0(facts[0]);
322         for(int i=0;i<dims[0];i++)
323           {
324             double *loc(outPtr+(offset+i)*nbCompo);
325             for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
326               {
327                 if(ifact!=0)
328                   std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
329                 else
330                   std::copy(inPtr,inPtr+nbCompo,loc);
331               }
332           }
333         break;
334       }
335     case 2:
336       {
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++)
339           {
340             for(int jfact=0;jfact<fact1;jfact++)
341               {
342                 for(int i=0;i<dims[0];i++)
343                   {
344                     double *loc(outPtr+(kk+i)*nbCompo);
345                     for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
346                       {
347                         if(jfact!=0 || ifact!=0)
348                           std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
349                         else
350                           std::copy(inPtr,inPtr+nbCompo,loc);
351                       }
352                   }
353               }
354             kk+=coarseSt[0];
355           }
356         break;
357       }
358     case 3:
359       {
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++)
362           {
363             for(int kfact=0;kfact<fact2;kfact++)
364               {
365                 for(int j=0;j<dims[1];j++)
366                   {
367                     for(int jfact=0;jfact<fact1;jfact++)
368                       {
369                         for(int i=0;i<dims[0];i++)
370                           {
371                             double *loc(outPtr+(kk+i+j*coarseSt[0])*nbCompo);
372                             for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
373                               {
374                                 if(kfact!=0 || jfact!=0 || ifact!=0)
375                                   std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
376                                 else
377                                   std::copy(inPtr,inPtr+nbCompo,loc);
378                               }
379                           }
380                       }
381                   }
382               }
383             kk+=coarseSt[0]*coarseSt[1];
384           }
385         break;
386       }
387     default:
388       throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : only dimensions 1, 2 and 3 supported !");
389   }
390 }
391
392 /*!
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.
396  *
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.
403  *
404  * \sa CondenseFineToCoarse,SpreadCoarseToFineGhost
405  */
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)
407 {
408   if(ghostSize<0)
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)
422     {
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());
425     }
426   //
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)
432     {
433       std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
434       throw INTERP_KERNEL::Exception(oss.str().c_str());
435     }
436   //
437   double *outPtr(coarseDA->getPointer());
438   const double *inPtr(fineDA->begin());
439   //
440   std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
441   switch(meshDim)
442   {
443     case 1:
444       {
445         int offset(fineLocInCoarse[0].first+ghostSize),fact0(facts[0]);
446         inPtr+=ghostSize*nbCompo;
447         for(int i=0;i<dims[0];i++)
448           {
449             double *loc(outPtr+(offset+i)*nbCompo);
450             for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
451               {
452                 if(ifact!=0)
453                   std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
454                 else
455                   std::copy(inPtr,inPtr+nbCompo,loc);
456               }
457           }
458         break;
459       }
460     case 2:
461       {
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++)
466           {
467              for(int jfact=0;jfact<fact1;jfact++)
468               {
469                 inPtr+=ghostSize*nbCompo;
470                 for(int i=0;i<dims[0];i++)
471                   {
472                     double *loc(outPtr+(kk+i)*nbCompo);
473                     for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
474                       {
475                         if(jfact!=0 || ifact!=0)
476                           std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
477                         else
478                           std::copy(inPtr,inPtr+nbCompo,loc);
479                       }
480                   }
481                 inPtr+=ghostSize*nbCompo;
482               }
483             kk+=nxwg;
484           }
485         break;
486       }
487     default:
488       throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2 supported !");
489   }
490 }
491
492 /*!
493  * This method spreads the values of coarse data \a coarseDA into \a fineDA.
494  *
495  * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
496  * \param [in] coarseSt The cell structure of coarse mesh.
497  * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
498  * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
499  * \param [in] facts The refinement coefficient per axis.
500  * \sa SpreadCoarseToFineGhost, CondenseFineToCoarse
501  */
502 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)
503 {
504   if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
505       throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !");
506   if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
507     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !");
508   int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
509   int nbCompo(fineDA->getNumberOfComponents());
510   if(coarseDA->getNumberOfComponents()!=nbCompo)
511     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the number of components of fine DA and coarse one mismatches !");
512   if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
513     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) !");
514   if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
515     {
516       std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
517       throw INTERP_KERNEL::Exception(oss.str().c_str());
518     }
519   int nbTuplesFine(fineDA->getNumberOfTuples());
520   if(nbTuplesFine%nbOfTuplesInFineExp!=0)
521     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : Invalid nb of tuples in fine DataArray regarding its structure !");
522   int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
523   if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
524     {
525       std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Invalid number of tuples ("  << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
526       throw INTERP_KERNEL::Exception(oss.str().c_str());
527     }
528   // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
529   double *outPtr(fineDA->getPointer());
530   const double *inPtr(coarseDA->begin());
531   //
532   std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
533   switch(meshDim)
534   {
535     case 1:
536       {
537         int offset(fineLocInCoarse[0].first),fact0(facts[0]);
538         for(int i=0;i<dims[0];i++)
539           {
540             const double *loc(inPtr+(offset+i)*nbCompo);
541             for(int ifact=0;ifact<fact0;ifact++)
542               outPtr=std::copy(loc,loc+nbCompo,outPtr);
543           }
544         break;
545       }
546     case 2:
547       {
548         int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact0(facts[0]),fact1(facts[1]);
549         for(int j=0;j<dims[1];j++)
550           {
551             for(int jfact=0;jfact<fact1;jfact++)
552               {
553                 for(int i=0;i<dims[0];i++)
554                   {
555                     const double *loc(inPtr+(kk+i)*nbCompo);
556                     for(int ifact=0;ifact<fact0;ifact++)
557                       outPtr=std::copy(loc,loc+nbCompo,outPtr);
558                   }
559               }
560             kk+=coarseSt[0];
561           }
562         break;
563       }
564     case 3:
565       {
566         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]);
567         for(int k=0;k<dims[2];k++)
568           {
569             for(int kfact=0;kfact<fact2;kfact++)
570               {
571                 for(int j=0;j<dims[1];j++)
572                   {
573                     for(int jfact=0;jfact<fact1;jfact++)
574                       {
575                         for(int i=0;i<dims[0];i++)
576                           {
577                             const double *loc(inPtr+(kk+i+j*coarseSt[0])*nbCompo);
578                             for(int ifact=0;ifact<fact0;ifact++)
579                               outPtr=std::copy(loc,loc+nbCompo,outPtr);
580                           }
581                       }
582                   }
583               }
584             kk+=coarseSt[0]*coarseSt[1];
585           }
586         break;
587       }
588     default:
589       throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : only dimensions 1, 2 and 3 supported !");
590   }
591 }
592
593 /*!
594  * This method spreads the values of coarse data \a coarseDA into \a fineDA.
595  *
596  * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
597  * \param [in] coarseSt The cell structure of coarse mesh.
598  * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
599  * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
600  * \param [in] facts The refinement coefficient per axis.
601  * \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.
602  *
603  * \sa CondenseFineToCoarse, SpreadCoarseToFineGhostZone
604  */
605 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)
606 {
607   if(ghostSize<0)
608     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level has to be >= 0 !");
609   if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
610     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !");
611   if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
612     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !");
613   std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
614   int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
615   int nbCompo(fineDA->getNumberOfComponents());
616   if(coarseDA->getNumberOfComponents()!=nbCompo)
617     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the number of components of fine DA and coarse one mismatches !");
618   if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
619     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) !");
620   if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
621     {
622       std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
623       throw INTERP_KERNEL::Exception(oss.str().c_str());
624     }
625   //
626   std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
627   std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
628   std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
629   int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
630   if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
631     {
632       std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
633       throw INTERP_KERNEL::Exception(oss.str().c_str());
634     }
635   //
636   double *outPtr(fineDA->getPointer());
637   const double *inPtr(coarseDA->begin());
638   //
639   std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
640   switch(meshDim)
641   {
642     case 1:
643       {
644         int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
645         for(int i=0;i<ghostSize;i++)
646           outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
647         offset=fineLocInCoarse[0].first+ghostSize;
648         for(int i=0;i<dims[0];i++)
649           {
650             const double *loc(inPtr+(offset+i)*nbCompo);
651             for(int ifact=0;ifact<fact0;ifact++)
652               outPtr=std::copy(loc,loc+nbCompo,outPtr);
653           }
654         offset=fineLocInCoarse[0].second+ghostSize;
655         for(int i=0;i<ghostSize;i++)
656           outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
657         break;
658       }
659     case 2:
660       {
661         int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
662         int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
663         for(int jg=0;jg<ghostSize;jg++)
664           {
665             for(int ig=0;ig<ghostSize;ig++)
666               outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
667             int kk0(kk+1);
668             for(int ig=0;ig<dims[0];ig++,kk0++)
669               for(int ifact=0;ifact<fact0;ifact++)
670                 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
671             for(int ik=0;ik<ghostSize;ik++)
672               outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
673           }
674         for(int j=0;j<dims[1];j++)
675           {
676             kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
677             for(int jfact=0;jfact<fact1;jfact++)
678               {
679                 for(int ig=0;ig<ghostSize;ig++)
680                   outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
681                 int kk0(kk+1);//1 not ghost. We make the hypothesis that factors is >= ghostlev
682                 for(int i=0;i<dims[0];i++,kk0++)
683                   {
684                     const double *loc(inPtr+kk0*nbCompo);
685                     for(int ifact=0;ifact<fact0;ifact++)
686                       outPtr=std::copy(loc,loc+nbCompo,outPtr);
687                   }
688                 for(int ig=0;ig<ghostSize;ig++)
689                   outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
690               }
691           }
692         kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
693         for(int jg=0;jg<ghostSize;jg++)
694           {
695             for(int ig=0;ig<ghostSize;ig++)
696               outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
697             int kk0(kk+1);
698             for(int ig=0;ig<dims[0];ig++,kk0++)
699               for(int ifact=0;ifact<fact0;ifact++)
700                 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
701             for(int ik=0;ik<ghostSize;ik++)
702               outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
703           }
704         break;
705       }
706     default:
707       throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : only dimensions 1, 2 supported !");
708   }
709 }
710
711 /*!
712  * 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).
713  *
714  * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
715  * \param [in] coarseSt The cell structure of coarse mesh.
716  * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
717  * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
718  * \param [in] facts The refinement coefficient per axis.
719  * \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.
720  *
721  * \sa SpreadCoarseToFineGhost
722  */
723 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)
724 {
725   if(ghostSize<0)
726     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : ghost level has to be >= 0 !");
727   if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
728     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : All input vectors (dimension) must have the same size !");
729   if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
730     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the parameters 1 or 3 are NULL or not allocated !");
731   std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
732   int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
733   int nbCompo(fineDA->getNumberOfComponents());
734   if(coarseDA->getNumberOfComponents()!=nbCompo)
735     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the number of components of fine DA and coarse one mismatches !");
736   if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
737     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) !");
738   if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
739     {
740       std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
741       throw INTERP_KERNEL::Exception(oss.str().c_str());
742     }
743   //
744   std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
745   std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
746   std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
747   int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
748   if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
749     {
750       std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
751       throw INTERP_KERNEL::Exception(oss.str().c_str());
752     }
753   //
754   double *outPtr(fineDA->getPointer());
755   const double *inPtr(coarseDA->begin());
756   //
757   std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
758   switch(meshDim)
759   {
760     case 1:
761       {
762         int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
763         for(int i=0;i<ghostSize;i++)
764           outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
765         outPtr+=nbCompo*fact0*dims[0];
766         offset=fineLocInCoarse[0].second+ghostSize;
767         for(int i=0;i<ghostSize;i++)
768           outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
769         break;
770       }
771     case 2:
772       {
773         int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
774         int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
775         for(int jg=0;jg<ghostSize;jg++)
776           {
777             for(int ig=0;ig<ghostSize;ig++)
778               outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
779             int kk0(kk+1);
780             for(int ig=0;ig<dims[0];ig++,kk0++)
781               for(int ifact=0;ifact<fact0;ifact++)
782                 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
783             for(int ik=0;ik<ghostSize;ik++)
784               outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
785           }
786         for(int j=0;j<dims[1];j++)
787           {
788             kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
789             for(int jfact=0;jfact<fact1;jfact++)
790               {
791                 for(int ig=0;ig<ghostSize;ig++)
792                   outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
793                 int kk0(kk+1+dims[0]);//1 not ghost. We make the hypothesis that factors is >= ghostlev
794                 outPtr+=fact0*nbCompo*dims[0];
795                 for(int ig=0;ig<ghostSize;ig++)
796                   outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
797               }
798           }
799         kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
800         for(int jg=0;jg<ghostSize;jg++)
801           {
802             for(int ig=0;ig<ghostSize;ig++)
803               outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
804             int kk0(kk+1);
805             for(int ig=0;ig<dims[0];ig++,kk0++)
806               for(int ifact=0;ifact<fact0;ifact++)
807                 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
808             for(int ik=0;ik<ghostSize;ik++)
809               outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
810           }
811         break;
812       }
813     default:
814       throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : only dimensions 1, 2 supported !");
815   }
816 }
817
818 void MEDCouplingIMesh::setSpaceDimension(int spaceDim)
819 {
820   if(spaceDim==_space_dim)
821     return ;
822   CheckSpaceDimension(spaceDim);
823   _space_dim=spaceDim;
824   declareAsNew();
825 }
826
827 void MEDCouplingIMesh::updateTime() const
828 {
829 }
830
831 std::size_t MEDCouplingIMesh::getHeapMemorySizeWithoutChildren() const
832 {
833   return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
834 }
835
836 std::vector<const BigMemoryObject *> MEDCouplingIMesh::getDirectChildren() const
837 {
838   return std::vector<const BigMemoryObject *>();
839 }
840
841 /*!
842  * This method copyies all tiny strings from other (name and components name).
843  * @throw if other and this have not same mesh type.
844  */
845 void MEDCouplingIMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
846
847   const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
848   if(!otherC)
849     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::copyTinyStringsFrom : meshes have not same type !");
850   MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
851   declareAsNew();
852 }
853
854 bool MEDCouplingIMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
855 {
856   if(!other)
857     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::isEqualIfNotWhy : input other pointer is null !");
858   const MEDCouplingIMesh *otherC(dynamic_cast<const MEDCouplingIMesh *>(other));
859   if(!otherC)
860     {
861       reason="mesh given in input is not castable in MEDCouplingIMesh !";
862       return false;
863     }
864   if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
865     return false;
866   if(!isEqualWithoutConsideringStrInternal(otherC,prec,reason))
867     return false;
868   if(_axis_unit!=otherC->_axis_unit)
869     {
870       reason="The units of axis are not the same !";
871       return false;
872     }
873   return true;
874 }
875
876 bool MEDCouplingIMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
877 {
878   const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
879   if(!otherC)
880     return false;
881   std::string tmp;
882   return isEqualWithoutConsideringStrInternal(other,prec,tmp);
883 }
884
885 bool MEDCouplingIMesh::isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const
886 {
887   const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
888   if(!otherC)
889     return false;
890   if(_space_dim!=otherC->_space_dim)
891     {
892       std::ostringstream oss;
893       oss << "The spaceDimension of this (" << _space_dim << ") is not equal to those of other (" << otherC->_space_dim << ") !";
894       return false;
895     }
896   checkSpaceDimension();
897   for(int i=0;i<_space_dim;i++)
898     {
899       if(fabs(_origin[i]-otherC->_origin[i])>prec)
900         {
901           std::ostringstream oss;
902           oss << "The origin of this and other differs at " << i << " !";
903           reason=oss.str();
904           return false;
905         }
906     }
907   for(int i=0;i<_space_dim;i++)
908     {
909       if(fabs(_dxyz[i]-otherC->_dxyz[i])>prec)
910         {
911           std::ostringstream oss;
912           oss << "The delta of this and other differs at " << i << " !";
913           reason=oss.str();
914           return false;
915         }
916     }
917   for(int i=0;i<_space_dim;i++)
918     {
919       if(_structure[i]!=otherC->_structure[i])
920         {
921           std::ostringstream oss;
922           oss << "The structure of this and other differs at " << i << " !";
923           reason=oss.str();
924           return false;
925         }
926     }
927   return true;
928 }
929
930 void MEDCouplingIMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
931                                             DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
932 {
933   if(!isEqualWithoutConsideringStr(other,prec))
934     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalWith : Meshes are not the same !");
935 }
936
937 /*!
938  * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingIMesh instance too).
939  * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingIMesh, \a this and \a other are the same !
940  */
941 void MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
942                                                        DataArrayInt *&cellCor) const
943 {
944   if(!isEqualWithoutConsideringStr(other,prec))
945     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
946 }
947
948 void MEDCouplingIMesh::checkCoherency() const
949 {
950   checkSpaceDimension();
951   for(int i=0;i<_space_dim;i++)
952     if(_structure[i]<1)
953       {
954         std::ostringstream oss; oss << "MEDCouplingIMesh::checkCoherency : On axis " << i << "/" << _space_dim << ", number of nodes is equal to " << _structure[i] << " ! must be >=1 !";
955         throw INTERP_KERNEL::Exception(oss.str().c_str());
956       }
957 }
958
959 void MEDCouplingIMesh::checkCoherency1(double eps) const
960 {
961   checkCoherency();
962 }
963
964 void MEDCouplingIMesh::checkCoherency2(double eps) const
965 {
966   checkCoherency1(eps);
967 }
968
969 void MEDCouplingIMesh::getNodeGridStructure(int *res) const
970 {
971   checkSpaceDimension();
972   std::copy(_structure,_structure+_space_dim,res);
973 }
974
975 std::vector<int> MEDCouplingIMesh::getNodeGridStructure() const
976 {
977   checkSpaceDimension();
978   std::vector<int> ret(_structure,_structure+_space_dim);
979   return ret;
980 }
981
982 MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
983 {
984   checkCoherency();
985   int dim(getSpaceDimension());
986   if(dim!=(int)cellPart.size())
987     {
988       std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !";
989       throw INTERP_KERNEL::Exception(oss.str().c_str());
990     }
991   double retOrigin[3]={0.,0.,0.};
992   int retStruct[3]={0,0,0};
993   MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(dynamic_cast<MEDCouplingIMesh *>(deepCpy()));
994   for(int i=0;i<dim;i++)
995     {
996       int startNode(cellPart[i].first),endNode(cellPart[i].second+1);
997       int myDelta(endNode-startNode);
998       if(startNode<0 || startNode>=_structure[i])
999         {
1000           std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : At dimension #" << i << " the start node id is " << startNode << " it should be in [0," << _structure[i] << ") !";
1001           throw INTERP_KERNEL::Exception(oss.str().c_str());
1002         }
1003       if(myDelta<0 || myDelta>_structure[i])
1004         {
1005           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;
1006           throw INTERP_KERNEL::Exception(oss.str().c_str());
1007         }
1008       retOrigin[i]=_origin[i]+startNode*_dxyz[i];
1009       retStruct[i]=myDelta;
1010     }
1011   ret->setNodeStruct(retStruct,retStruct+dim);
1012   ret->setOrigin(retOrigin,retOrigin+dim);
1013   ret->checkCoherency();
1014   return ret.retn();
1015 }
1016
1017 /*!
1018  * Return the space dimension of \a this.
1019  */
1020 int MEDCouplingIMesh::getSpaceDimension() const
1021 {
1022   return _space_dim;
1023 }
1024
1025 void MEDCouplingIMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
1026 {
1027   int tmp[3];
1028   int spaceDim(getSpaceDimension());
1029   getSplitNodeValues(tmp);
1030   int tmp2[3];
1031   GetPosFromId(nodeId,spaceDim,tmp,tmp2);
1032   for(int j=0;j<spaceDim;j++)
1033     coo.push_back(_origin[j]+_dxyz[j]*tmp2[j]);
1034 }
1035
1036 std::string MEDCouplingIMesh::simpleRepr() const
1037 {
1038   std::ostringstream ret;
1039   ret << "Image grid with name : \"" << getName() << "\"\n";
1040   ret << "Description of mesh : \"" << getDescription() << "\"\n";
1041   int tmpp1,tmpp2;
1042   double tt(getTime(tmpp1,tmpp2));
1043   int spaceDim(_space_dim);
1044   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
1045   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
1046   ret << "Space dimension : " << spaceDim << "\n";
1047   if(spaceDim<0 || spaceDim>3)
1048     return ret.str();
1049   ret << "The nodal structure is : "; std::copy(_structure,_structure+spaceDim,std::ostream_iterator<int>(ret," ")); ret << "\n";
1050   ret << "The origin position is [" << _axis_unit << "]: ";
1051   std::copy(_origin,_origin+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
1052   ret << "The intervals along axis are : ";
1053   std::copy(_dxyz,_dxyz+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
1054   return ret.str();
1055 }
1056
1057 std::string MEDCouplingIMesh::advancedRepr() const
1058 {
1059   return simpleRepr();
1060 }
1061
1062 void MEDCouplingIMesh::getBoundingBox(double *bbox) const
1063 {
1064   checkCoherency();
1065   int dim(getSpaceDimension());
1066   for(int idim=0; idim<dim; idim++)
1067     {
1068       bbox[2*idim]=_origin[idim];
1069       int coeff(_structure[idim]);
1070       if(_structure[idim]<0)
1071         {
1072           std::ostringstream oss; oss << "MEDCouplingIMesh::getBoundingBox : on axis #" << idim << " number of nodes in structure is < 0 !";
1073           throw INTERP_KERNEL::Exception(oss.str().c_str());
1074         }
1075       if(_structure[idim]>1)
1076         coeff=_structure[idim]-1;
1077       bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*coeff;
1078     }
1079 }
1080
1081 /*!
1082  * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
1083  * mesh.<br>
1084  * For 1D cells, the returned field contains lengths.<br>
1085  * For 2D cells, the returned field contains areas.<br>
1086  * For 3D cells, the returned field contains volumes.
1087  *  \param [in] isAbs - a not used parameter.
1088  *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
1089  *         and one time . The caller is to delete this field using decrRef() as it is no
1090  *         more needed.
1091  */
1092 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureField(bool isAbs) const
1093 {
1094   checkCoherency();
1095   std::string name="MeasureOfMesh_";
1096   name+=getName();
1097   int nbelem(getNumberOfCells());
1098   MEDCouplingFieldDouble *field(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
1099   field->setName(name);
1100   DataArrayDouble* array(DataArrayDouble::New());
1101   array->alloc(nbelem,1);
1102   array->fillWithValue(getMeasureOfAnyCell());
1103   field->setArray(array) ;
1104   array->decrRef();
1105   field->setMesh(const_cast<MEDCouplingIMesh *>(this));
1106   field->synchronizeTimeWithMesh();
1107   return field;
1108 }
1109
1110 /*!
1111  * not implemented yet !
1112  */
1113 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureFieldOnNode(bool isAbs) const
1114 {
1115   throw INTERP_KERNEL::Exception("MEDCouplingIMesh::getMeasureFieldOnNode : not implemented yet !");
1116   //return 0;
1117 }
1118
1119 int MEDCouplingIMesh::getCellContainingPoint(const double *pos, double eps) const
1120 {
1121   int dim(getSpaceDimension()),ret(0),coeff(1);
1122   for(int i=0;i<dim;i++)
1123     {
1124       int nbOfCells(_structure[i]-1);
1125       double ref(pos[i]);
1126       int tmp((int)((ref-_origin[i])/_dxyz[i]));
1127       if(tmp>=0 && tmp<nbOfCells)
1128         {
1129           ret+=coeff*tmp;
1130           coeff*=nbOfCells;
1131         }
1132       else
1133         return -1;
1134     }
1135   return ret;
1136 }
1137
1138 void MEDCouplingIMesh::rotate(const double *center, const double *vector, double angle)
1139 {
1140   throw INTERP_KERNEL::Exception("No rotation available on IMesh : Traduce it to unstructured mesh to apply it !");
1141 }
1142
1143 /*!
1144  * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
1145  * component of the \a vector to all node coordinates of a corresponding axis.
1146  *  \param [in] vector - the translation vector whose size must be not less than \a
1147  *         this->getSpaceDimension().
1148  */
1149 void MEDCouplingIMesh::translate(const double *vector)
1150 {
1151   checkSpaceDimension();
1152   int dim(getSpaceDimension());
1153   std::transform(_origin,_origin+dim,vector,_origin,std::plus<double>());
1154   declareAsNew();
1155 }
1156
1157 /*!
1158  * Applies scaling transformation to all nodes of \a this mesh.
1159  *  \param [in] point - coordinates of a scaling center. This array is to be of
1160  *         size \a this->getSpaceDimension() at least.
1161  *  \param [in] factor - a scale factor.
1162  */
1163 void MEDCouplingIMesh::scale(const double *point, double factor)
1164 {
1165   checkSpaceDimension();
1166   int dim(getSpaceDimension());
1167   std::transform(_origin,_origin+dim,point,_origin,std::minus<double>());
1168   std::transform(_origin,_origin+dim,_origin,std::bind2nd(std::multiplies<double>(),factor));
1169   std::transform(_dxyz,_dxyz+dim,_dxyz,std::bind2nd(std::multiplies<double>(),factor));
1170   std::transform(_origin,_origin+dim,point,_origin,std::plus<double>());
1171   declareAsNew();
1172 }
1173
1174 MEDCouplingMesh *MEDCouplingIMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
1175 {
1176   //not implemented yet !
1177   return 0;
1178 }
1179
1180 /*!
1181  * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
1182  *  \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1183  *          this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
1184  *          components. The caller is to delete this array using decrRef() as it is
1185  *          no more needed.
1186  */
1187 DataArrayDouble *MEDCouplingIMesh::getCoordinatesAndOwner() const
1188 {
1189   checkCoherency();
1190   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1191   int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
1192   ret->alloc(nbNodes,spaceDim);
1193   double *pt(ret->getPointer());
1194   ret->setInfoOnComponents(buildInfoOnComponents());
1195   int tmp2[3],tmp[3];
1196   getSplitNodeValues(tmp);
1197   for(int i=0;i<nbNodes;i++)
1198     {
1199       GetPosFromId(i,spaceDim,tmp,tmp2);
1200       for(int j=0;j<spaceDim;j++)
1201         pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+_origin[j];
1202     }
1203   return ret.retn();
1204 }
1205
1206 /*!
1207  * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
1208  * computed by averaging coordinates of cell nodes.
1209  *  \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1210  *          this->getNumberOfCells() tuples per \a this->getSpaceDimension()
1211  *          components. The caller is to delete this array using decrRef() as it is
1212  *          no more needed.
1213  */
1214 DataArrayDouble *MEDCouplingIMesh::getBarycenterAndOwner() const
1215 {
1216   checkCoherency();
1217   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1218   int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()),tmp[3],tmp2[3];
1219   ret->alloc(nbCells,spaceDim);
1220   double *pt(ret->getPointer()),shiftOrigin[3];
1221   std::transform(_dxyz,_dxyz+spaceDim,shiftOrigin,std::bind2nd(std::multiplies<double>(),0.5));
1222   std::transform(_origin,_origin+spaceDim,shiftOrigin,shiftOrigin,std::plus<double>());
1223   getSplitCellValues(tmp);
1224   ret->setInfoOnComponents(buildInfoOnComponents());
1225   for(int i=0;i<nbCells;i++)
1226     {
1227       GetPosFromId(i,spaceDim,tmp,tmp2);
1228       for(int j=0;j<spaceDim;j++)
1229         pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+shiftOrigin[j];
1230     }
1231   return ret.retn();
1232 }
1233
1234 DataArrayDouble *MEDCouplingIMesh::computeIsoBarycenterOfNodesPerCell() const
1235 {
1236   return MEDCouplingIMesh::getBarycenterAndOwner();
1237 }
1238
1239 void MEDCouplingIMesh::renumberCells(const int *old2NewBg, bool check)
1240 {
1241   throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for IMesh !");
1242 }
1243
1244 void MEDCouplingIMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1245 {
1246   int it,order;
1247   double time(getTime(it,order));
1248   tinyInfo.clear();
1249   tinyInfoD.clear();
1250   littleStrings.clear();
1251   littleStrings.push_back(getName());
1252   littleStrings.push_back(getDescription());
1253   littleStrings.push_back(getTimeUnit());
1254   littleStrings.push_back(getAxisUnit());
1255   tinyInfo.push_back(it);
1256   tinyInfo.push_back(order);
1257   tinyInfo.push_back(_space_dim);
1258   tinyInfo.insert(tinyInfo.end(),_structure,_structure+3);
1259   tinyInfoD.push_back(time);
1260   tinyInfoD.insert(tinyInfoD.end(),_dxyz,_dxyz+3);
1261   tinyInfoD.insert(tinyInfoD.end(),_origin,_origin+3);
1262 }
1263
1264 void MEDCouplingIMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1265 {
1266   a1->alloc(0,1);
1267   a2->alloc(0,1);
1268 }
1269
1270 void MEDCouplingIMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1271 {
1272   a1=DataArrayInt::New();
1273   a1->alloc(0,1);
1274   a2=DataArrayDouble::New();
1275   a2->alloc(0,1);
1276 }
1277
1278 void MEDCouplingIMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1279                                        const std::vector<std::string>& littleStrings)
1280 {
1281   setName(littleStrings[0]);
1282   setDescription(littleStrings[1]);
1283   setTimeUnit(littleStrings[2]);
1284   setAxisUnit(littleStrings[3]);
1285   setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]);
1286   _space_dim=tinyInfo[2];
1287   _structure[0]=tinyInfo[3]; _structure[1]=tinyInfo[4]; _structure[2]=tinyInfo[5];
1288   _dxyz[0]=tinyInfoD[1]; _dxyz[1]=tinyInfoD[2]; _dxyz[2]=tinyInfoD[3];
1289   _origin[0]=tinyInfoD[4]; _origin[1]=tinyInfoD[5]; _origin[2]=tinyInfoD[6];
1290   declareAsNew();
1291 }
1292
1293 void MEDCouplingIMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
1294 {
1295   checkCoherency();
1296   std::ostringstream extent,origin,spacing;
1297   for(int i=0;i<3;i++)
1298     {
1299       if(i<_space_dim)
1300         { extent << "0 " <<  _structure[i]-1 << " "; origin << _origin[i] << " "; spacing << _dxyz[i] << " "; }
1301       else
1302         { extent << "0 0 "; origin << "0 "; spacing << "0 "; }
1303     }
1304   ofs << "  <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\" Origin=\"" << origin.str() << "\" Spacing=\"" << spacing.str() << "\">\n";
1305   ofs << "    <Piece Extent=\"" << extent.str() << "\">\n";
1306   ofs << "      <PointData>\n" << pointData << std::endl;
1307   ofs << "      </PointData>\n";
1308   ofs << "      <CellData>\n" << cellData << std::endl;
1309   ofs << "      </CellData>\n";
1310   ofs << "      <Coordinates>\n";
1311   ofs << "      </Coordinates>\n";
1312   ofs << "    </Piece>\n";
1313   ofs << "  </" << getVTKDataSetType() << ">\n";
1314 }
1315
1316 void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const
1317 {
1318   stream << "MEDCouplingIMesh C++ instance at " << this << ". Name : \"" << getName() << "\". Space dimension : " << _space_dim << ".";
1319   if(_space_dim<0 || _space_dim>3)
1320     return ;
1321   stream << "\n";
1322   std::ostringstream stream0,stream1;
1323   int nbNodes(1),nbCells(0);
1324   bool isPb(false);
1325   for(int i=0;i<_space_dim;i++)
1326     {
1327       char tmp('X'+i);
1328       int tmpNodes(_structure[i]);
1329       stream1 << "- Axis " << tmp << " : " << tmpNodes << " nodes (orig=" << _origin[i] << ", inter=" << _dxyz[i] << ").";
1330       if(i!=_space_dim-1)
1331         stream1 << std::endl;
1332       if(tmpNodes>=1)
1333         nbNodes*=tmpNodes;
1334       else
1335         isPb=true;
1336       if(tmpNodes>=2)
1337         nbCells=nbCells==0?tmpNodes-1:nbCells*(tmpNodes-1);
1338     }
1339   if(!isPb)
1340     {
1341       stream0 << "Number of cells : " << nbCells << ", Number of nodes : " << nbNodes;
1342       stream << stream0.str();
1343       if(_space_dim>0)
1344         stream << std::endl;
1345     }
1346   stream << stream1.str();
1347 }
1348
1349 std::string MEDCouplingIMesh::getVTKDataSetType() const
1350 {
1351   return std::string("ImageData");
1352 }
1353
1354 std::vector<std::string> MEDCouplingIMesh::buildInfoOnComponents() const
1355 {
1356   checkSpaceDimension();
1357   int dim(getSpaceDimension());
1358   std::vector<std::string> ret(dim);
1359   for(int i=0;i<dim;i++)
1360     {
1361       std::ostringstream oss;
1362       char tmp('X'+i); oss << tmp;
1363       ret[i]=DataArray::BuildInfoFromVarAndUnit(oss.str(),_axis_unit);
1364     }
1365   return ret;
1366 }
1367
1368 void MEDCouplingIMesh::checkSpaceDimension() const
1369 {
1370   CheckSpaceDimension(_space_dim);
1371 }
1372
1373 void MEDCouplingIMesh::CheckSpaceDimension(int spaceDim)
1374 {
1375   if(spaceDim<0 || spaceDim>3)
1376     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CheckSpaceDimension : input spaceDim must be in [0,1,2,3] !");
1377 }
1378
1379 int MEDCouplingIMesh::FindIntRoot(int val, int order)
1380 {
1381   if(order==0)
1382     return 1;
1383   if(val<0)
1384     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : input val is < 0 ! Not possible to compute a root !");
1385   if(order==1)
1386     return val;
1387   if(order!=2 && order!=3)
1388     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the order available are 0,1,2 or 3 !");
1389   double valf((double)val);
1390   if(order==2)
1391     {
1392       double retf(sqrt(valf));
1393       int ret((int)retf);
1394       if(ret*ret!=val)
1395         throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect square root !");
1396       return ret;
1397     }
1398   else//order==3
1399     {
1400       double retf(std::pow(val,0.3333333333333333));
1401       int ret((int)retf),ret2(ret+1);
1402       if(ret*ret*ret!=val && ret2*ret2*ret2!=val)
1403         throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect cublic root !");
1404       if(ret*ret*ret==val)
1405         return ret;
1406       else
1407         return ret2;
1408     }
1409 }