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