Salome HOME
167b4284fb1d15d86e98b06e7e6e37618ee58d21
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingField.cxx
1 // Copyright (C) 2007-2019  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 "MEDCouplingField.hxx"
22 #include "MEDCouplingMesh.hxx"
23 #include "MEDCouplingFieldDiscretization.hxx"
24
25 #include <sstream>
26
27 using namespace MEDCoupling;
28
29 void MEDCouplingField::checkConsistencyLight() const
30 {
31   if(!_mesh)
32     throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !");
33   if(_type.isNull())
34     throw INTERP_KERNEL::Exception("MEDCouplingField::checkConsistencyLight : no spatial discretization !");
35 }
36
37 bool MEDCouplingField::isEqualIfNotWhyProtected(const MEDCouplingField *other, double meshPrec, std::string& reason) const
38 {
39   if(!other)
40     throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualIfNotWhy : other instance is NULL !");
41   std::ostringstream oss; oss.precision(15);
42   if(_name!=other->_name)
43     {
44       oss << "Field names differ : this name = \"" << _name << "\" and other name = \"" << other->_name << "\" !";
45       reason=oss.str();
46       return false;
47     }
48   if(_desc!=other->_desc)
49     {
50       oss << "Field descriptions differ : this description = \"" << _desc << "\" and other description = \"" << other->_desc << "\" !";
51       reason=oss.str();
52       return false;
53     }
54   if(_nature!=other->_nature)
55     {
56       oss << "Field nature differ : this nature = \"" << MEDCouplingNatureOfField::GetRepr(_nature) << "\" and other nature = \"" << MEDCouplingNatureOfField::GetRepr(other->_nature) << "\" !";
57       reason=oss.str();
58       return false;
59     }
60   if(!_type->isEqualIfNotWhy(other->_type,meshPrec,reason))
61     {
62       reason.insert(0,"Spatial discretizations differ :");
63       return false;
64     }
65   if(_mesh==0 && other->_mesh==0)
66     return true;
67   if(_mesh==0 || other->_mesh==0)
68     {
69       reason="Only one field between the two this and other has its underlying mesh defined !";
70       return false;
71     }
72   if(_mesh==other->_mesh)
73     return true;
74   bool ret=_mesh->isEqualIfNotWhy(other->_mesh,meshPrec,reason);
75   if(!ret)
76     reason.insert(0,"Underlying meshes of fields differ for the following reason : ");
77   return ret;
78 }
79
80 /*!
81  * Checks if \a this and another MEDCouplingField are equal. The textual
82  * information like names etc. is not considered.
83  *  \param [in] other - the field to compare with \a this one.
84  *  \param [in] meshPrec - precision used to compare node coordinates of the underlying mesh.
85  *  \return bool - \c true if the two fields are equal, \c false else.
86  *  \throw If \a other is NULL.
87  *  \throw If the spatial discretization of \a this field is NULL.
88  */
89 bool MEDCouplingField::isEqualWithoutConsideringStrProtected(const MEDCouplingField *other, double meshPrec) const
90 {
91   if(!other)
92     throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualWithoutConsideringStr : input field is NULL !");
93   if(!_type)
94     throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualWithoutConsideringStr : spatial discretization of this is NULL !");
95   if(!_type->isEqualWithoutConsideringStr(other->_type,meshPrec))
96     return false;
97   if(_nature!=other->_nature)
98     return false;
99   if(_mesh==0 && other->_mesh==0)
100     return true;
101   if(_mesh==0 || other->_mesh==0)
102     return false;
103   if(_mesh==other->_mesh)
104     return true;
105   return _mesh->isEqualWithoutConsideringStr(other->_mesh,meshPrec);
106 }
107
108 /*!
109  * This method states if 'this' and 'other' are compatibles each other before performing any treatment.
110  * This method is good for methods like : mergeFields.
111  * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields.
112  */
113 bool MEDCouplingField::areCompatibleForMerge(const MEDCouplingField *other) const
114 {
115   if(!other)
116     throw INTERP_KERNEL::Exception("MEDCouplingField::areCompatibleForMerge : input field is NULL !");
117   if(!_type || !other->_type)
118     throw INTERP_KERNEL::Exception("MEDCouplingField::areCompatibleForMerge : this or other has a nullptr spatial discretization !");
119   if(_type->getEnum()!=other->_type->getEnum())
120     return false;
121   if(_nature!=other->_nature)
122     return false;
123   if(_mesh==other->_mesh)
124     return true;
125   return _mesh->areCompatibleForMerge(other->_mesh);
126 }
127
128 /*!
129  * This method is more strict than MEDCouplingField::areCompatibleForMerge method.
130  * This method is used for operation on fields to operate a first check before attempting operation.
131  */
132 bool MEDCouplingField::areStrictlyCompatible(const MEDCouplingField *other) const
133 {
134   if(!other)
135     throw INTERP_KERNEL::Exception("MEDCouplingField::areStrictlyCompatible : input field is NULL !");
136   if(!_type->isEqual(other->_type,1.e-12))
137     return false;
138   if(_nature!=other->_nature)
139     return false;
140   return _mesh==other->_mesh;
141 }
142
143 /*!
144  * This method is less strict than MEDCouplingField::areStrictlyCompatible method.
145  * The difference is that the nature is not checked.
146  * This method is used for multiplication and division on fields to operate a first check before attempting operation.
147  */
148 bool MEDCouplingField::areStrictlyCompatibleForMulDiv(const MEDCouplingField *other) const
149 {
150   if(!other)
151     throw INTERP_KERNEL::Exception("MEDCouplingField::areStrictlyCompatible : input field is NULL !");
152   if(!_type->isEqual(other->_type,1.e-12))
153     return false;
154   return _mesh==other->_mesh;
155 }
156
157
158 void MEDCouplingField::updateTime() const
159 {
160   if(_mesh)
161     updateTimeWith(*_mesh);
162   if(_type)
163     updateTimeWith(*_type);
164 }
165
166 std::size_t MEDCouplingField::getHeapMemorySizeWithoutChildren() const
167 {
168   std::size_t ret=0;
169   ret+=_name.capacity();
170   ret+=_desc.capacity();
171   return ret;
172 }
173
174 std::vector<const BigMemoryObject *> MEDCouplingField::getDirectChildrenWithNull() const
175 {
176   std::vector<const BigMemoryObject *> ret;
177   ret.push_back(_mesh);
178   ret.push_back((const MEDCouplingFieldDiscretization *)_type);
179   return ret;
180 }
181
182 /*!
183  * Returns a type of \ref MEDCouplingSpatialDisc "spatial discretization" of \a this
184  * field in terms of enum MEDCoupling::TypeOfField. 
185  * \return MEDCoupling::TypeOfField - the type of \a this field.
186  * \throw If the geometric type is empty.
187  */
188 TypeOfField MEDCouplingField::getTypeOfField() const
189 {
190   if(!((const MEDCouplingFieldDiscretization *)_type))
191     throw INTERP_KERNEL::Exception("MEDCouplingField::getTypeOfField : spatial discretization is null !");
192   return _type->getEnum();
193 }
194
195 /*!
196  * Returns the nature of \a this field. This information is very important during
197  * interpolation process using MEDCoupling::MEDCouplingRemapper or MEDCoupling::InterpKernelDEC.
198  * In other context than the two mentioned above, this attribute is unimportant. This
199  * attribute is not stored in the MED file.
200  * For more information of the semantics and the influence of this attribute to the
201  * result of interpolation, see
202  * - \ref NatureOfField
203  * - \ref TableNatureOfField "How interpolation coefficients depend on Field Nature"
204  */
205 NatureOfField MEDCouplingField::getNature() const
206 {
207   return _nature;
208 }
209
210 /*!
211  * Sets the nature of \a this field. This information is very important during
212  * interpolation process using MEDCoupling::MEDCouplingRemapper or MEDCoupling::InterpKernelDEC.
213  * In other context than the two mentioned above, this attribute is unimportant. This
214  * attribute is not stored in the MED file.
215  * For more information of the semantics and the influence of this attribute to the
216  * result of interpolation, see
217  * - \ref NatureOfField
218  * - \ref TableNatureOfField "How interpolation coefficients depend on Field Nature"
219  *
220  *  \param [in] nat - the nature of \a this field.
221  *  \throw If \a nat has an invalid value.
222  */
223 void MEDCouplingField::setNature(NatureOfField nat)
224 {
225   MEDCouplingNatureOfField::GetRepr(nat);//generate a throw if nat not recognized
226   if(_type)
227     _type->checkCompatibilityWithNature(nat);
228   _nature=nat;
229 }
230
231 /*!
232  * Returns coordinates of field location points that depend on 
233  * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field.
234  * - For a field on nodes, returns coordinates of nodes.
235  * - For a field on cells, returns barycenters of cells.
236  * - For a field on gauss points, returns coordinates of gauss points.
237  * 
238  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
239  *          delete this array using decrRef() as it is no more needed. 
240  *  \throw If the spatial discretization of \a this field is NULL.
241  *  \throw If the mesh is not set.
242  */
243 DataArrayDouble *MEDCouplingField::getLocalizationOfDiscr() const
244 {
245   if(!_mesh)
246     throw INTERP_KERNEL::Exception("MEDCouplingField::getLocalizationOfDiscr : No mesh set !");
247   if(!((const MEDCouplingFieldDiscretization *)_type))
248     throw INTERP_KERNEL::Exception("MEDCouplingField::getLocalizationOfDiscr : No spatial discretization set !");
249   return _type->getLocalizationOfDiscValues(_mesh);
250 }
251
252 /*!
253  * Returns a new MEDCouplingFieldDouble containing volumes of cells of a dual mesh whose
254  * cells are constructed around field location points (getLocalizationOfDiscr()) of \a this
255  * field. (In case of a field on cells, the dual mesh coincides with the underlying mesh).<br>
256  * For 1D cells, the returned field contains lengths.<br>
257  * For 2D cells, the returned field contains areas.<br>
258  * For 3D cells, the returned field contains volumes.
259  *  \param [in] isAbs - if \c true, the computed cell volume does not reflect cell
260  *         orientation, i.e. the volume is always positive.
261  *  \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble.
262  *          The caller is to delete this array using decrRef() as
263  *          it is no more needed.
264  *  \throw If the mesh is not set.
265  *  \throw If the spatial discretization of \a this field is NULL.
266  *  \throw If the spatial discretization of \a this field is not well defined.
267  */
268
269 MEDCouplingFieldDouble *MEDCouplingField::buildMeasureField(bool isAbs) const
270 {
271   if(!_mesh)
272     throw INTERP_KERNEL::Exception("MEDCouplingField::buildMeasureField : no mesh defined !");
273   if(!((const MEDCouplingFieldDiscretization *)_type))
274     throw INTERP_KERNEL::Exception("MEDCouplingField::buildMeasureField : No spatial discretization set !");
275   return _type->getMeasureField(_mesh,isAbs);
276 }
277
278 /*!
279  * Sets the underlying mesh of \a this field.
280  * For examples of field construction, see \ref MEDCouplingFirstSteps3.
281  *  \param [in] mesh - the new underlying mesh.
282  */
283 void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh)
284 {
285   if(mesh!=_mesh)
286     {
287       if(_mesh)
288         _mesh->decrRef();
289       _mesh=mesh;
290       declareAsNew();
291       if(_mesh)
292         {
293           _mesh->incrRef();
294           updateTimeWith(*_mesh);
295         }
296     }
297 }
298
299 /*!
300  * Sets localization of Gauss points for a given geometric type of cell.
301  *  \param [in] type - the geometric type of cell for which the Gauss localization is set.
302  *  \param [in] refCoo - coordinates of points of the reference cell. Size of this vector
303  *         must be \c nbOfNodesPerCell * \c dimOfType. 
304  *  \param [in] gsCoo - coordinates of Gauss points on the reference cell. Size of this vector
305  *         must be  _wg_.size() * \c dimOfType.
306  *  \param [in] wg - the weights of Gauss points.
307  *  \throw If \a this field is not on Gauss points.
308  *  \throw If the spatial discretization of \a this field is NULL.
309  *  \throw If the mesh is not set.
310  *  \throw If size of any vector do not match the \a type.
311  */
312 void MEDCouplingField::setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
313                                                   const std::vector<double>& gsCoo, const std::vector<double>& wg)
314 {
315   if(!_mesh)
316     throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnType method !");
317   if(!((const MEDCouplingFieldDiscretization *)_type))
318     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call setGaussLocalizationOnType method !");
319   _type->setGaussLocalizationOnType(_mesh,type,refCoo,gsCoo,wg);
320 }
321
322 /*!
323  * Sets localization of Gauss points for given cells specified by their ids.
324  *  \param [in] begin - an array of cell ids of interest.
325  *  \param [in] end - the end of \a begin, i.e. a pointer to its (last+1)-th element.
326  *  \param [in] refCoo - coordinates of points of the reference cell. Size of this vector
327  *         must be \c nbOfNodesPerCell * \c dimOfType. 
328  *  \param [in] gsCoo - coordinates of Gauss points on the reference cell. Size of this vector
329  *         must be  _wg_.size() * \c dimOfType.
330  *  \param [in] wg - the weights of Gauss points.
331  *  \throw If \a this field is not on Gauss points.
332  *  \throw If the spatial discretization of \a this field is NULL.
333  *  \throw If the mesh is not set.
334  *  \throw If size of any vector do not match the type of cell # \a begin[0].
335  *  \throw If type of any cell in \a begin differs from that of cell # \a begin[0].
336  *  \throw If the range [_begin_,_end_) is empty.
337  */
338 void MEDCouplingField::setGaussLocalizationOnCells(const mcIdType *begin, const mcIdType *end, const std::vector<double>& refCoo,
339                                                    const std::vector<double>& gsCoo, const std::vector<double>& wg)
340 {
341   if(!_mesh)
342     throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnCells method !");
343   if(!((const MEDCouplingFieldDiscretization *)_type))
344     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call setGaussLocalizationOnCells method !");
345   _type->setGaussLocalizationOnCells(_mesh,begin,end,refCoo,gsCoo,wg);
346 }
347
348 /*!
349  * Clears data on Gauss points localization.
350  *  \throw If \a this field is not on Gauss points.
351  *  \throw If the spatial discretization of \a this field is NULL.
352  */
353 void MEDCouplingField::clearGaussLocalizations()
354 {
355   if(!((const MEDCouplingFieldDiscretization *)_type))
356     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call clearGaussLocalizations method !");
357   _type->clearGaussLocalizations();
358 }
359
360 /*!
361  * Returns a reference to the Gauss localization object by its id.
362  * \warning This method is not const, so the returned object can be modified without any
363  *          problem.
364  *  \param [in] locId - the id of the Gauss localization object of interest.
365  *         It must be in range <em> 0 <= locId < getNbOfGaussLocalization() </em>.
366  *  \return \ref MEDCoupling::MEDCouplingGaussLocalization "MEDCouplingGaussLocalization" & - the
367  *  Gauss localization object.
368  *  \throw If \a this field is not on Gauss points.
369  *  \throw If \a locId is not within the valid range.
370  *  \throw If the spatial discretization of \a this field is NULL.
371  */
372 MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId)
373 {
374   if(!((const MEDCouplingFieldDiscretization *)_type))
375     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !");
376   return _type->getGaussLocalization(locId);
377 }
378
379 /*!
380  * Returns an id of the Gauss localization object corresponding to a given cell type.
381  *  \param [in] type - the cell type of interest.
382  *  \return mcIdType - the id of the Gauss localization object.
383  *  \throw If \a this field is not on Gauss points.
384  *  \throw If the spatial discretization of \a this field is NULL.
385  *  \throw If no Gauss localization object found for the given cell \a type.
386  *  \throw If more than one Gauss localization object found for the given cell \a type.
387  */
388 mcIdType MEDCouplingField::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const
389 {
390   if(!((const MEDCouplingFieldDiscretization *)_type))
391     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdOfOneType method !");
392   return _type->getGaussLocalizationIdOfOneType(type);
393 }
394
395 /*!
396  * Returns ids of Gauss localization objects corresponding to a given cell type.
397  *  \param [in] type - the cell type of interest.
398  *  \return std::set<mcIdType> - ids of the Gauss localization object.
399  *  \throw If \a this field is not on Gauss points.
400  *  \throw If the spatial discretization of \a this field is NULL
401  */
402 std::set<mcIdType> MEDCouplingField::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const
403 {
404   if(!((const MEDCouplingFieldDiscretization *)_type))
405     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdsOfOneType method !");
406   return _type->getGaussLocalizationIdsOfOneType(type);
407 }
408
409 /*!
410  * Returns number of Gauss localization objects available. Implicitly all ids in
411  * [0,getNbOfGaussLocalization()) are valid Gauss localization ids. 
412  *  \return mcIdType - the number of available Gauss localization objects.
413  *  \throw If \a this field is not on Gauss points.
414  *  \throw If the spatial discretization of \a this field is NULL.
415  */
416 mcIdType MEDCouplingField::getNbOfGaussLocalization() const
417 {
418   if(!((const MEDCouplingFieldDiscretization *)_type))
419     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNbOfGaussLocalization method !");
420   return _type->getNbOfGaussLocalization();
421 }
422
423 /*!
424  * Returns an id of the Gauss localization object corresponding to a type of a given cell.
425  *  \param [in] cellId - an id of the cell of interest.
426  *  \return mcIdType - the id of the Gauss localization object.
427  *  \throw If \a this field is not on Gauss points.
428  *  \throw If the spatial discretization of \a this field is NULL.
429  *  \throw If no Gauss localization object found for the given cell.
430  */
431 mcIdType MEDCouplingField::getGaussLocalizationIdOfOneCell(mcIdType cellId) const
432 {
433   if(!((const MEDCouplingFieldDiscretization *)_type))
434     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdOfOneCell method !");
435   return _type->getGaussLocalizationIdOfOneCell(cellId);
436 }
437
438 /*!
439  * Returns ids of cells that share the same Gauss localization given by its id.
440  *  \param [in] locId - the id of the Gauss localization object of interest. 
441  *         It must be in range <em> 0 <= locId < getNbOfGaussLocalization() </em>.
442  *  \param [in,out] cellIds - a vector returning ids of found cells. It is cleared before
443  *         filling in. It remains empty if no cells found.
444  *  \throw If \a this field is not on Gauss points.
445  *  \throw If \a locId is not within the valid range.
446  *  \throw If the spatial discretization of \a this field is NULL.
447  */
448 void MEDCouplingField::getCellIdsHavingGaussLocalization(int locId, std::vector<mcIdType>& cellIds) const
449 {
450   cellIds.clear();
451   if(!((const MEDCouplingFieldDiscretization *)_type))
452     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getCellIdsHavingGaussLocalization method !");
453   _type->getCellIdsHavingGaussLocalization(locId,cellIds);
454 }
455
456 /*!
457  * Returns a reference to the Gauss localization object by its id.
458  * \warning This method is const, so the returned object is not apt for modification.
459  *  \param [in] locId - the id of the Gauss localization object of interest.
460  *         It must be in range <em> 0 <= locId < getNbOfGaussLocalization() </em>.
461  *  \return const \ref MEDCouplingGaussLocalization & - the Gauss localization object.
462  *  \throw If \a this field is not on Gauss points.
463  *  \throw If \a locId is not within the valid range.
464  *  \throw If the spatial discretization of \a this field is NULL.
465  */
466 const MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) const
467 {
468   if(!((const MEDCouplingFieldDiscretization *)_type))
469     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !");
470   return _type->getGaussLocalization(locId);
471 }
472
473 MEDCouplingField::~MEDCouplingField()
474 {
475   if(_mesh)
476     _mesh->decrRef();
477 }
478
479 MEDCouplingField::MEDCouplingField(MEDCouplingFieldDiscretization *type, NatureOfField nature):_nature(nature),_mesh(0),_type(type)
480 {
481 }
482
483 MEDCouplingField::MEDCouplingField(TypeOfField type):_nature(NoNature),_mesh(0),_type(MEDCouplingFieldDiscretization::New(type))
484 {
485 }
486
487 MEDCouplingField::MEDCouplingField(const MEDCouplingField& other, bool deepCopy):RefCountObject(other),_name(other._name),_desc(other._desc),_nature(other._nature),
488     _mesh(0),_type(0)
489 {
490   if(other._mesh)
491     {
492       _mesh=other._mesh;
493       _mesh->incrRef();
494     }
495   if(deepCopy)
496     _type=other._type->clone();
497   else
498     _type=other._type;
499 }
500
501 /*!
502  * Returns a new MEDCouplingMesh constituted by some cells of the underlying mesh of \a
503  * this field, and returns ids of entities (nodes, cells, Gauss points) lying on the
504  * specified cells. The cells to include to the result mesh are specified by an array of
505  * cell ids. The new mesh shares the coordinates array with the underlying mesh. 
506  *  \param [in] start - an array of cell ids to include to the result mesh.
507  *  \param [in] end - specifies the end of the array \a start, so that
508  *              the last value of \a start is \a end[ -1 ].
509  *  \param [out] di - a new instance of DataArrayIdType holding the ids of entities (nodes,
510  *         cells, Gauss points). The caller is to delete this array using decrRef() as it
511  *         is no more needed.  
512  *  \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to
513  *         delete this mesh using decrRef() as it is no more needed. 
514  *  \throw If the spatial discretization of \a this field is NULL.
515  *  \throw If the mesh is not set.
516  * \sa buildSubMeshDataRange()
517  */
518 MEDCouplingMesh *MEDCouplingField::buildSubMeshData(const mcIdType *start, const mcIdType *end, DataArrayIdType *&di) const
519 {
520   if(!((const MEDCouplingFieldDiscretization *)_type))
521     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call buildSubMeshData method !");
522   return _type->buildSubMeshData(_mesh,start,end,di);
523 }
524
525 /*!
526  * This method returns a submesh of 'mesh' instance constituting cell ids defined by a range given by the 3 following inputs \a begin, \a end and \a step.
527  * 
528  * \param [out] beginOut Valid only if \a di is NULL
529  * \param [out] endOut Valid only if \a di is NULL
530  * \param [out] stepOut Valid only if \a di is NULL
531  * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable.
532  * 
533  * \sa MEDCouplingField::buildSubMeshData
534  */
535 MEDCouplingMesh *MEDCouplingField::buildSubMeshDataRange(mcIdType begin, mcIdType end, mcIdType step, mcIdType& beginOut, mcIdType& endOut, mcIdType& stepOut, DataArrayIdType *&di) const
536 {
537   if(!((const MEDCouplingFieldDiscretization *)_type))
538     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call buildSubMeshDataRange method !");
539   return _type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,di);
540 }
541
542 /*!
543  * This method returns tuples ids implied by the mesh selection of the  cell ids contained in array defined as an interval [start;end).
544  * \return a newly allocated DataArrayIdType instance containing tuples ids.
545  */
546 DataArrayIdType *MEDCouplingField::computeTupleIdsToSelectFromCellIds(const mcIdType *startCellIds, const mcIdType *endCellIds) const
547 {
548   if(!((const MEDCouplingFieldDiscretization *)_type))
549     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call computeTupleIdsToSelectFromCellIds method !");
550   return _type->computeTupleIdsToSelectFromCellIds(_mesh,startCellIds,endCellIds);
551 }
552
553 /*!
554  * Returns number of tuples expected regarding the spatial discretization of \a this
555  * field and number of entities in the underlying mesh. This method behaves exactly as MEDCouplingFieldDouble::getNumberOfTuples.
556  *  \return mcIdType - the number of expected tuples.
557  *  \throw If the spatial discretization of \a this field is NULL.
558  *  \throw If the mesh is not set.
559  */
560 mcIdType MEDCouplingField::getNumberOfTuplesExpected() const
561 {
562   if(!((const MEDCouplingFieldDiscretization *)_type))
563     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNumberOfTuplesExpected method !");
564   if(_mesh)
565     return _type->getNumberOfTuples(_mesh);
566   else
567     throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfTuplesExpected : Empty mesh !");
568 }
569
570 void MEDCouplingField::setDiscretization(MEDCouplingFieldDiscretization *newDisc)
571 {
572   bool needUpdate=(const MEDCouplingFieldDiscretization *)_type!=newDisc;
573   _type=newDisc;
574   if(newDisc)
575     newDisc->incrRef();
576   if(needUpdate)
577     declareAsNew();
578 }
579
580 /*!
581  * Returns number of mesh entities in the underlying mesh of \a this field regarding the
582  * spatial discretization.
583  *  \return mcIdType - the number of mesh entities porting the field values.
584  *  \throw If the spatial discretization of \a this field is NULL.
585  *  \throw If the mesh is not set.
586  */
587 mcIdType MEDCouplingField::getNumberOfMeshPlacesExpected() const
588 {
589   if(!((const MEDCouplingFieldDiscretization *)_type))
590     throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNumberOfMeshPlacesExpected method !");
591   if(_mesh)
592     return _type->getNumberOfMeshPlaces(_mesh);
593   else
594     throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfMeshPlacesExpected : Empty mesh !");
595 }
596
597 /*!
598  * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason).
599  */
600 void MEDCouplingField::copyTinyStringsFrom(const MEDCouplingField *other)
601 {
602   if(other)
603     {
604       setName(other->_name);
605       setDescription(other->_desc);    
606     }
607 }
608
609 /*!
610  * This method computes the number of tuples a DataArrayDouble instance should have to build a correct MEDCouplingFieldDouble instance starting from a 
611  * submesh of a virtual mesh on which a substraction per type had been applied regarding the spatial discretization in \a this.
612  * 
613  * For spatial discretization \b not equal to ON_GAUSS_NE this method will make the hypothesis that any positive entity id in \a code \a idsPerType is valid.
614  * So in those cases attribute \a _mesh of \a this is ignored.
615  * 
616  * For spatial discretization equal to ON_GAUSS_NE \a _mesh attribute will be taken into account.
617  *
618  * The input code is those implemented in MEDCouplingUMesh::splitProfilePerType.
619  *
620  * \param [in] code - a code with format described above.
621  * \param [in] idsPerType - a list of subparts
622  * \throw If \a this has no spatial discretization set.
623  * \throw If input code point to invalid zones in spatial discretization.
624  * \throw If spatial discretization in \a this requires a mesh and those mesh is invalid (null,...)
625  */
626 mcIdType MEDCouplingField::getNumberOfTuplesExpectedRegardingCode(const std::vector<mcIdType>& code, const std::vector<const DataArrayIdType *>& idsPerType) const
627 {
628   const MEDCouplingFieldDiscretization *t(_type);
629   if(!t)
630     throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfTuplesExpectedRegardingCode : no spatial discretization set !");
631   return t->getNumberOfTuplesExpectedRegardingCode(code,idsPerType);
632 }