]> SALOME platform Git repositories - modules/med.git/blob - src/MEDCoupling/MEDCouplingIMesh.cxx
Salome HOME
d26364a52ce96f3f367d398de71313bb126d95a1
[modules/med.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     case 3:
488       {
489         int nxwg(coarseSt[0]+2*ghostSize),nxywg((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize));
490         int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)+nxywg*(fineLocInCoarse[2].first+ghostSize)),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]);
491         inPtr+=(dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)*ghostSize*nbCompo;
492         for(int k=0;k<dims[2];k++)
493           {
494             for(int kfact=0;kfact<fact2;kfact++)
495               {
496                 inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo;
497                 for(int j=0;j<dims[1];j++)
498                   {
499                     int kky(j*nxwg);
500                     for(int jfact=0;jfact<fact1;jfact++)
501                       {
502                         inPtr+=ghostSize*nbCompo;
503                         for(int i=0;i<dims[0];i++)
504                           {
505                             double *loc(outPtr+(kky+kk+i)*nbCompo);
506                             for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo)
507                               {
508                                 if(kfact!=0 || jfact!=0 || ifact!=0)
509                                   std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>());
510                                 else
511                                   std::copy(inPtr,inPtr+nbCompo,loc);
512                               }
513                           }
514                         inPtr+=ghostSize*nbCompo;
515                       }
516                   }
517                 inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo;
518               }
519             kk+=nxywg;
520           }
521         break;
522       }
523     default:
524       throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2, 3 supported !");
525   }
526 }
527
528 /*!
529  * This method spreads the values of coarse data \a coarseDA into \a fineDA.
530  *
531  * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
532  * \param [in] coarseSt The cell structure of coarse mesh.
533  * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
534  * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
535  * \param [in] facts The refinement coefficient per axis.
536  * \sa SpreadCoarseToFineGhost, CondenseFineToCoarse
537  */
538 void MEDCouplingIMesh::SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts)
539 {
540   if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
541       throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !");
542   if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
543     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !");
544   int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
545   int nbCompo(fineDA->getNumberOfComponents());
546   if(coarseDA->getNumberOfComponents()!=nbCompo)
547     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the number of components of fine DA and coarse one mismatches !");
548   if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
549     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
550   if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
551     {
552       std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
553       throw INTERP_KERNEL::Exception(oss.str().c_str());
554     }
555   int nbTuplesFine(fineDA->getNumberOfTuples());
556   if(nbTuplesFine%nbOfTuplesInFineExp!=0)
557     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : Invalid nb of tuples in fine DataArray regarding its structure !");
558   int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
559   if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
560     {
561       std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Invalid number of tuples ("  << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
562       throw INTERP_KERNEL::Exception(oss.str().c_str());
563     }
564   // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom
565   double *outPtr(fineDA->getPointer());
566   const double *inPtr(coarseDA->begin());
567   //
568   std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
569   switch(meshDim)
570   {
571     case 1:
572       {
573         int offset(fineLocInCoarse[0].first),fact0(facts[0]);
574         for(int i=0;i<dims[0];i++)
575           {
576             const double *loc(inPtr+(offset+i)*nbCompo);
577             for(int ifact=0;ifact<fact0;ifact++)
578               outPtr=std::copy(loc,loc+nbCompo,outPtr);
579           }
580         break;
581       }
582     case 2:
583       {
584         int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact0(facts[0]),fact1(facts[1]);
585         for(int j=0;j<dims[1];j++)
586           {
587             for(int jfact=0;jfact<fact1;jfact++)
588               {
589                 for(int i=0;i<dims[0];i++)
590                   {
591                     const double *loc(inPtr+(kk+i)*nbCompo);
592                     for(int ifact=0;ifact<fact0;ifact++)
593                       outPtr=std::copy(loc,loc+nbCompo,outPtr);
594                   }
595               }
596             kk+=coarseSt[0];
597           }
598         break;
599       }
600     case 3:
601       {
602         int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first+coarseSt[0]*coarseSt[1]*fineLocInCoarse[2].first),fact0(facts[0]),fact1(facts[2]),fact2(facts[2]);
603         for(int k=0;k<dims[2];k++)
604           {
605             for(int kfact=0;kfact<fact2;kfact++)
606               {
607                 for(int j=0;j<dims[1];j++)
608                   {
609                     for(int jfact=0;jfact<fact1;jfact++)
610                       {
611                         for(int i=0;i<dims[0];i++)
612                           {
613                             const double *loc(inPtr+(kk+i+j*coarseSt[0])*nbCompo);
614                             for(int ifact=0;ifact<fact0;ifact++)
615                               outPtr=std::copy(loc,loc+nbCompo,outPtr);
616                           }
617                       }
618                   }
619               }
620             kk+=coarseSt[0]*coarseSt[1];
621           }
622         break;
623       }
624     default:
625       throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : only dimensions 1, 2 and 3 supported !");
626   }
627 }
628
629 /*!
630  * This method spreads the values of coarse data \a coarseDA into \a fineDA.
631  *
632  * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
633  * \param [in] coarseSt The cell structure of coarse mesh.
634  * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
635  * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
636  * \param [in] facts The refinement coefficient per axis.
637  * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
638  *
639  * \sa CondenseFineToCoarse, SpreadCoarseToFineGhostZone
640  */
641 void MEDCouplingIMesh::SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
642 {
643   if(ghostSize<0)
644     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level has to be >= 0 !");
645   if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
646     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !");
647   if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
648     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !");
649   std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
650   int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
651   int nbCompo(fineDA->getNumberOfComponents());
652   if(coarseDA->getNumberOfComponents()!=nbCompo)
653     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the number of components of fine DA and coarse one mismatches !");
654   if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
655     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
656   if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
657     {
658       std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
659       throw INTERP_KERNEL::Exception(oss.str().c_str());
660     }
661   //
662   std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
663   std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
664   std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
665   int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
666   if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
667     {
668       std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
669       throw INTERP_KERNEL::Exception(oss.str().c_str());
670     }
671   //
672   double *outPtr(fineDA->getPointer());
673   const double *inPtr(coarseDA->begin());
674   //
675   switch(meshDim)
676   {
677     case 1:
678       {
679         std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
680         int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
681         for(int i=0;i<ghostSize;i++)
682           outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
683         offset=fineLocInCoarse[0].first+ghostSize;
684         for(int i=0;i<dims[0];i++)
685           {
686             const double *loc(inPtr+(offset+i)*nbCompo);
687             for(int ifact=0;ifact<fact0;ifact++)
688               outPtr=std::copy(loc,loc+nbCompo,outPtr);
689           }
690         offset=fineLocInCoarse[0].second+ghostSize;
691         for(int i=0;i<ghostSize;i++)
692           outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
693         break;
694       }
695     case 2:
696       {
697         SpreadCoarseToFineGhost2D(inPtr,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
698         break;
699       }
700     case 3:
701       {
702         std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
703         int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]);
704         int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize));
705         int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 !
706         for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
707           SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
708         offset+=nxyWgCoarse;
709         for(int i=0;i<dims[2];i++,offset+=nxyWgCoarse)
710           for(int j=0;j<fact2;j++,outPtr+=nxyWgFine*nbCompo)
711             SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
712         for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo)
713           SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize);
714         break;
715       }
716     default:
717       throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : only dimensions 1, 2, 3 supported !");
718   }
719 }
720
721 /*!
722  * This method spreads the values of coarse data \a coarseDA into \a fineDA \b ONLY \b in \b the \b ghost \b zone (contrary to SpreadCoarseToFineGhost that spread the values everywhere).
723  *
724  * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt.
725  * \param [in] coarseSt The cell structure of coarse mesh.
726  * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh
727  * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one.
728  * \param [in] facts The refinement coefficient per axis.
729  * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes.
730  *
731  * \sa SpreadCoarseToFineGhost
732  */
733 void MEDCouplingIMesh::SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
734 {
735   if(ghostSize<0)
736     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : ghost level has to be >= 0 !");
737   if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
738     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : All input vectors (dimension) must have the same size !");
739   if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
740     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the parameters 1 or 3 are NULL or not allocated !");
741   std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
742   int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
743   int nbCompo(fineDA->getNumberOfComponents());
744   if(coarseDA->getNumberOfComponents()!=nbCompo)
745     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the number of components of fine DA and coarse one mismatches !");
746   if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size())
747     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
748   if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
749     {
750       std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
751       throw INTERP_KERNEL::Exception(oss.str().c_str());
752     }
753   //
754   std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
755   std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
756   std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
757   int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
758   if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
759     {
760       std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
761       throw INTERP_KERNEL::Exception(oss.str().c_str());
762     }
763   //
764   double *outPtr(fineDA->getPointer());
765   const double *inPtr(coarseDA->begin());
766   //
767   std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
768   switch(meshDim)
769   {
770     case 1:
771       {
772         int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 !
773         for(int i=0;i<ghostSize;i++)
774           outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
775         outPtr+=nbCompo*fact0*dims[0];
776         offset=fineLocInCoarse[0].second+ghostSize;
777         for(int i=0;i<ghostSize;i++)
778           outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr);
779         break;
780       }
781     case 2:
782       {
783         int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
784         int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
785         for(int jg=0;jg<ghostSize;jg++)
786           {
787             for(int ig=0;ig<ghostSize;ig++)
788               outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
789             int kk0(kk+1);
790             for(int ig=0;ig<dims[0];ig++,kk0++)
791               for(int ifact=0;ifact<fact0;ifact++)
792                 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
793             for(int ik=0;ik<ghostSize;ik++)
794               outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
795           }
796         for(int j=0;j<dims[1];j++)
797           {
798             kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
799             for(int jfact=0;jfact<fact1;jfact++)
800               {
801                 for(int ig=0;ig<ghostSize;ig++)
802                   outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
803                 int kk0(kk+1+dims[0]);//1 not ghost. We make the hypothesis that factors is >= ghostlev
804                 outPtr+=fact0*nbCompo*dims[0];
805                 for(int ig=0;ig<ghostSize;ig++)
806                   outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
807               }
808           }
809         kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
810         for(int jg=0;jg<ghostSize;jg++)
811           {
812             for(int ig=0;ig<ghostSize;ig++)
813               outPtr=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr);
814             int kk0(kk+1);
815             for(int ig=0;ig<dims[0];ig++,kk0++)
816               for(int ifact=0;ifact<fact0;ifact++)
817                 outPtr=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
818             for(int ik=0;ik<ghostSize;ik++)
819               outPtr=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr);
820           }
821         break;
822       }
823     default:
824       throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : only dimensions 1, 2 supported !");
825   }
826 }
827
828 void MEDCouplingIMesh::setSpaceDimension(int spaceDim)
829 {
830   if(spaceDim==_space_dim)
831     return ;
832   CheckSpaceDimension(spaceDim);
833   _space_dim=spaceDim;
834   declareAsNew();
835 }
836
837 void MEDCouplingIMesh::updateTime() const
838 {
839 }
840
841 std::size_t MEDCouplingIMesh::getHeapMemorySizeWithoutChildren() const
842 {
843   return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
844 }
845
846 std::vector<const BigMemoryObject *> MEDCouplingIMesh::getDirectChildren() const
847 {
848   return std::vector<const BigMemoryObject *>();
849 }
850
851 /*!
852  * This method copyies all tiny strings from other (name and components name).
853  * @throw if other and this have not same mesh type.
854  */
855 void MEDCouplingIMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
856
857   const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
858   if(!otherC)
859     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::copyTinyStringsFrom : meshes have not same type !");
860   MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
861   declareAsNew();
862 }
863
864 bool MEDCouplingIMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
865 {
866   if(!other)
867     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::isEqualIfNotWhy : input other pointer is null !");
868   const MEDCouplingIMesh *otherC(dynamic_cast<const MEDCouplingIMesh *>(other));
869   if(!otherC)
870     {
871       reason="mesh given in input is not castable in MEDCouplingIMesh !";
872       return false;
873     }
874   if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
875     return false;
876   if(!isEqualWithoutConsideringStrInternal(otherC,prec,reason))
877     return false;
878   if(_axis_unit!=otherC->_axis_unit)
879     {
880       reason="The units of axis are not the same !";
881       return false;
882     }
883   return true;
884 }
885
886 bool MEDCouplingIMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
887 {
888   const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
889   if(!otherC)
890     return false;
891   std::string tmp;
892   return isEqualWithoutConsideringStrInternal(other,prec,tmp);
893 }
894
895 bool MEDCouplingIMesh::isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const
896 {
897   const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other);
898   if(!otherC)
899     return false;
900   if(_space_dim!=otherC->_space_dim)
901     {
902       std::ostringstream oss;
903       oss << "The spaceDimension of this (" << _space_dim << ") is not equal to those of other (" << otherC->_space_dim << ") !";
904       return false;
905     }
906   checkSpaceDimension();
907   for(int i=0;i<_space_dim;i++)
908     {
909       if(fabs(_origin[i]-otherC->_origin[i])>prec)
910         {
911           std::ostringstream oss;
912           oss << "The origin 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(fabs(_dxyz[i]-otherC->_dxyz[i])>prec)
920         {
921           std::ostringstream oss;
922           oss << "The delta of this and other differs at " << i << " !";
923           reason=oss.str();
924           return false;
925         }
926     }
927   for(int i=0;i<_space_dim;i++)
928     {
929       if(_structure[i]!=otherC->_structure[i])
930         {
931           std::ostringstream oss;
932           oss << "The structure of this and other differs at " << i << " !";
933           reason=oss.str();
934           return false;
935         }
936     }
937   return true;
938 }
939
940 void MEDCouplingIMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
941                                             DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
942 {
943   if(!isEqualWithoutConsideringStr(other,prec))
944     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalWith : Meshes are not the same !");
945 }
946
947 /*!
948  * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingIMesh instance too).
949  * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingIMesh, \a this and \a other are the same !
950  */
951 void MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
952                                                        DataArrayInt *&cellCor) const
953 {
954   if(!isEqualWithoutConsideringStr(other,prec))
955     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
956 }
957
958 void MEDCouplingIMesh::checkCoherency() const
959 {
960   checkSpaceDimension();
961   for(int i=0;i<_space_dim;i++)
962     if(_structure[i]<1)
963       {
964         std::ostringstream oss; oss << "MEDCouplingIMesh::checkCoherency : On axis " << i << "/" << _space_dim << ", number of nodes is equal to " << _structure[i] << " ! must be >=1 !";
965         throw INTERP_KERNEL::Exception(oss.str().c_str());
966       }
967 }
968
969 void MEDCouplingIMesh::checkCoherency1(double eps) const
970 {
971   checkCoherency();
972 }
973
974 void MEDCouplingIMesh::checkCoherency2(double eps) const
975 {
976   checkCoherency1(eps);
977 }
978
979 void MEDCouplingIMesh::getNodeGridStructure(int *res) const
980 {
981   checkSpaceDimension();
982   std::copy(_structure,_structure+_space_dim,res);
983 }
984
985 std::vector<int> MEDCouplingIMesh::getNodeGridStructure() const
986 {
987   checkSpaceDimension();
988   std::vector<int> ret(_structure,_structure+_space_dim);
989   return ret;
990 }
991
992 MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
993 {
994   checkCoherency();
995   int dim(getSpaceDimension());
996   if(dim!=(int)cellPart.size())
997     {
998       std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !";
999       throw INTERP_KERNEL::Exception(oss.str().c_str());
1000     }
1001   double retOrigin[3]={0.,0.,0.};
1002   int retStruct[3]={0,0,0};
1003   MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(dynamic_cast<MEDCouplingIMesh *>(deepCpy()));
1004   for(int i=0;i<dim;i++)
1005     {
1006       int startNode(cellPart[i].first),endNode(cellPart[i].second+1);
1007       int myDelta(endNode-startNode);
1008       if(startNode<0 || startNode>=_structure[i])
1009         {
1010           std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : At dimension #" << i << " the start node id is " << startNode << " it should be in [0," << _structure[i] << ") !";
1011           throw INTERP_KERNEL::Exception(oss.str().c_str());
1012         }
1013       if(myDelta<0 || myDelta>_structure[i])
1014         {
1015           std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : Along dimension #" << i << " the number of nodes is " << _structure[i] << ", and you are requesting for " << myDelta << " nodes wide range !" << std::endl;
1016           throw INTERP_KERNEL::Exception(oss.str().c_str());
1017         }
1018       retOrigin[i]=_origin[i]+startNode*_dxyz[i];
1019       retStruct[i]=myDelta;
1020     }
1021   ret->setNodeStruct(retStruct,retStruct+dim);
1022   ret->setOrigin(retOrigin,retOrigin+dim);
1023   ret->checkCoherency();
1024   return ret.retn();
1025 }
1026
1027 /*!
1028  * Return the space dimension of \a this.
1029  */
1030 int MEDCouplingIMesh::getSpaceDimension() const
1031 {
1032   return _space_dim;
1033 }
1034
1035 void MEDCouplingIMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
1036 {
1037   int tmp[3];
1038   int spaceDim(getSpaceDimension());
1039   getSplitNodeValues(tmp);
1040   int tmp2[3];
1041   GetPosFromId(nodeId,spaceDim,tmp,tmp2);
1042   for(int j=0;j<spaceDim;j++)
1043     coo.push_back(_origin[j]+_dxyz[j]*tmp2[j]);
1044 }
1045
1046 std::string MEDCouplingIMesh::simpleRepr() const
1047 {
1048   std::ostringstream ret;
1049   ret << "Image grid with name : \"" << getName() << "\"\n";
1050   ret << "Description of mesh : \"" << getDescription() << "\"\n";
1051   int tmpp1,tmpp2;
1052   double tt(getTime(tmpp1,tmpp2));
1053   int spaceDim(_space_dim);
1054   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
1055   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
1056   ret << "Space dimension : " << spaceDim << "\n";
1057   if(spaceDim<0 || spaceDim>3)
1058     return ret.str();
1059   ret << "The nodal structure is : "; std::copy(_structure,_structure+spaceDim,std::ostream_iterator<int>(ret," ")); ret << "\n";
1060   ret << "The origin position is [" << _axis_unit << "]: ";
1061   std::copy(_origin,_origin+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
1062   ret << "The intervals along axis are : ";
1063   std::copy(_dxyz,_dxyz+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n";
1064   return ret.str();
1065 }
1066
1067 std::string MEDCouplingIMesh::advancedRepr() const
1068 {
1069   return simpleRepr();
1070 }
1071
1072 void MEDCouplingIMesh::getBoundingBox(double *bbox) const
1073 {
1074   checkCoherency();
1075   int dim(getSpaceDimension());
1076   for(int idim=0; idim<dim; idim++)
1077     {
1078       bbox[2*idim]=_origin[idim];
1079       int coeff(_structure[idim]);
1080       if(_structure[idim]<0)
1081         {
1082           std::ostringstream oss; oss << "MEDCouplingIMesh::getBoundingBox : on axis #" << idim << " number of nodes in structure is < 0 !";
1083           throw INTERP_KERNEL::Exception(oss.str().c_str());
1084         }
1085       if(_structure[idim]>1)
1086         coeff=_structure[idim]-1;
1087       bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*coeff;
1088     }
1089 }
1090
1091 /*!
1092  * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
1093  * mesh.<br>
1094  * For 1D cells, the returned field contains lengths.<br>
1095  * For 2D cells, the returned field contains areas.<br>
1096  * For 3D cells, the returned field contains volumes.
1097  *  \param [in] isAbs - a not used parameter.
1098  *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
1099  *         and one time . The caller is to delete this field using decrRef() as it is no
1100  *         more needed.
1101  */
1102 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureField(bool isAbs) const
1103 {
1104   checkCoherency();
1105   std::string name="MeasureOfMesh_";
1106   name+=getName();
1107   int nbelem(getNumberOfCells());
1108   MEDCouplingFieldDouble *field(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME));
1109   field->setName(name);
1110   DataArrayDouble* array(DataArrayDouble::New());
1111   array->alloc(nbelem,1);
1112   array->fillWithValue(getMeasureOfAnyCell());
1113   field->setArray(array) ;
1114   array->decrRef();
1115   field->setMesh(const_cast<MEDCouplingIMesh *>(this));
1116   field->synchronizeTimeWithMesh();
1117   return field;
1118 }
1119
1120 /*!
1121  * not implemented yet !
1122  */
1123 MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureFieldOnNode(bool isAbs) const
1124 {
1125   throw INTERP_KERNEL::Exception("MEDCouplingIMesh::getMeasureFieldOnNode : not implemented yet !");
1126   //return 0;
1127 }
1128
1129 int MEDCouplingIMesh::getCellContainingPoint(const double *pos, double eps) const
1130 {
1131   int dim(getSpaceDimension()),ret(0),coeff(1);
1132   for(int i=0;i<dim;i++)
1133     {
1134       int nbOfCells(_structure[i]-1);
1135       double ref(pos[i]);
1136       int tmp((int)((ref-_origin[i])/_dxyz[i]));
1137       if(tmp>=0 && tmp<nbOfCells)
1138         {
1139           ret+=coeff*tmp;
1140           coeff*=nbOfCells;
1141         }
1142       else
1143         return -1;
1144     }
1145   return ret;
1146 }
1147
1148 void MEDCouplingIMesh::rotate(const double *center, const double *vector, double angle)
1149 {
1150   throw INTERP_KERNEL::Exception("No rotation available on IMesh : Traduce it to unstructured mesh to apply it !");
1151 }
1152
1153 /*!
1154  * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
1155  * component of the \a vector to all node coordinates of a corresponding axis.
1156  *  \param [in] vector - the translation vector whose size must be not less than \a
1157  *         this->getSpaceDimension().
1158  */
1159 void MEDCouplingIMesh::translate(const double *vector)
1160 {
1161   checkSpaceDimension();
1162   int dim(getSpaceDimension());
1163   std::transform(_origin,_origin+dim,vector,_origin,std::plus<double>());
1164   declareAsNew();
1165 }
1166
1167 /*!
1168  * Applies scaling transformation to all nodes of \a this mesh.
1169  *  \param [in] point - coordinates of a scaling center. This array is to be of
1170  *         size \a this->getSpaceDimension() at least.
1171  *  \param [in] factor - a scale factor.
1172  */
1173 void MEDCouplingIMesh::scale(const double *point, double factor)
1174 {
1175   checkSpaceDimension();
1176   int dim(getSpaceDimension());
1177   std::transform(_origin,_origin+dim,point,_origin,std::minus<double>());
1178   std::transform(_origin,_origin+dim,_origin,std::bind2nd(std::multiplies<double>(),factor));
1179   std::transform(_dxyz,_dxyz+dim,_dxyz,std::bind2nd(std::multiplies<double>(),factor));
1180   std::transform(_origin,_origin+dim,point,_origin,std::plus<double>());
1181   declareAsNew();
1182 }
1183
1184 MEDCouplingMesh *MEDCouplingIMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
1185 {
1186   //not implemented yet !
1187   return 0;
1188 }
1189
1190 /*!
1191  * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
1192  *  \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1193  *          this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
1194  *          components. The caller is to delete this array using decrRef() as it is
1195  *          no more needed.
1196  */
1197 DataArrayDouble *MEDCouplingIMesh::getCoordinatesAndOwner() const
1198 {
1199   checkCoherency();
1200   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1201   int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
1202   ret->alloc(nbNodes,spaceDim);
1203   double *pt(ret->getPointer());
1204   ret->setInfoOnComponents(buildInfoOnComponents());
1205   int tmp2[3],tmp[3];
1206   getSplitNodeValues(tmp);
1207   for(int i=0;i<nbNodes;i++)
1208     {
1209       GetPosFromId(i,spaceDim,tmp,tmp2);
1210       for(int j=0;j<spaceDim;j++)
1211         pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+_origin[j];
1212     }
1213   return ret.retn();
1214 }
1215
1216 /*!
1217  * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
1218  * computed by averaging coordinates of cell nodes.
1219  *  \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
1220  *          this->getNumberOfCells() tuples per \a this->getSpaceDimension()
1221  *          components. The caller is to delete this array using decrRef() as it is
1222  *          no more needed.
1223  */
1224 DataArrayDouble *MEDCouplingIMesh::getBarycenterAndOwner() const
1225 {
1226   checkCoherency();
1227   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1228   int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()),tmp[3],tmp2[3];
1229   ret->alloc(nbCells,spaceDim);
1230   double *pt(ret->getPointer()),shiftOrigin[3];
1231   std::transform(_dxyz,_dxyz+spaceDim,shiftOrigin,std::bind2nd(std::multiplies<double>(),0.5));
1232   std::transform(_origin,_origin+spaceDim,shiftOrigin,shiftOrigin,std::plus<double>());
1233   getSplitCellValues(tmp);
1234   ret->setInfoOnComponents(buildInfoOnComponents());
1235   for(int i=0;i<nbCells;i++)
1236     {
1237       GetPosFromId(i,spaceDim,tmp,tmp2);
1238       for(int j=0;j<spaceDim;j++)
1239         pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+shiftOrigin[j];
1240     }
1241   return ret.retn();
1242 }
1243
1244 DataArrayDouble *MEDCouplingIMesh::computeIsoBarycenterOfNodesPerCell() const
1245 {
1246   return MEDCouplingIMesh::getBarycenterAndOwner();
1247 }
1248
1249 void MEDCouplingIMesh::renumberCells(const int *old2NewBg, bool check)
1250 {
1251   throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for IMesh !");
1252 }
1253
1254 void MEDCouplingIMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
1255 {
1256   int it,order;
1257   double time(getTime(it,order));
1258   tinyInfo.clear();
1259   tinyInfoD.clear();
1260   littleStrings.clear();
1261   littleStrings.push_back(getName());
1262   littleStrings.push_back(getDescription());
1263   littleStrings.push_back(getTimeUnit());
1264   littleStrings.push_back(getAxisUnit());
1265   tinyInfo.push_back(it);
1266   tinyInfo.push_back(order);
1267   tinyInfo.push_back(_space_dim);
1268   tinyInfo.insert(tinyInfo.end(),_structure,_structure+3);
1269   tinyInfoD.push_back(time);
1270   tinyInfoD.insert(tinyInfoD.end(),_dxyz,_dxyz+3);
1271   tinyInfoD.insert(tinyInfoD.end(),_origin,_origin+3);
1272 }
1273
1274 void MEDCouplingIMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
1275 {
1276   a1->alloc(0,1);
1277   a2->alloc(0,1);
1278 }
1279
1280 void MEDCouplingIMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
1281 {
1282   a1=DataArrayInt::New();
1283   a1->alloc(0,1);
1284   a2=DataArrayDouble::New();
1285   a2->alloc(0,1);
1286 }
1287
1288 void MEDCouplingIMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
1289                                        const std::vector<std::string>& littleStrings)
1290 {
1291   setName(littleStrings[0]);
1292   setDescription(littleStrings[1]);
1293   setTimeUnit(littleStrings[2]);
1294   setAxisUnit(littleStrings[3]);
1295   setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]);
1296   _space_dim=tinyInfo[2];
1297   _structure[0]=tinyInfo[3]; _structure[1]=tinyInfo[4]; _structure[2]=tinyInfo[5];
1298   _dxyz[0]=tinyInfoD[1]; _dxyz[1]=tinyInfoD[2]; _dxyz[2]=tinyInfoD[3];
1299   _origin[0]=tinyInfoD[4]; _origin[1]=tinyInfoD[5]; _origin[2]=tinyInfoD[6];
1300   declareAsNew();
1301 }
1302
1303 void MEDCouplingIMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
1304 {
1305   checkCoherency();
1306   std::ostringstream extent,origin,spacing;
1307   for(int i=0;i<3;i++)
1308     {
1309       if(i<_space_dim)
1310         { extent << "0 " <<  _structure[i]-1 << " "; origin << _origin[i] << " "; spacing << _dxyz[i] << " "; }
1311       else
1312         { extent << "0 0 "; origin << "0 "; spacing << "0 "; }
1313     }
1314   ofs << "  <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\" Origin=\"" << origin.str() << "\" Spacing=\"" << spacing.str() << "\">\n";
1315   ofs << "    <Piece Extent=\"" << extent.str() << "\">\n";
1316   ofs << "      <PointData>\n" << pointData << std::endl;
1317   ofs << "      </PointData>\n";
1318   ofs << "      <CellData>\n" << cellData << std::endl;
1319   ofs << "      </CellData>\n";
1320   ofs << "      <Coordinates>\n";
1321   ofs << "      </Coordinates>\n";
1322   ofs << "    </Piece>\n";
1323   ofs << "  </" << getVTKDataSetType() << ">\n";
1324 }
1325
1326 void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const
1327 {
1328   stream << "MEDCouplingIMesh C++ instance at " << this << ". Name : \"" << getName() << "\". Space dimension : " << _space_dim << ".";
1329   if(_space_dim<0 || _space_dim>3)
1330     return ;
1331   stream << "\n";
1332   std::ostringstream stream0,stream1;
1333   int nbNodes(1),nbCells(0);
1334   bool isPb(false);
1335   for(int i=0;i<_space_dim;i++)
1336     {
1337       char tmp('X'+i);
1338       int tmpNodes(_structure[i]);
1339       stream1 << "- Axis " << tmp << " : " << tmpNodes << " nodes (orig=" << _origin[i] << ", inter=" << _dxyz[i] << ").";
1340       if(i!=_space_dim-1)
1341         stream1 << std::endl;
1342       if(tmpNodes>=1)
1343         nbNodes*=tmpNodes;
1344       else
1345         isPb=true;
1346       if(tmpNodes>=2)
1347         nbCells=nbCells==0?tmpNodes-1:nbCells*(tmpNodes-1);
1348     }
1349   if(!isPb)
1350     {
1351       stream0 << "Number of cells : " << nbCells << ", Number of nodes : " << nbNodes;
1352       stream << stream0.str();
1353       if(_space_dim>0)
1354         stream << std::endl;
1355     }
1356   stream << stream1.str();
1357 }
1358
1359 std::string MEDCouplingIMesh::getVTKDataSetType() const
1360 {
1361   return std::string("ImageData");
1362 }
1363
1364 std::vector<std::string> MEDCouplingIMesh::buildInfoOnComponents() const
1365 {
1366   checkSpaceDimension();
1367   int dim(getSpaceDimension());
1368   std::vector<std::string> ret(dim);
1369   for(int i=0;i<dim;i++)
1370     {
1371       std::ostringstream oss;
1372       char tmp('X'+i); oss << tmp;
1373       ret[i]=DataArray::BuildInfoFromVarAndUnit(oss.str(),_axis_unit);
1374     }
1375   return ret;
1376 }
1377
1378 void MEDCouplingIMesh::checkSpaceDimension() const
1379 {
1380   CheckSpaceDimension(_space_dim);
1381 }
1382
1383 void MEDCouplingIMesh::CheckSpaceDimension(int spaceDim)
1384 {
1385   if(spaceDim<0 || spaceDim>3)
1386     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CheckSpaceDimension : input spaceDim must be in [0,1,2,3] !");
1387 }
1388
1389 int MEDCouplingIMesh::FindIntRoot(int val, int order)
1390 {
1391   if(order==0)
1392     return 1;
1393   if(val<0)
1394     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : input val is < 0 ! Not possible to compute a root !");
1395   if(order==1)
1396     return val;
1397   if(order!=2 && order!=3)
1398     throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the order available are 0,1,2 or 3 !");
1399   double valf((double)val);
1400   if(order==2)
1401     {
1402       double retf(sqrt(valf));
1403       int ret((int)retf);
1404       if(ret*ret!=val)
1405         throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect square root !");
1406       return ret;
1407     }
1408   else//order==3
1409     {
1410       double retf(std::pow(val,0.3333333333333333));
1411       int ret((int)retf),ret2(ret+1);
1412       if(ret*ret*ret!=val && ret2*ret2*ret2!=val)
1413         throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect cublic root !");
1414       if(ret*ret*ret==val)
1415         return ret;
1416       else
1417         return ret2;
1418     }
1419 }
1420
1421 void MEDCouplingIMesh::SpreadCoarseToFineGhost2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector<int>& coarseSt, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
1422 {
1423   double *outPtrWork(outPtr);
1424   std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
1425   int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]);
1426   int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 !
1427   for(int jg=0;jg<ghostSize;jg++)
1428     {
1429       for(int ig=0;ig<ghostSize;ig++)
1430         outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1431       int kk0(kk+1);
1432       for(int ig=0;ig<dims[0];ig++,kk0++)
1433         for(int ifact=0;ifact<fact0;ifact++)
1434           outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1435       for(int ik=0;ik<ghostSize;ik++)
1436         outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1437     }
1438   for(int j=0;j<dims[1];j++)
1439     {
1440       kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j);
1441       for(int jfact=0;jfact<fact1;jfact++)
1442         {
1443           for(int ig=0;ig<ghostSize;ig++)
1444             outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1445           int kk0(kk+1);//1 not ghost. We make the hypothesis that factors is >= ghostlev
1446           for(int i=0;i<dims[0];i++,kk0++)
1447             {
1448               const double *loc(inPtr+kk0*nbCompo);
1449               for(int ifact=0;ifact<fact0;ifact++)
1450                 outPtrWork=std::copy(loc,loc+nbCompo,outPtrWork);
1451             }
1452           for(int ig=0;ig<ghostSize;ig++)
1453             outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1454         }
1455     }
1456   kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize);
1457   for(int jg=0;jg<ghostSize;jg++)
1458     {
1459       for(int ig=0;ig<ghostSize;ig++)
1460         outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork);
1461       int kk0(kk+1);
1462       for(int ig=0;ig<dims[0];ig++,kk0++)
1463         for(int ifact=0;ifact<fact0;ifact++)
1464           outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1465       for(int ik=0;ik<ghostSize;ik++)
1466         outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork);
1467     }
1468 }