Salome HOME
- C++/Python API modif MEDLoader::setEpsilonForNodeComp -> MEDLoader::SetEpsilonForNo...
[modules/med.git] / src / MEDLoader / MEDLoader.cxx
1 // Copyright (C) 2007-2013  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.
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 "MEDLoader.hxx"
22 #include "MEDLoaderBase.hxx"
23 #include "MEDFileUtilities.hxx"
24 #include "CellModel.hxx"
25 #include "MEDCouplingUMesh.hxx"
26 #include "MEDCouplingMemArray.hxx"
27 #include "MEDCouplingFieldDouble.hxx"
28 #include "MEDCouplingGaussLocalization.hxx"
29 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
30
31 #include "InterpKernelAutoPtr.hxx"
32
33 #include "med.h"
34
35 #include <string>
36 #include <limits>
37 #include <cstring>
38 #include <sstream>
39 #include <fstream>
40 #include <numeric>
41 #include <iterator>
42 #include <algorithm>
43
44 med_geometry_type typmai[MED_N_CELL_FIXED_GEO] = { MED_POINT1,
45                                                    MED_SEG2,
46                                                    MED_SEG3,
47                                                    MED_SEG4,
48                                                    MED_TRIA3,
49                                                    MED_QUAD4,
50                                                    MED_TRIA6,
51                                                    MED_TRIA7,
52                                                    MED_QUAD8,
53                                                    MED_QUAD9,
54                                                    MED_TETRA4,
55                                                    MED_PYRA5,
56                                                    MED_PENTA6,
57                                                    MED_HEXA8,
58                                                    MED_OCTA12,
59                                                    MED_TETRA10,
60                                                    MED_PYRA13,
61                                                    MED_PENTA15,
62                                                    MED_HEXA20,
63                                                    MED_HEXA27,
64                                                    MED_POLYGON,
65                                                    MED_POLYHEDRON };
66
67 med_geometry_type typmainoeud[1] = { MED_NONE };
68
69 INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO] = { INTERP_KERNEL::NORM_POINT1,
70                                                                     INTERP_KERNEL::NORM_SEG2,
71                                                                     INTERP_KERNEL::NORM_SEG3,
72                                                                     INTERP_KERNEL::NORM_SEG4,
73                                                                     INTERP_KERNEL::NORM_TRI3,
74                                                                     INTERP_KERNEL::NORM_QUAD4,
75                                                                     INTERP_KERNEL::NORM_TRI6,
76                                                                     INTERP_KERNEL::NORM_TRI7,
77                                                                     INTERP_KERNEL::NORM_QUAD8,
78                                                                     INTERP_KERNEL::NORM_QUAD9,
79                                                                     INTERP_KERNEL::NORM_TETRA4,
80                                                                     INTERP_KERNEL::NORM_PYRA5,
81                                                                     INTERP_KERNEL::NORM_PENTA6,
82                                                                     INTERP_KERNEL::NORM_HEXA8,
83                                                                     INTERP_KERNEL::NORM_HEXGP12,
84                                                                     INTERP_KERNEL::NORM_TETRA10,
85                                                                     INTERP_KERNEL::NORM_PYRA13,
86                                                                     INTERP_KERNEL::NORM_PENTA15,
87                                                                     INTERP_KERNEL::NORM_HEXA20,
88                                                                     INTERP_KERNEL::NORM_HEXA27,
89                                                                     INTERP_KERNEL::NORM_POLYGON,
90                                                                     INTERP_KERNEL::NORM_POLYHED };
91
92 med_geometry_type typmai3[34] = { MED_POINT1,//0
93                                   MED_SEG2,//1
94                                   MED_SEG3,//2
95                                   MED_TRIA3,//3
96                                   MED_QUAD4,//4
97                                   MED_POLYGON,//5
98                                   MED_TRIA6,//6
99                                   MED_TRIA7,//7
100                                   MED_QUAD8,//8
101                                   MED_QUAD9,//9
102                                   MED_SEG4,//10
103                                   MED_NONE,//11
104                                   MED_NONE,//12
105                                   MED_NONE,//13
106                                   MED_TETRA4,//14
107                                   MED_PYRA5,//15
108                                   MED_PENTA6,//16
109                                   MED_NONE,//17
110                                   MED_HEXA8,//18
111                                   MED_NONE,//19
112                                   MED_TETRA10,//20
113                                   MED_NONE,//21
114                                   MED_OCTA12,//22
115                                   MED_PYRA13,//23
116                                   MED_NONE,//24
117                                   MED_PENTA15,//25
118                                   MED_NONE,//26
119                                   MED_HEXA27,//27
120                                   MED_NONE,//28
121                                   MED_NONE,//29
122                                   MED_HEXA20,//30
123                                   MED_POLYHEDRON,//31
124                                   MED_NONE,//32
125                                   MED_NONE//33
126 };
127
128 double MEDLoader::_EPS_FOR_NODE_COMP=1.e-12;
129
130 int MEDLoader::_COMP_FOR_CELL=0;
131
132 int MEDLoader::_TOO_LONG_STR=0;
133
134 using namespace ParaMEDMEM;
135
136 /// @cond INTERNAL
137
138 namespace MEDLoaderNS
139 {
140   class FieldPerTypeCopier
141   {
142   public:
143     FieldPerTypeCopier(double *ptr):_ptr(ptr) { }
144     void operator()(const MEDLoader::MEDFieldDoublePerCellType& elt) { _ptr=std::copy(elt.getArray(),elt.getArray()+elt.getNbOfValues(),_ptr); }
145   private:
146     double *_ptr;
147   };
148  
149   class ConnReaderML
150   {
151   public:
152     ConnReaderML(const int *c, int val):_conn(c),_val(val) { }
153     bool operator() (const int& pos) { return _conn[pos]!=_val; }
154   private:
155     const int *_conn;
156     int _val;
157   };
158   
159   std::vector<std::string> getMeshNamesFid(med_idt fid);
160   void readFieldDoubleDataInMedFile(const char *fileName, const char *meshName, const char *fieldName,
161                                     int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField,
162                                     std::list<MEDLoader::MEDFieldDoublePerCellType>& field,
163                                     double& time, std::vector<std::string>& infos);
164   std::vector<int> getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector<std::string>& fams);
165   std::vector<int> getIdsFromGroups(const char *fileName, const char *meshName, const std::vector<std::string>& grps);
166   med_int getIdFromMeshName(med_idt fid, const char *meshName, std::string& trueMeshName) throw(INTERP_KERNEL::Exception);
167   void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity);
168   int readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector<int>& possibilities);
169   void readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayDouble *&coords, std::list<MEDLoader::MEDConnOfOneElemType>& conn, std::string& desc);
170   int buildMEDSubConnectivityOfOneType(const std::vector<const DataArrayInt *>& conn, const std::vector<const DataArrayInt *>& connIndex, const std::vector<const DataArrayInt *>& families, INTERP_KERNEL::NormalizedCellType type,
171                                        std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile,
172                                        std::vector<int>& fam4MEDFile, std::vector<int>& renumber);
173   MEDCouplingUMesh *readUMeshFromFileLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<int>& ids,
174                                           const std::vector<INTERP_KERNEL::NormalizedCellType>& typesToKeep, unsigned& meshDimExtract, int *&cellRenum) throw(INTERP_KERNEL::Exception);
175   void tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDLoader::MEDConnOfOneElemType>& medConnFrmt,
176                                             const std::vector<int>& familiesToKeep,
177                                             DataArrayInt* &conn,
178                                             DataArrayInt* &connIndex,
179                                             int *&cellRenum);
180   ParaMEDMEM::DataArrayDouble *buildArrayFromRawData(const std::list<MEDLoader::MEDFieldDoublePerCellType>& fieldPerType,
181                                                      const std::vector<std::string>& infos);
182   int buildMEDSubConnectivityOfOneTypesPolyg(const std::vector<const DataArrayInt *>& conn, const std::vector<const DataArrayInt *>& connIndex, const std::vector<const DataArrayInt *>& families,
183                                              std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber);
184   int buildMEDSubConnectivityOfOneTypesPolyh(const std::vector<const DataArrayInt *>&conn, const std::vector<const DataArrayInt *>& connIndex, const std::vector<const DataArrayInt *>& families,
185                                              std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile,
186                                              std::vector<int>& fam4MEDFile, std::vector<int>& renumber);
187   int buildMEDSubConnectivityOfOneTypeStaticTypes(const std::vector<const DataArrayInt *>& conn, const std::vector<const DataArrayInt *>& connIndex, const std::vector<const DataArrayInt *>& families,
188                                                   INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber);
189   ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order,
190                                                           ParaMEDMEM::TypeOfField typeOfOutField) throw(INTERP_KERNEL::Exception);
191   ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev2(const char *fileName, ParaMEDMEM::TypeOfField typeOfOutField, unsigned meshDim, const int *renumCell, const ParaMEDMEM::MEDCouplingUMesh *mesh,
192                                                           const std::vector<std::string>& infos, const char *fieldName, int iteration, int order, double time,
193                                                           std::list<MEDLoader::MEDFieldDoublePerCellType>& fieldPerCellType) throw(INTERP_KERNEL::Exception);
194   med_idt appendFieldSimpleAtt(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, med_int& numdt, med_int& numo, med_float& dt);
195   void appendFieldDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f);
196   void appendNodeProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshNodeIds);
197   void appendCellProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIds);
198   void appendNodeElementProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIds);
199   void prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *cellIds, std::list<MEDLoader::MEDFieldDoublePerCellType>& split);
200   void fillGaussDataOnField(const char *fileName, const std::list<MEDLoader::MEDFieldDoublePerCellType>& data, MEDCouplingFieldDouble *f);
201   void writeUMeshesDirectly(const char *fileName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& mesh, const std::vector<const DataArrayInt *>& families, bool forceFromScratch, bool &isRenumbering);
202   void writeUMeshesPartitionDirectly(const char *fileName, const char *meshName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool forceFromScratch);
203   void writeFieldAndMeshDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch);
204   void writeFieldTryingToFitExistingMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f);
205 }
206
207 /// @endcond
208
209 /*!
210  * This method sets the epsilon value used for node comparison when trying to buid a profile for a field on node/cell on an already written mesh.
211  */
212 void MEDLoader::SetEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception)
213 {
214   _EPS_FOR_NODE_COMP=val;
215 }
216
217 /*!
218  * This method sets the policy comparison when trying to fit the already written mesh on a field. The semantic of the policy is specified in MEDCouplingUMesh::zipConnectivityTraducer.
219  */
220 void MEDLoader::SetCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception)
221 {
222   _COMP_FOR_CELL=val;
223 }
224
225 /*!
226  * This method set the behaviour of MEDLoader when a too long string is seen in datastructure before copy it in MED file.
227  * By default (0) an exception is thrown. If equal to 1 a warning is emitted in std_err but no exception is thrown.
228  */
229 void MEDLoader::SetTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception)
230 {
231   _TOO_LONG_STR=val;
232 }
233
234 /*!
235  * @param lgth is the size of fam tab. For classical types conn is size of 'lgth'*number_of_nodes_in_type.
236  * @param index is optionnal only for polys. Set it to 0 if it is not the case.
237  * @param connLgth is the size of conn in the case of poly. Unsued if it is not the case.
238  */
239 MEDLoader::MEDConnOfOneElemType::MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int *index, int *fam, int lgth, int connLgth):_lgth(lgth),_fam(fam),
240                                                                                                                                                        _conn(conn),_index(index),
241                                                                                                                                                        _global(0),_conn_lgth(connLgth),
242                                                                                                                                                        _type(type)
243 {
244 }
245
246 void MEDLoader::MEDConnOfOneElemType::setGlobal(int *global)
247 {
248   if(_global!=global)
249     {
250       if(_global)
251         delete [] _global;
252       _global=global;
253     }
254 }
255
256 void MEDLoader::MEDConnOfOneElemType::releaseArray()
257 {
258   delete [] _fam;
259   delete [] _conn;
260   delete [] _index;
261   delete [] _global;
262 }
263
264 MEDLoader::MEDFieldDoublePerCellType::MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int nGeoElt, int nbi,
265                                                                 const int *cellIdPerType, const char *locName):_ngeo_elt(nGeoElt),_nbi(nbi),_ncomp(ncomp),_values(values),_type(type)
266 {
267   if(cellIdPerType)
268     _cell_id_per_type.insert(_cell_id_per_type.end(),cellIdPerType,cellIdPerType+nGeoElt);
269   if(locName)
270     _loc_name=locName;
271 }
272
273 void MEDLoader::MEDFieldDoublePerCellType::releaseArray()
274 {
275   delete [] _values;
276 }
277
278 /// @cond INTERNAL
279
280 std::vector<std::string> MEDLoaderNS::getMeshNamesFid(med_idt fid)
281 {
282   med_mesh_type type_maillage;
283   char maillage_description[MED_COMMENT_SIZE+1];
284   char dtunit[MED_COMMENT_SIZE+1];
285   med_int space_dim;
286   med_int mesh_dim;
287   char nommaa[MED_NAME_SIZE+1];
288   med_axis_type axistype;
289   med_sorting_type stype;
290   med_int n=MEDnMesh(fid);
291   std::vector<std::string> ret(n);
292   for(int i=0;i<n;i++)
293     {
294       int naxis=MEDmeshnAxis(fid,i+1);
295       INTERP_KERNEL::AutoPtr<char> axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
296       INTERP_KERNEL::AutoPtr<char> axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
297       int nstep;
298       MEDmeshInfo(fid,i+1,nommaa,&space_dim,&mesh_dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit);
299       std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa));
300       ret[i]=cur;
301     }
302   return ret;
303 }
304
305 void MEDLoaderNS::fillGaussDataOnField(const char *fileName, const std::list<MEDLoader::MEDFieldDoublePerCellType>& data, MEDCouplingFieldDouble *f)
306 {
307   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
308   char locName[MED_NAME_SIZE+1];
309   int nloc=MEDnLocalization(fid);
310   med_geometry_type typeGeo;
311   int offset=0;
312   for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=data.begin();iter!=data.end();iter++)
313     {
314       const std::string& loc=(*iter).getLocName();
315       int idLoc=1;
316       int nbOfGaussPt=-1;
317       med_int spaceDim;
318       for(;idLoc<=nloc;idLoc++)
319         {
320           char geointerpname[MED_NAME_SIZE+1]="";
321           char ipointstructmeshname[MED_NAME_SIZE+1]="";
322           med_int nsectionmeshcell;
323           med_geometry_type sectiongeotype;
324           MEDlocalizationInfo(fid,idLoc,locName,&typeGeo,&spaceDim,&nbOfGaussPt, geointerpname, ipointstructmeshname, &nsectionmeshcell,
325                               &sectiongeotype);
326           if(loc==locName)
327             break;
328         }
329       int dim=(int)INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getDimension();
330       int nbPtPerCell=(int)INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getNumberOfNodes();
331       std::vector<double> refcoo(nbPtPerCell*dim),gscoo(nbOfGaussPt*dim),w(nbOfGaussPt);
332       MEDlocalizationRd(fid,(*iter).getLocName().c_str(),MED_FULL_INTERLACE,&refcoo[0],&gscoo[0],&w[0]);
333       if((*iter).getCellIdPerType().empty())
334         f->setGaussLocalizationOnType((*iter).getType(),refcoo,gscoo,w);
335       else
336         {
337           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> pfl=DataArrayInt::New();
338           pfl->alloc((*iter).getCellIdPerType().size(),1);
339           pfl->iota(offset);
340           f->setGaussLocalizationOnCells(pfl->begin(),pfl->end(),refcoo,gscoo,w);
341         }
342       offset+=(*iter).getNbOfGeoElt();
343     }
344 }
345
346 /// @endcond
347
348 void MEDLoader::CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception)
349 {
350   MEDFileUtilities::CheckFileForRead(fileName);
351 }
352
353 std::vector<std::string> MEDLoader::GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception)
354 {
355   CheckFileForRead(fileName);
356   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
357   std::vector<std::string> ret=MEDLoaderNS::getMeshNamesFid(fid);
358   return ret;
359 }
360
361 std::vector< std::pair<std::string,std::string> > MEDLoader::GetComponentsNamesOfField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception)
362 {
363   CheckFileForRead(fileName);
364   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
365   med_int nbFields=MEDnField(fid);
366   std::vector<std::string> fields(nbFields);
367   med_field_type typcha;
368   for(int i=0;i<nbFields;i++)
369     {
370       med_int ncomp=MEDfieldnComponent(fid,i+1);
371       INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1];
372       INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1];
373       INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
374       med_int nbPdt;
375       med_bool localmesh;
376       INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
377       INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
378       MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt);
379       std::string meshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE);
380       std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1);
381       if(curFieldName==fieldName)
382         {
383           std::vector< std::pair<std::string,std::string> > ret(ncomp);
384           for(int j=0;j<ncomp;j++)
385             ret[j]=std::pair<std::string,std::string>(MEDLoaderBase::buildStringFromFortran(((char *)comp)+j*MED_SNAME_SIZE,MED_SNAME_SIZE),
386                                                       MEDLoaderBase::buildStringFromFortran(((char *)unit)+j*MED_SNAME_SIZE,MED_SNAME_SIZE));
387           return ret;
388         }
389       fields[i]=curFieldName;
390     }
391   std::ostringstream oss; oss << "MEDLoader::GetComponentsNamesOfField : no such field \"" << fieldName << "\" in file \"" << fileName << "\" !" << std::endl;
392   oss << "Possible field names are : " << std::endl;
393   std::copy(fields.begin(),fields.end(),std::ostream_iterator<std::string>(oss," "));
394   throw INTERP_KERNEL::Exception(oss.str().c_str());
395 }
396
397 /*!
398  * Given a 'fileName' and a 'meshName' this method returns global information concerning this mesh.
399  * It returns, in this order :
400  * - number of cells sorted by dimension and by geometry type. The first entry in the vector is the maximal dimension, the 2nd in the vector is the maximal dimension-1...
401  * - the mesh dimension
402  * - the space dimension
403  * - the number of nodes
404  */
405 std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > > MEDLoader::GetUMeshGlobalInfo(const char *fileName, const char *meshName, int &meshDim, int& spaceDim, int& numberOfNodes) throw(INTERP_KERNEL::Exception)
406 {
407   CheckFileForRead(fileName);
408   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
409   std::set<int> poss;
410   char nommaa[MED_NAME_SIZE+1];
411   char maillage_description[MED_COMMENT_SIZE+1];
412   med_mesh_type type_maillage;
413   std::string trueMeshName;
414   med_int meshId=MEDLoaderNS::getIdFromMeshName(fid,meshName,trueMeshName);
415   INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
416   med_sorting_type sortingType;
417   med_int nstep;
418   med_axis_type axisType;
419   int naxis=MEDmeshnAxis(fid,meshId);
420   INTERP_KERNEL::AutoPtr<char> axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
421   INTERP_KERNEL::AutoPtr<char> axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
422   MEDmeshInfo(fid,meshId,nommaa,&spaceDim,&meshDim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,axisname,axisunit); 
423   if(type_maillage!=MED_UNSTRUCTURED_MESH)
424     {
425       std::ostringstream oss; oss << "MEDLoader::GetUMeshGlobalInfo : Mesh \""<< meshName << "\" in file \"" << fileName;
426       oss << "\" exists but it is not an unstructured mesh ! This method is not relevant for mesh types that are not unstructured !";
427       throw INTERP_KERNEL::Exception(oss.str().c_str());
428     }
429   // limitation
430   if(nstep!=1)
431     throw INTERP_KERNEL::Exception("MEDLoader::GetUMeshGlobalInfo : multisteps on mesh not managed !");
432   med_int numdt,numit;
433   med_float dt;
434   MEDmeshComputationStepInfo(fid,nommaa,1,&numdt,&numit,&dt);
435   // endlimitation
436   std::vector<int> dims;
437   std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > geoTypes;
438   med_bool changement,transformation;
439   for(int i=0;i<MED_N_CELL_FIXED_GEO;i++)
440     {
441       med_geometry_type curMedType=typmai[i];
442       int curNbOfElemM=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,curMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation);
443       if(curNbOfElemM>0)
444         {
445           INTERP_KERNEL::NormalizedCellType typp=typmai2[i];
446           int mdimCell=INTERP_KERNEL::CellModel::GetCellModel(typp).getDimension();
447           dims.push_back(mdimCell);
448           geoTypes.push_back(std::pair<INTERP_KERNEL::NormalizedCellType,int>(typp,curNbOfElemM));
449         }
450     }
451   int maxLev=*std::max_element(dims.begin(),dims.end());
452   int lowLev=*std::min_element(dims.begin(),dims.end());
453   int nbOfLevels=maxLev-lowLev+1;
454   std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > > ret(nbOfLevels);
455   for(std::size_t i=0;i<dims.size();i++)
456     {
457       ret[maxLev-dims[i]].push_back(geoTypes[i]);
458     }
459   numberOfNodes=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation);
460   return ret;
461 }
462
463 std::vector<std::string> MEDLoader::GetMeshNamesOnField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception)
464 {
465   CheckFileForRead(fileName);
466   std::vector<std::string> ret;
467   //
468   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
469   med_int nbFields=MEDnField(fid);
470   //
471   med_field_type typcha;
472   INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
473   INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
474   med_bool localmesh;
475   //
476   for(int i=0;i<nbFields;i++)
477     {
478       med_int ncomp=MEDfieldnComponent(fid,i+1);
479       INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1];
480       INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1];
481       med_int nbPdt;
482       INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
483       MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt);
484       std::string meshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE);
485       std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1);
486       if(curFieldName==fieldName)
487         ret.push_back(meshName);
488     }
489   return ret;
490 }
491
492 std::vector<std::string> MEDLoader::GetMeshFamiliesNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
493 {
494   CheckFileForRead(fileName);
495   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
496   med_int nfam=MEDnFamily(fid,meshName);
497   std::vector<std::string> ret(nfam);
498   char nomfam[MED_NAME_SIZE+1];
499   med_int numfam;
500   for(int i=0;i<nfam;i++)
501     {
502       int ngro=MEDnFamilyGroup(fid,meshName,i+1);
503       med_int natt=MEDnFamily23Attribute(fid,meshName,i+1);
504       INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt];
505       INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt];
506       INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1];
507       INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1];
508       MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro);
509       std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam));
510       ret[i]=cur;
511     }
512   return ret;
513 }
514
515
516 std::vector<std::string> MEDLoader::GetMeshFamiliesNamesOnGroup(const char *fileName, const char *meshName, const char *grpName) throw(INTERP_KERNEL::Exception)
517 {
518   CheckFileForRead(fileName);
519   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
520   med_int nfam=MEDnFamily(fid,meshName);
521   std::vector<std::string> ret;
522   char nomfam[MED_NAME_SIZE+1];
523   med_int numfam;
524   for(int i=0;i<nfam;i++)
525     {
526       int ngro=MEDnFamilyGroup(fid,meshName,i+1);
527       med_int natt=MEDnFamily23Attribute(fid,meshName,i+1);
528       INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt];
529       INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt];
530       INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1];
531       INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1];
532       MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro);
533       std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam));
534       for(int j=0;j<ngro;j++)
535         {
536           std::string cur2=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
537           if(cur2==grpName)
538             ret.push_back(cur);
539         }
540     }
541   return ret;
542 }
543
544 std::vector<std::string> MEDLoader::GetMeshGroupsNamesOnFamily(const char *fileName, const char *meshName, const char *famName) throw(INTERP_KERNEL::Exception)
545 {
546   CheckFileForRead(fileName);
547   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
548   med_int nfam=MEDnFamily(fid,meshName);
549   std::vector<std::string> ret;
550   char nomfam[MED_NAME_SIZE+1];
551   med_int numfam;
552   bool found=false;
553   for(int i=0;i<nfam && !found;i++)
554     {
555       int ngro=MEDnFamilyGroup(fid,meshName,i+1);
556       med_int natt=MEDnFamily23Attribute(fid,meshName,i+1);
557       INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt];
558       INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt];
559       INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1];
560       INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1];
561       MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro);
562       std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam));
563       found=(cur==famName);
564       if(found)
565         for(int j=0;j<ngro;j++)
566           {
567             std::string cur2=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
568             ret.push_back(cur2);
569           }
570     }
571   if(!found)
572     {
573       std::ostringstream oss;
574       oss << "MEDLoader::GetMeshGroupsNamesOnFamily : no such family \"" << famName << "\" in file \"" << fileName << "\" in mesh \"" << meshName << "\" !";
575       throw INTERP_KERNEL::Exception(oss.str().c_str());
576     }
577   return ret;
578 }
579
580   
581 std::vector<std::string> MEDLoader::GetMeshGroupsNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
582 {
583   CheckFileForRead(fileName);
584   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
585   med_int nfam=MEDnFamily(fid,meshName);
586   std::vector<std::string> ret;
587   char nomfam[MED_NAME_SIZE+1];
588   med_int numfam;
589   for(int i=0;i<nfam;i++)
590     {
591       int ngro=MEDnFamilyGroup(fid,meshName,i+1);
592       med_int natt=MEDnFamily23Attribute(fid,meshName,i+1);
593       INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt];
594       INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt];
595       INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1];
596       INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1];
597       MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro);
598       for(int j=0;j<ngro;j++)
599         {
600           std::string cur=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
601           if(std::find(ret.begin(),ret.end(),cur)==ret.end())
602             ret.push_back(cur);
603         }
604     }
605   return ret;
606 }
607 std::vector<ParaMEDMEM::TypeOfField> MEDLoader::GetTypesOfField(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception)
608 {
609   CheckFileForRead(fileName);
610   std::vector<ParaMEDMEM::TypeOfField> ret;
611   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
612   med_int nbFields=MEDnField(fid);
613   //
614   med_field_type typcha;
615   //med_int nbpdtnor=0,pflsize,*pflval,lnsize;
616   med_int numdt=0,numo=0;
617   med_float dt=0.0;
618   char pflname[MED_NAME_SIZE+1]="";
619   char locname[MED_NAME_SIZE+1]="";
620   char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
621   char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
622   med_bool localmesh;
623   //
624   for(int i=0;i<nbFields;i++)
625     {
626       med_int ncomp=MEDfieldnComponent(fid,i+1);
627       INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1];
628       INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1];
629       INTERP_KERNEL::AutoPtr<char> dt_unit=new char[MED_LNAME_SIZE+1];
630       med_int nbPdt;
631       MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt);
632       std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1);
633       std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1);
634       if(curMeshName==meshName)
635         {
636           if(curFieldName==fieldName)
637             {
638               int profilesize,nbi;
639               if(nbPdt>0)
640                 {
641                   bool found=false;
642                   for(int ii=0;ii<nbPdt && !found;ii++)
643                     {
644                       MEDfieldComputingStepInfo(fid,nomcha,1,&numdt,&numo,&dt);
645                       med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_NODE,MED_NONE,1,MED_COMPACT_PFLMODE,
646                                                                 pflname,&profilesize,locname,&nbi);
647                       if(nbOfVal>0)
648                         {
649                           ret.push_back(ON_NODES);
650                           found=true;
651                         }
652                     }
653                 }
654               bool found=false;
655               for(int j=0;j<MED_N_CELL_FIXED_GEO && !found;j++)
656                 {
657                   if(nbPdt>0)
658                     {
659                       MEDfieldComputingStepInfo(fid,nomcha,1,&numdt,&numo,&dt);
660                       med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_CELL,typmai[j],1,MED_COMPACT_PFLMODE,
661                                                                 pflname,&profilesize,locname,&nbi);
662                       if(nbOfVal>0)
663                         {
664                           found=true;
665                           ret.push_back(ON_CELLS);
666                         }
667                     }
668                 }
669             }
670         }
671     }
672   delete [] maa_ass;
673   delete [] nomcha;
674   return ret;
675 }
676
677 std::vector<std::string> MEDLoader::GetAllFieldNames(const char *fileName) throw(INTERP_KERNEL::Exception)
678 {
679   CheckFileForRead(fileName);
680   std::vector<std::string> ret;
681   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
682   med_int nbFields=MEDnField(fid);
683   med_field_type typcha;
684   for(int i=0;i<nbFields;i++)
685     {
686       med_int ncomp=MEDfieldnComponent(fid,i+1);
687       INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1];
688       INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1];
689       INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
690       INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
691       INTERP_KERNEL::AutoPtr<char> dt_unit=new char[MED_LNAME_SIZE+1];
692       med_int nbPdt;
693       med_bool localmesh;
694       MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt);
695       ret.push_back(std::string(nomcha));
696     }
697   return ret;
698 }
699
700 std::vector<std::string> MEDLoader::GetAllFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
701 {
702   CheckFileForRead(fileName);
703   std::vector<std::string> ret;
704   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
705   med_int nbFields=MEDnField(fid);
706   //
707   med_field_type typcha;
708   char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
709   char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
710   //
711   for(int i=0;i<nbFields;i++)
712     {
713       med_int ncomp=MEDfieldnComponent(fid,i+1);
714       INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1];
715       INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1];
716       INTERP_KERNEL::AutoPtr<char> dt_unit=new char[MED_LNAME_SIZE+1];
717       med_int nbPdt;
718       med_bool localmesh;
719       MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt);
720       std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1);
721       std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1);
722       //
723       if(curMeshName==meshName)
724         ret.push_back(curFieldName);
725     }
726   delete [] maa_ass;
727   delete [] nomcha;
728   return ret;
729 }
730
731 std::vector<std::string> MEDLoader::GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
732 {
733   CheckFileForRead(fileName);
734   switch(type)
735     {
736     case ON_CELLS:
737       return GetCellFieldNamesOnMesh(fileName,meshName);
738     case ON_NODES:
739       return GetNodeFieldNamesOnMesh(fileName,meshName);
740     default:
741       throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !");
742     } 
743 }
744
745 std::vector<std::string> MEDLoader::GetCellFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
746 {
747   CheckFileForRead(fileName);
748   std::vector<std::string> ret;
749   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
750   med_int nbFields=MEDnField(fid);
751   //
752   med_field_type typcha;
753   //med_int nbpdtnor=0,pflsize,*pflval,lnsize;
754   med_int numdt=0,numo=0;
755   med_float dt=0.0;
756   char pflname[MED_NAME_SIZE+1]="";
757   char locname[MED_NAME_SIZE+1]="";
758   INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
759   INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
760   INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
761   med_bool localmesh;
762   med_int nbPdt;
763   //
764   for(int i=0;i<nbFields;i++)
765     {
766       med_int ncomp=MEDfieldnComponent(fid,i+1);
767       INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1];
768       INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1];
769       MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt);
770       std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1);
771       std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1);
772       int profilesize,nbi;
773       if(curMeshName==meshName)
774         {
775           bool found=false;
776           for(int j=0;j<MED_N_CELL_FIXED_GEO && !found;j++)
777             {
778               if(nbPdt>0)
779                 {
780                   MEDfieldComputingStepInfo(fid,nomcha,1,&numdt,&numo,&dt);
781                   med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_CELL,typmai[j],1,MED_COMPACT_PFLMODE,
782                                                             pflname,&profilesize,locname,&nbi);
783                   if(nbOfVal>0)
784                     {
785                       found=true;
786                       ret.push_back(curFieldName);
787                     }
788                 }
789             }
790         }
791     }
792   return ret;
793 }
794
795 std::vector<std::string> MEDLoader::GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
796 {
797   CheckFileForRead(fileName);
798   std::vector<std::string> ret;
799   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
800   med_int nbFields=MEDnField(fid);
801   char pflname[MED_NAME_SIZE+1]="";
802   char locname[MED_NAME_SIZE+1]="";
803   //
804   med_field_type typcha;
805   med_int numdt=0,numo=0;
806   med_float dt=0.0;
807   INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
808   INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
809   INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
810   med_bool localmesh;
811   //
812   for(int i=0;i<nbFields;i++)
813     {
814       med_int ncomp=MEDfieldnComponent(fid,i+1);
815       INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1];
816       INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1];
817       med_int nbPdt;
818       MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt);
819       std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1);
820       std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1);
821       if(nbPdt>0)
822         {
823           int profilesize,nbi;
824           MEDfieldComputingStepInfo(fid,nomcha,1,&numdt,&numo,&dt);
825           med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_NODE,MED_NONE,1,MED_COMPACT_PFLMODE,
826                                                     pflname,&profilesize,locname,&nbi);
827           if(curMeshName==meshName && nbOfVal>0)
828             {
829               ret.push_back(curFieldName);
830             }
831         }
832     }
833   return ret;
834 }
835
836 std::vector< std::pair< std::pair<int,int>, double> > MEDLoader::GetAllFieldIterations(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception)
837 {
838   CheckFileForRead(fileName);
839   std::vector< std::pair< std::pair<int,int>, double > > ret;
840   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
841   med_int nbFields=MEDnField(fid);
842   //
843   med_field_type typcha;
844   med_int numdt=0,numo=0;
845   med_float dt=0.0;
846   INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
847   INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
848   INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
849   med_bool localmesh;
850   //
851   std::ostringstream oss; oss << "MEDLoader::GetAllFieldIterations : No field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : ";
852   for(int i=0;i<nbFields;i++)
853     {
854       med_int ncomp=MEDfieldnComponent(fid,i+1);
855       INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1];
856       INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1];
857       med_int nbPdt;
858       MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt);
859       std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1);
860       if(curFieldName==fieldName)
861         {
862           for(int k=0;k<nbPdt;k++)
863             {
864               MEDfieldComputingStepInfo(fid,nomcha,k+1,&numdt,&numo,&dt);
865               ret.push_back(std::make_pair(std::make_pair(numdt,numo),dt));
866             }
867           return ret;
868         }
869       else
870         {
871           oss << "\"" << curFieldName << "\"";
872           if(i!=nbFields-1) oss << ", ";
873         }
874     }
875   oss << " !";
876   throw INTERP_KERNEL::Exception(oss.str().c_str());
877 }
878
879 double MEDLoader::GetTimeAttachedOnFieldIteration(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
880 {
881   CheckFileForRead(fileName);
882   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
883   med_int nbFields=MEDnField(fid);
884   //
885   med_field_type typcha;
886   med_int numdt=0,numo=0;
887   med_float dt=0.0;
888   med_bool local;
889   INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
890   INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
891   INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
892   //
893   bool found=false;
894   bool found2=false;
895   double ret=std::numeric_limits<double>::max();
896   for(int i=0;i<nbFields && !found;i++)
897     {
898       med_int ncomp=MEDfieldnComponent(fid,i+1);
899       INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1];
900       INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1];
901       med_int nbPdt;
902       MEDfieldInfo(fid,i+1,nomcha,maa_ass,&local,&typcha,comp,unit,dt_unit,&nbPdt);
903       std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1);
904       if(curFieldName==fieldName)
905         {
906           found=true;
907           for(int k=0;k<nbPdt;k++)
908             {
909               MEDfieldComputingStepInfo(fid,nomcha,k+1,&numdt,&numo,&dt);
910               if(numdt==iteration && numo==order)
911                 {
912                   found2=true;
913                   ret=dt;
914                 }
915             }
916         }
917     }
918   if(!found || !found2)
919     {
920       std::ostringstream oss;
921       oss << "No such field with name \"" << fieldName << "\" and iteration,order=(" << iteration << "," << order << ") exists in file \"" << fileName << "\" !";
922       throw INTERP_KERNEL::Exception(oss.str().c_str());
923     }
924   return ret;
925 }
926
927 std::vector< std::pair<int,int> > MEDLoader::GetFieldIterations(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception)
928 {
929   CheckFileForRead(fileName);
930   switch(type)
931     {
932     case ON_CELLS:
933       return GetCellFieldIterations(fileName,meshName,fieldName);
934     case ON_NODES:
935       return GetNodeFieldIterations(fileName,meshName,fieldName);
936     default:
937       throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !");
938     }
939 }
940
941 std::vector< std::pair<int,int> > MEDLoader::GetCellFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception)
942 {
943   CheckFileForRead(fileName);
944   std::string meshNameCpp(meshName);
945   std::vector< std::pair<int,int> > ret;
946   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
947   med_int nbFields=MEDnField(fid);
948   //
949   med_field_type typcha;
950   med_int numdt=0,numo=0;
951   med_float dt=0.0;
952   char pflname[MED_NAME_SIZE+1]="";
953   char locname[MED_NAME_SIZE+1]="";
954   INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
955   INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
956   INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
957   med_bool localmesh;
958   //
959   std::ostringstream oss; oss << "MEDLoader::GetCellFieldIterations : No cell Field field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : ";
960   std::set<std::string> s2;
961   for(int i=0;i<nbFields;i++)
962     {
963       med_int ncomp=MEDfieldnComponent(fid,i+1);
964       INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1];
965       INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1];
966       med_int nbPdt;
967       MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt);
968       std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1);
969       if(curFieldName==fieldName)
970         {
971           bool found=false;
972           for(int j=0;j<MED_N_CELL_FIXED_GEO && !found;j++)
973             {
974               for(int k=0;k<nbPdt;k++)
975                 {
976                   int profilesize,nbi;
977                   MEDfieldComputingStepInfo(fid,nomcha,k+1,&numdt,&numo,&dt);
978                   med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_CELL,typmai[j],1,MED_COMPACT_PFLMODE,
979                                                             pflname,&profilesize,locname,&nbi);
980                   std::string maa_ass_cpp(maa_ass);
981                   if(nbOfVal>0)
982                     {
983                       if(meshNameCpp==maa_ass_cpp)
984                         {
985                           found=true;
986                           ret.push_back(std::make_pair(numdt,numo));
987                         }
988                       else
989                         s2.insert(maa_ass_cpp);
990                     }
991                 }
992             }
993         }
994       else
995         {
996           oss << "\"" << curFieldName << "\"";
997           if(i!=nbFields-1) oss << ", ";
998         }
999     }
1000   if(ret.empty())
1001     {
1002       if(!s2.empty())
1003         {
1004           oss << ". Cell Field \"" << fieldName << "\" exists but lies on meshes with names : \"";
1005           std::copy(s2.begin(),s2.end(),std::ostream_iterator<std::string>(oss,"\", \""));
1006         }
1007       oss << " !";
1008       throw INTERP_KERNEL::Exception(oss.str().c_str());
1009     }
1010   return ret;
1011 }
1012
1013 std::vector< std::pair<int,int> > MEDLoader::GetNodeFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception)
1014 {
1015   CheckFileForRead(fileName);
1016   std::string meshNameCpp(meshName);
1017   std::vector< std::pair<int,int> > ret;
1018   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1019   med_int nbFields=MEDnField(fid);
1020   //
1021   med_field_type typcha;
1022   med_int numdt=0,numo=0;
1023   med_float dt=0.0;
1024   char pflname[MED_NAME_SIZE+1]="";
1025   char locname[MED_NAME_SIZE+1]="";
1026   INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
1027   INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
1028   INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
1029   med_bool localmesh;
1030   //
1031   std::ostringstream oss; oss << "MEDLoader::GetNodeFieldIterations : No node Field field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : ";
1032   std::set<std::string> s2;
1033   for(int i=0;i<nbFields;i++)
1034     {
1035       med_int ncomp=MEDfieldnComponent(fid,i+1);
1036       INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1];
1037       INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1];
1038       med_int nbPdt;
1039       MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt);
1040       std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1);
1041       if(curFieldName==fieldName)
1042         {
1043           for(int k=0;k<nbPdt;k++)
1044             {
1045               int profilesize,nbi;
1046               MEDfieldComputingStepInfo(fid,nomcha,k+1,&numdt,&numo,&dt);
1047               med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_NODE,MED_NONE,1,MED_COMPACT_PFLMODE,
1048                                                         pflname,&profilesize,locname,&nbi);
1049                std::string maa_ass_cpp(maa_ass);
1050                if(nbOfVal>0)
1051                  {
1052                    if(meshNameCpp==maa_ass_cpp)
1053                      { ret.push_back(std::make_pair(numdt,numo)); }
1054                    else
1055                      s2.insert(maa_ass_cpp);
1056                  }
1057             }
1058         }
1059       else
1060         {
1061           oss << "\"" << curFieldName << "\"";
1062           if(i!=nbFields-1) oss << ", ";
1063         }
1064     }
1065   if(ret.empty())
1066     {
1067       if(!s2.empty())
1068         {
1069           oss << ". Node Field \"" << fieldName << "\" exists but lies on meshes with names : \"";
1070           std::copy(s2.begin(),s2.end(),std::ostream_iterator<std::string>(oss,"\", \""));
1071         }
1072       oss << " !";
1073       throw INTERP_KERNEL::Exception(oss.str().c_str());
1074     }
1075   return ret;
1076 }
1077
1078 /*!
1079  * This method reads all the content of a field 'fieldName' at a time specified by (iteration,order) lying on a mesh 'meshName' with a specified type 'TypeOfOutField'
1080  * The returned values are strored in 'field' (sorted by type of cell), time corresponding to field, and 'infos' to load properly little strings.
1081  * The principle of this method is to put into 'field' only data that fulfills \b perfectly request.
1082  */
1083 void MEDLoaderNS::readFieldDoubleDataInMedFile(const char *fileName, const char *meshName, const char *fieldName, 
1084                                                int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField,
1085                                                std::list<MEDLoader::MEDFieldDoublePerCellType>& field,
1086                                                double& time, std::vector<std::string>& infos)
1087 {
1088   time=0.;
1089   MEDFileUtilities::CheckFileForRead(fileName);
1090   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1091   med_int nbFields=MEDnField(fid);
1092   //
1093   med_field_type typcha;
1094   char nomcha[MED_NAME_SIZE+1]="";
1095   char pflname [MED_NAME_SIZE+1]="";
1096   char locname [MED_NAME_SIZE+1]="";
1097   std::map<ParaMEDMEM::TypeOfField, med_entity_type> tabEnt;
1098   std::map<ParaMEDMEM::TypeOfField, med_geometry_type *> tabType;
1099   std::map<ParaMEDMEM::TypeOfField, int> tabTypeLgth;
1100   med_bool localmesh;
1101   bool found=false;
1102   tabEnt[ON_CELLS]=MED_CELL;
1103   tabType[ON_CELLS]=typmai;
1104   tabTypeLgth[ON_CELLS]=MED_N_CELL_FIXED_GEO;
1105   tabEnt[ON_NODES]=MED_NODE;
1106   tabType[ON_NODES]=typmainoeud;
1107   tabTypeLgth[ON_NODES]=1;
1108   tabEnt[ON_GAUSS_PT]=MED_CELL;
1109   tabType[ON_GAUSS_PT]=typmai;
1110   tabTypeLgth[ON_GAUSS_PT]=MED_N_CELL_FIXED_GEO;
1111   tabEnt[ON_GAUSS_NE]=MED_NODE_ELEMENT;
1112   tabType[ON_GAUSS_NE]=typmai;
1113   tabTypeLgth[ON_GAUSS_NE]=MED_N_CELL_FIXED_GEO;
1114   //
1115   for(int i=0;i<nbFields && !found;i++)
1116     {
1117       med_int ncomp=MEDfieldnComponent(fid,i+1);
1118       INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1];
1119       INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1];
1120       INTERP_KERNEL::AutoPtr<char> dt_unit=new char[MED_LNAME_SIZE+1];
1121       INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
1122       med_int nbPdt;
1123       MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt);
1124       std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1);
1125       std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1);
1126       found=(curFieldName==fieldName) && (curMeshName==meshName);
1127       if(found)
1128         {
1129           infos.resize(ncomp);
1130           for(int ii=0;ii<ncomp;ii++)
1131             infos[ii]=MEDLoaderBase::buildUnionUnit(comp+ii*MED_SNAME_SIZE,MED_SNAME_SIZE,unit+ii*MED_SNAME_SIZE,MED_SNAME_SIZE);
1132           bool found2=false;
1133           med_int numdt=0,numo=0;
1134           med_float dt=0.0;
1135           for(int k=0;k<nbPdt && !found2;k++)
1136             {
1137               MEDfieldComputingStepInfo(fid,fieldName,k+1,&numdt,&numo,&dt);
1138               found2=(numdt==iteration && numo==order);
1139               if(found2)
1140                 time=dt;
1141             }
1142           if(!found2)
1143             {
1144               std::ostringstream oss; oss << "FieldDouble in file \""<< fileName<< "\" with name \"" << fieldName << "\" on mesh \"" <<  meshName;
1145               oss << "\" does not have such time step : iteration=" << iteration << " order=" << order << std::endl;
1146               throw INTERP_KERNEL::Exception(oss.str().c_str());
1147             }
1148           for(int j=0;j<tabTypeLgth[typeOfOutField];j++)
1149             {
1150               if(nbPdt>0)
1151                 {
1152                   INTERP_KERNEL::AutoPtr<char> pflDummy=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
1153                   INTERP_KERNEL::AutoPtr<char> locDummy=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
1154                   int nbProfiles=MEDfieldnProfile(fid,fieldName,numdt,numo,tabEnt[typeOfOutField],tabType[typeOfOutField][j],pflDummy,locDummy);
1155                   for(int kk=0;kk<nbProfiles;kk++)
1156                     {
1157                       int profilesize,nbi;
1158                       int nval=MEDfieldnValueWithProfile(fid,fieldName,numdt,numo,tabEnt[typeOfOutField],tabType[typeOfOutField][j],kk+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi);
1159                       if(nval>0)
1160                         {
1161                           double *valr=new double[ncomp*nval*nbi];
1162                           MEDfieldValueWithProfileRd(fid,fieldName,iteration,order,tabEnt[typeOfOutField],tabType[typeOfOutField][j],MED_COMPACT_PFLMODE,
1163                                                      pflname,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,(unsigned char*)valr);
1164                           std::string tmp(locname);
1165                           if((locname[0]!='\0' && (typeOfOutField!=ON_GAUSS_PT))
1166                              || (locname[0]=='\0' && typeOfOutField==ON_GAUSS_PT))
1167                             {
1168                               delete [] valr;
1169                               continue;
1170                             }
1171                           INTERP_KERNEL::AutoPtr<int> pfl=0;
1172                           if(pflname[0]!='\0')
1173                             {
1174                               pfl=new int[nval];
1175                               MEDprofileRd(fid,pflname,pfl);
1176                             }
1177                           field.push_back(MEDLoader::MEDFieldDoublePerCellType(typmai2[j],valr,ncomp,nval,nbi,pfl,locname));
1178                         }
1179                     }
1180                 }
1181             }
1182         }
1183     }
1184   if(!found)
1185     {
1186       std::ostringstream oss; oss << "MEDLoaderNS::readFieldDoubleDataInMedFile : no such couple meshName=\"" << meshName << "\", fieldName=\"" << fieldName << "\" in file \"" << fileName << "\" !";
1187       throw INTERP_KERNEL::Exception(oss.str().c_str());
1188     }
1189 }
1190
1191 std::vector<int> MEDLoaderNS::getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector<std::string>& fams)
1192 {
1193   std::vector<int> ret;
1194   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1195   med_int nfam=MEDnFamily(fid,meshName);
1196   char nomfam[MED_NAME_SIZE+1];
1197   med_int numfam;
1198   for(int i=0;i<nfam;i++)
1199     {
1200       int ngro=MEDnFamilyGroup(fid,meshName,i+1);
1201       med_int natt=MEDnFamily23Attribute(fid,meshName,i+1);
1202       INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt];
1203       INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt];
1204       INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1];
1205       INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1];
1206       MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro);
1207       std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam));
1208       if(std::find(fams.begin(),fams.end(),cur)!=fams.end())
1209         ret.push_back(numfam);
1210     }
1211   return ret;
1212 }
1213
1214 std::vector<int> MEDLoaderNS::getIdsFromGroups(const char *fileName, const char *meshName, const std::vector<std::string>& grps)
1215 {
1216   std::vector<int> ret;
1217   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1218   med_int nfam=MEDnFamily(fid,meshName);
1219   char nomfam[MED_NAME_SIZE+1];
1220   med_int numfam;
1221   for(int i=0;i<nfam;i++)
1222     {
1223       int ngro=MEDnFamilyGroup(fid,meshName,i+1);
1224       med_int natt=MEDnFamily23Attribute(fid,meshName,i+1);
1225       INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt];
1226       INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt];
1227       INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1];
1228       INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1];
1229       MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro);
1230       std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam));
1231       for(int j=0;j<ngro;j++)
1232         {
1233           std::string cur2=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
1234           if(std::find(grps.begin(),grps.end(),cur2)!=grps.end())
1235             {
1236               ret.push_back(numfam);
1237               break;
1238             }
1239         }
1240     }
1241   return ret;
1242 }
1243
1244 med_int MEDLoaderNS::getIdFromMeshName(med_idt fid, const char *meshName, std::string& trueMeshName) throw(INTERP_KERNEL::Exception)
1245 {
1246   if(meshName==0)
1247     {
1248       std::vector<std::string> meshes=getMeshNamesFid(fid);
1249       if(meshes.empty())
1250         throw INTERP_KERNEL::Exception("No mesh in file");
1251       trueMeshName=meshes[0];
1252       return 1;
1253     }
1254   std::string meshNameStr(meshName);
1255   std::vector<std::string> meshes=getMeshNamesFid(fid);
1256   if(meshes.empty())
1257     throw INTERP_KERNEL::Exception("No mesh in file");
1258   std::vector<std::string>::iterator iter=std::find(meshes.begin(),meshes.end(),meshNameStr);
1259   if(iter==meshes.end())
1260     {
1261       std::ostringstream os2;
1262       os2 << "MeshName '" << meshName << "' not in file : meshes available : ";
1263       std::copy(meshes.begin(),meshes.end(),std::ostream_iterator<std::string>(os2," "));
1264       throw INTERP_KERNEL::Exception(os2.str().c_str());
1265     }
1266   trueMeshName=meshName;
1267   return iter-meshes.begin()+1;
1268 }
1269
1270 /*!
1271  * This methods allows to merger all entities and to considerate only cell types.
1272  */
1273 void MEDLoaderNS::dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity)
1274 {
1275   if(nbOfElemCell>=nbOfElemFace)
1276     {
1277       whichEntity=MED_CELL;
1278       nbOfElem=nbOfElemCell;
1279     }
1280   else
1281     {
1282       whichEntity=MED_CELL;
1283       nbOfElem=nbOfElemFace;
1284     }
1285 }
1286
1287 /*!
1288  * This method returns a first quick overview of mesh with name 'meshName' into the file 'fileName'.
1289  * @param possibilities the relativeToMeshDim authorized to returned maxdim. This vector is systematically cleared at the begin of this method.
1290  * @return the maximal mesh dimension of specified mesh. If nothing found -1 is returned.
1291  */
1292 int MEDLoaderNS::readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector<int>& possibilities)
1293 {
1294   possibilities.clear();
1295   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1296   int ret;
1297   std::set<int> poss;
1298   char nommaa[MED_NAME_SIZE+1];
1299   char maillage_description[MED_COMMENT_SIZE+1];
1300   med_mesh_type type_maillage;
1301   med_int Sdim,Mdim;
1302   std::string trueMeshName;
1303   med_int meshId=getIdFromMeshName(fid,meshName,trueMeshName);
1304   INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
1305   med_sorting_type sortingType;
1306   med_int nstep;
1307   med_axis_type axisType;
1308   int naxis=MEDmeshnAxis(fid,meshId);
1309   INTERP_KERNEL::AutoPtr<char> axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
1310   INTERP_KERNEL::AutoPtr<char> axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE);
1311   MEDmeshInfo(fid,meshId,nommaa,&Sdim,&Mdim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,axisname,axisunit);
1312   // limitation
1313   if(nstep!=1)
1314     {
1315       throw INTERP_KERNEL::Exception("multisteps on mesh not managed yet !");
1316     } 
1317   med_int numdt,numit;
1318   med_float dt;
1319   MEDmeshComputationStepInfo(fid,nommaa,1,&numdt,&numit,&dt);
1320   // endlimitation
1321   for(int i=0;i<MED_N_CELL_GEO_FIXED_CON;i++)
1322     {
1323       med_geometry_type curMedType=typmai[i];
1324       med_bool changement,transformation;
1325       int curNbOfElemM=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,curMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation);
1326       int curNbOfElemF=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,curMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation);//limitation
1327       int curNbOfElem;
1328       med_entity_type whichEntity;
1329       MEDLoaderNS::dispatchElems(curNbOfElemM,curNbOfElemF,curNbOfElem,whichEntity);
1330       if(curNbOfElem>0)
1331         {
1332           INTERP_KERNEL::NormalizedCellType type=typmai2[i];
1333           int curDim=(int)INTERP_KERNEL::CellModel::GetCellModel(type).getDimension();
1334           poss.insert(curDim);
1335         }
1336     }
1337   if(!poss.empty())
1338     {
1339       ret=*poss.rbegin();
1340       for(std::set<int>::const_reverse_iterator it=poss.rbegin();it!=poss.rend();it++)
1341         possibilities.push_back(*it-ret);
1342     }
1343   else
1344     ret=-2;
1345   return ret;
1346 }
1347
1348 void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayDouble *&coords, std::list<MEDLoader::MEDConnOfOneElemType>& conn, std::string& description)
1349 {
1350   char nommaa[MED_NAME_SIZE+1];
1351   char maillage_description[MED_COMMENT_SIZE+1];
1352   med_mesh_type type_maillage;
1353   med_int Mdim;
1354   med_int Sdim;
1355   INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
1356   med_sorting_type sortingType;
1357   med_int nstep;
1358   med_axis_type axisType;
1359   med_int numdt,numit;
1360   med_float dt;
1361   med_bool changement,transformation;
1362   // endlimitation
1363   Sdim=MEDmeshnAxis(fid,1);
1364   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(Sdim*MED_SNAME_SIZE);
1365   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(Sdim*MED_SNAME_SIZE);
1366   MEDmeshInfo(fid,meshId,nommaa,&Sdim,&Mdim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,comp,unit);
1367   description=MEDLoaderBase::buildStringFromFortran(maillage_description,sizeof(maillage_description));
1368   MEDmeshComputationStepInfo(fid,nommaa,1,&numdt,&numit,&dt);
1369   int spaceDim=std::max((int)Mdim,(int)Sdim);
1370   int nCoords=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation);
1371   // limitation
1372   if(nstep!=1)
1373     {
1374       throw INTERP_KERNEL::Exception("multisteps on mesh not managed yet !");
1375     }
1376   coords=DataArrayDouble::New();
1377   coords->alloc(nCoords,spaceDim);
1378   double *coordsPtr=coords->getPointer();
1379   MEDmeshNodeCoordinateRd(fid,nommaa,numdt,numit,MED_FULL_INTERLACE,coordsPtr);
1380   for(int i=0;i<spaceDim;i++)
1381     {
1382       std::string info=MEDLoaderBase::buildUnionUnit(comp+i*MED_SNAME_SIZE,MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,MED_SNAME_SIZE);
1383       coords->setInfoOnComponent(i,info.c_str());
1384     }
1385   for(int i=0;i<MED_N_CELL_GEO_FIXED_CON;i++)
1386     {
1387       med_geometry_type curMedType=typmai[i];
1388       med_entity_type whichEntity;
1389       int curNbOfElemM=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,curMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation);
1390       int curNbOfElemF=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,curMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation);//limitation
1391       int curNbOfElem;
1392       MEDLoaderNS::dispatchElems(curNbOfElemM,curNbOfElemF,curNbOfElem,whichEntity);
1393       if(curNbOfElem>0)
1394         {
1395           int *connTab=new int[(curMedType%100)*curNbOfElem];
1396           int *fam=new int[curNbOfElem];
1397           MEDLoader::MEDConnOfOneElemType elem(typmai2[i],connTab,0,fam,curNbOfElem,-1);
1398           char *noms=new char[MED_SNAME_SIZE*curNbOfElem+1];
1399           med_bool withname=MED_FALSE,withnumber=MED_FALSE,withfam=MED_FALSE;
1400           int *globArr=new int[curNbOfElem];
1401           MEDmeshElementRd(fid,nommaa,numdt,numit,whichEntity,curMedType,MED_NODAL,MED_FULL_INTERLACE,connTab,&withname,noms,&withnumber,globArr,&withfam,fam);
1402           if(!withfam)
1403             std::fill(fam,fam+curNbOfElem,0);
1404           delete [] noms;
1405           //trying to read global numbering
1406           if(withnumber)
1407             elem.setGlobal(globArr);
1408           else
1409             delete [] globArr;
1410           //limitation manage withfam==false
1411           conn.push_back(elem);
1412         }
1413     }
1414   int curNbOfPolyElem;
1415   int curNbOfPolyElemM=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)-1;
1416   int curNbOfPolyElemF=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)-1;//limitation
1417   med_entity_type whichPolyEntity;
1418   MEDLoaderNS::dispatchElems(curNbOfPolyElemM,curNbOfPolyElemF,curNbOfPolyElem,whichPolyEntity);
1419   if(curNbOfPolyElem>0)
1420     {
1421       med_int arraySize=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation);
1422       int *index=new int[curNbOfPolyElem+1];
1423       int *locConn=new int[arraySize];
1424       int *fam=new int[curNbOfPolyElem];
1425       int *globArr=new int[curNbOfPolyElem];
1426       MEDLoader::MEDConnOfOneElemType elem(INTERP_KERNEL::NORM_POLYGON,locConn,index,fam,curNbOfPolyElem,arraySize);
1427       MEDmeshPolygonRd(fid,nommaa,numdt,numit,MED_CELL,MED_NODAL,index,locConn);
1428       if(MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0)
1429         {
1430           if(MEDmeshEntityFamilyNumberRd(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,fam)!=0)
1431             std::fill(fam,fam+curNbOfPolyElem,0);
1432         }
1433       else
1434         std::fill(fam,fam+curNbOfPolyElem,0);
1435       if(MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_NUMBER,MED_NODAL,&changement,&transformation)>0)
1436         {
1437           if(MEDmeshEntityNumberRd(fid,nommaa,numdt,numit,whichPolyEntity,MED_POLYGON,globArr)==0)
1438             elem.setGlobal(globArr);
1439           else
1440             delete [] globArr;
1441         }
1442       else
1443         delete [] globArr;
1444       conn.push_back(elem);
1445     }
1446   curNbOfPolyElem=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYHEDRON,MED_INDEX_FACE,MED_NODAL,&changement,&transformation)-1;
1447   if(curNbOfPolyElem>0)
1448     {
1449       med_int indexFaceLgth,connFaceLgth;
1450       indexFaceLgth=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYHEDRON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation);
1451       connFaceLgth=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYHEDRON,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation);
1452       INTERP_KERNEL::AutoPtr<int> index=new int[curNbOfPolyElem+1];
1453       INTERP_KERNEL::AutoPtr<int> indexFace=new int[indexFaceLgth];
1454       INTERP_KERNEL::AutoPtr<int> locConn=new int[connFaceLgth];
1455       int *fam=new int[curNbOfPolyElem];
1456       int *globArr=new int[curNbOfPolyElem];
1457       MEDmeshPolyhedronRd(fid,nommaa,numdt,numit,MED_CELL,MED_NODAL,index,indexFace,locConn);
1458       if(MEDmeshnEntity(fid,nommaa,numdt,numit,whichPolyEntity,MED_POLYHEDRON,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0)
1459         {
1460           if(MEDmeshEntityFamilyNumberRd(fid,nommaa,numdt,numit,whichPolyEntity,MED_POLYHEDRON,fam)!=0)
1461             std::fill(fam,fam+curNbOfPolyElem,0);
1462         }
1463       else
1464         std::fill(fam,fam+curNbOfPolyElem,0);
1465       int arraySize=connFaceLgth;
1466       for(int i=0;i<curNbOfPolyElem;i++)
1467         arraySize+=index[i+1]-index[i]-1;
1468       int *finalConn=new int[arraySize];
1469       int *finalIndex=new int[curNbOfPolyElem+1];
1470       finalIndex[0]=1;
1471       int *wFinalConn=finalConn;
1472       for(int i=0;i<curNbOfPolyElem;i++)
1473         {
1474           finalIndex[i+1]=finalIndex[i]+index[i+1]-index[i]-1+indexFace[index[i+1]-1]-indexFace[index[i]-1];
1475           wFinalConn=std::copy(locConn+indexFace[index[i]-1]-1,locConn+indexFace[index[i]]-1,wFinalConn);
1476           for(int j=index[i];j<index[i+1]-1;j++)
1477             {
1478               *wFinalConn++=0;
1479               wFinalConn=std::copy(locConn+indexFace[j]-1,locConn+indexFace[j+1]-1,wFinalConn);
1480             }
1481         }
1482       MEDLoader::MEDConnOfOneElemType elem(INTERP_KERNEL::NORM_POLYHED,finalConn,finalIndex,fam,curNbOfPolyElem,arraySize);
1483       if(MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYHEDRON,MED_NUMBER,MED_NODAL,&changement,&transformation)>0)
1484         {
1485           if(MEDmeshEntityNumberRd(fid,nommaa,numdt,numit,whichPolyEntity,MED_POLYHEDRON,globArr)==0)
1486             elem.setGlobal(globArr);
1487           else
1488             delete [] globArr;
1489         }
1490       else
1491         delete [] globArr;
1492       conn.push_back(elem);
1493     }
1494 }
1495
1496 /// @cond INTERNAL
1497
1498 namespace MEDLoaderNS
1499 {
1500   template<class T>
1501   unsigned calculateHighestMeshDim(const std::list<T>& conn)
1502   {
1503     unsigned ret=0;
1504     for(typename std::list<T>::const_iterator iter=conn.begin();iter!=conn.end();iter++)
1505       {
1506         unsigned curDim=INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getDimension();
1507         if(ret<curDim)
1508           ret=curDim;
1509       }
1510     return ret;
1511   }
1512   
1513   template<class T>
1514   void keepSpecifiedMeshDim(typename std::list<T>& conn, unsigned meshDim)
1515   {
1516     for(typename std::list<T>::iterator iter=conn.begin();iter!=conn.end();)
1517       {
1518         unsigned curDim=INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getDimension();
1519         if(curDim!=meshDim)
1520           {
1521             (*iter).releaseArray();
1522             iter=conn.erase(iter);
1523           }
1524         else
1525           iter++;
1526       }
1527   }
1528   
1529   template<class T>
1530   void keepTypes(typename std::list<T>& conn, const std::vector<INTERP_KERNEL::NormalizedCellType>& typesToKeep)
1531   {
1532     if(!typesToKeep.empty())
1533       {
1534         for(typename std::list<T>::iterator iter=conn.begin();iter!=conn.end();)
1535           {
1536             INTERP_KERNEL::NormalizedCellType curType=(*iter).getType();
1537             if(std::find(typesToKeep.begin(),typesToKeep.end(),curType)==typesToKeep.end())
1538               {
1539                 (*iter).releaseArray();
1540                 iter=conn.erase(iter);
1541               }
1542             else
1543               iter++;
1544           }
1545       }
1546   }
1547 }
1548
1549 class FieldPerTypeAccumulator
1550 {
1551 public:
1552   int operator()(int res, const MEDLoader::MEDFieldDoublePerCellType& elt) { return res+elt.getNbOfTuple(); }
1553 };
1554
1555 ParaMEDMEM::DataArrayDouble *MEDLoaderNS::buildArrayFromRawData(const std::list<MEDLoader::MEDFieldDoublePerCellType>& fieldPerType,
1556                                                                 const std::vector<std::string>& infos)
1557 {
1558   ParaMEDMEM::DataArrayDouble *ret=ParaMEDMEM::DataArrayDouble::New();
1559   int totalNbOfTuple=std::accumulate(fieldPerType.begin(),fieldPerType.end(),0,FieldPerTypeAccumulator());
1560   int nbOfComp=(*fieldPerType.begin()).getNbComp();
1561   double *ptr=new double[nbOfComp*totalNbOfTuple];
1562   ret->useArray(ptr,true,ParaMEDMEM::CPP_DEALLOC,totalNbOfTuple,nbOfComp);
1563   std::for_each(fieldPerType.begin(),fieldPerType.end(),FieldPerTypeCopier(ptr));
1564   for(int i=0;i<nbOfComp;i++)
1565     ret->setInfoOnComponent(i,infos[i].c_str());
1566   return ret;
1567 }
1568
1569 class PolyCounterForFams
1570 {
1571 public:
1572   PolyCounterForFams(int id, const int *index):_id(id),_index(index),_count(0),_sigma(0) { }
1573   void operator()(int val) { if(val==_id) _sigma+=_index[_count+1]-_index[_count]; _count++; }
1574   int getSigma() const { return _sigma; }
1575 private:
1576   int _id;
1577   const int *_index;
1578   int _count;
1579   int _sigma;
1580 };
1581
1582 /*!
1583  * This method fills unstructured connectivity using basic MED file format 'medConnFrmt'.
1584  * If in each elements of 'medConnFrmt' a renumbering cell array is found the aggregate array 'cellRenum' is returned.
1585  */
1586 void MEDLoaderNS::tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDLoader::MEDConnOfOneElemType>& medConnFrmt,
1587                                                        const std::vector<int>& familiesToKeep,
1588                                                        DataArrayInt* &conn,
1589                                                        DataArrayInt* &connIndex,
1590                                                        int *&cellRenum)
1591 {
1592   bool keepAll=familiesToKeep.empty();
1593   if(medConnFrmt.empty())
1594     {
1595       conn=0;
1596       connIndex=0;
1597       cellRenum=0;
1598       return ;
1599     }
1600   std::list<MEDLoader::MEDConnOfOneElemType>::const_iterator iter=medConnFrmt.begin();
1601   int totalNbOfCells=0;
1602   int totalNbOfMedConn=0;
1603   bool renumber=true;
1604   cellRenum=0;
1605   for(;iter!=medConnFrmt.end();iter++)
1606     {
1607       if((*iter).getGlobal()==0)
1608         renumber=false;
1609       const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::GetCellModel((*iter).getType());
1610       if(keepAll)
1611         totalNbOfCells+=(*iter).getLength();
1612       else
1613         for(std::vector<int>::const_iterator iter2=familiesToKeep.begin();iter2!=familiesToKeep.end();iter2++)
1614           totalNbOfCells+=std::count((*iter).getFam(),(*iter).getFam()+(*iter).getLength(),*iter2);
1615       if(!cellMod.isDynamic())
1616         if(keepAll)
1617           totalNbOfMedConn+=(*iter).getLength()*cellMod.getNumberOfNodes();
1618         else
1619           for(std::vector<int>::const_iterator iter2=familiesToKeep.begin();iter2!=familiesToKeep.end();iter2++)
1620             totalNbOfMedConn+=std::count((*iter).getFam(),(*iter).getFam()+(*iter).getLength(),*iter2)*cellMod.getNumberOfNodes();
1621       else
1622         if(keepAll)
1623           totalNbOfMedConn+=(*iter).getConnLength();
1624         else
1625           for(std::vector<int>::const_iterator iter2=familiesToKeep.begin();iter2!=familiesToKeep.end();iter2++)
1626             {
1627               PolyCounterForFams res=std::for_each((*iter).getFam(),(*iter).getFam()+(*iter).getLength(),PolyCounterForFams(*iter2,(*iter).getIndex()));
1628               totalNbOfMedConn+=res.getSigma();
1629             }
1630     }
1631   connIndex=DataArrayInt::New();
1632   conn=DataArrayInt::New();
1633   connIndex->alloc(totalNbOfCells+1,1);
1634   int *connIdxPtr=connIndex->getPointer();
1635   int connFillId=0;
1636   conn->alloc(totalNbOfMedConn+totalNbOfCells,1);
1637   int *connPtr=conn->getPointer();
1638   if(renumber)
1639     cellRenum=new int[totalNbOfCells];
1640   int *renumW=cellRenum;
1641   for(iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++)
1642     {
1643       INTERP_KERNEL::NormalizedCellType type=(*iter).getType();
1644       const int *sourceConn=(*iter).getArray();
1645       const int *sourceIndex=(*iter).getIndex();
1646       const int *globalNum=(*iter).getGlobal();
1647       const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::GetCellModel(type);
1648       int nbOfCellsInCurType;
1649       int nbOfNodesIn1Cell=cellMod.getNumberOfNodes();
1650       nbOfCellsInCurType=(*iter).getLength();
1651       bool isDyn=cellMod.isDynamic();
1652       int *tmpConnPtr;
1653       for(int i=0;i<nbOfCellsInCurType;i++)
1654         {
1655           if(keepAll)
1656             {//duplication of next 3 lines needed.
1657               *connIdxPtr=connFillId;
1658               *connPtr++=type;
1659               if(renumber)
1660                 *renumW++=globalNum[i];
1661               if(!isDyn)
1662                 tmpConnPtr=std::transform(sourceConn,sourceConn+nbOfNodesIn1Cell,connPtr,std::bind2nd(std::minus<int>(),1));
1663               else
1664                 tmpConnPtr=std::transform(sourceConn,sourceConn+sourceIndex[i+1]-sourceIndex[i],connPtr,std::bind2nd(std::minus<int>(),1));
1665               connIdxPtr++;
1666               nbOfNodesIn1Cell=tmpConnPtr-connPtr;
1667               connFillId+=nbOfNodesIn1Cell+1;
1668               connPtr=tmpConnPtr;
1669             }
1670           else if(std::find(familiesToKeep.begin(),familiesToKeep.end(),(*iter).getFam()[i])!=familiesToKeep.end())
1671             {//duplication of next 3 lines needed.
1672               *connIdxPtr=connFillId;
1673               *connPtr++=type;
1674               if(renumber)
1675                 *renumW++=globalNum[i];
1676               if(!isDyn)
1677                 tmpConnPtr=std::transform(sourceConn,sourceConn+nbOfNodesIn1Cell,connPtr,std::bind2nd(std::minus<int>(),1));
1678               else//The duplication of code is motivated by the line underneath.
1679                 tmpConnPtr=std::transform((*iter).getArray()+sourceIndex[i]-1,(*iter).getArray()+sourceIndex[i+1]-1,connPtr,std::bind2nd(std::minus<int>(),1));
1680               connIdxPtr++;
1681               nbOfNodesIn1Cell=tmpConnPtr-connPtr;
1682               connFillId+=nbOfNodesIn1Cell+1;
1683               connPtr=tmpConnPtr;
1684             }
1685           sourceConn+=nbOfNodesIn1Cell;
1686         }
1687       *connIdxPtr=connFillId;
1688     }
1689 }
1690
1691 namespace MEDLoaderNS
1692 {
1693   template<class T>
1694   void releaseMEDFileCoreFrmt(typename std::list<T>& medConnFrmt)
1695   {
1696     for(typename std::list<T>::iterator iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++)
1697       (*iter).releaseArray();
1698     medConnFrmt.clear();
1699   }
1700 }
1701
1702 /*!
1703  * This method builds a sub set of connectivity for a given type 'type'. \b WARNING connV,connVIndex and familiesV must have same size !
1704  * @param connV input containing connectivity with MEDCoupling format.
1705  * @param connVIndex input containing connectivity index in MEDCoupling format.
1706  * @param familiesV input that may be equal to 0. This specifies an array specifying cell family foreach cell.
1707  * @param type input specifying which cell types will be extracted in conn4MEDFile. 
1708  * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called.
1709  * @param connIndex4MEDFile output containing index connectivity understandable by MEDFile; only used by polygons and polyhedrons (it is face nodal connec).
1710  * @param connIndexRk24MEDFile output containing index of rank 2 understandable by MEDFile; only used by polyhedrons.
1711  * @param fam4MEDFile output containing family number of cells whose type is 'type'. This output is updated only if 'families' is different than 0.
1712  * @return nb of elements extracted.
1713  */
1714 int MEDLoaderNS::buildMEDSubConnectivityOfOneTypeStaticTypes(const std::vector<const DataArrayInt *>& connV, const std::vector<const DataArrayInt *>& connVIndex, const std::vector<const DataArrayInt *>& familiesV,
1715                                                              INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber)
1716 {
1717   int ret=0;
1718   int nbOfMeshes=connV.size();
1719   int renumOffset=0;
1720   for(int i=0;i<nbOfMeshes;i++)
1721     {
1722       const DataArrayInt *conn=connV[i];
1723       const DataArrayInt *connIndex=connVIndex[i];
1724       const DataArrayInt *families=familiesV[i];
1725       int nbOfElem=connIndex->getNbOfElems()-1;
1726       const int *connPtr=conn->getConstPointer();
1727       const int *connIdxPtr=connIndex->getConstPointer();
1728       const int *famPtr=0;
1729       if(families)
1730         famPtr=families->getConstPointer();
1731       for(int ii=0;ii<nbOfElem;ii++)
1732         {
1733           int delta=connIdxPtr[1]-connIdxPtr[0];
1734           if(*connPtr==type)
1735             {
1736               conn4MEDFile.insert(conn4MEDFile.end(),connPtr+1,connPtr+delta);
1737               if(families)
1738                 fam4MEDFile.push_back(famPtr[ii]);
1739               renumber.push_back(ii+1+renumOffset);
1740               ret++;
1741             }
1742           connIdxPtr++;
1743           connPtr+=delta;
1744         }
1745       renumOffset+=nbOfElem;
1746     }
1747   std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1));
1748   return ret;
1749 }
1750
1751 int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyg(const std::vector<const DataArrayInt *>&connV, const std::vector<const DataArrayInt *>& connVIndex, const std::vector<const DataArrayInt *>& familiesV,
1752                                                         std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber)
1753 {
1754   int ret=0;
1755   int nbOfMeshes=connV.size();
1756   connIndex4MEDFile.push_back(1);
1757   int renumOffset=0;
1758   for(int i=0;i<nbOfMeshes;i++)
1759     {
1760       const DataArrayInt *conn=connV[i];
1761       const DataArrayInt *connIndex=connVIndex[i];
1762       const DataArrayInt *families=familiesV[i];
1763       int nbOfElem=connIndex->getNbOfElems()-1;
1764       const int *connPtr=conn->getConstPointer();
1765       const int *connIdxPtr=connIndex->getConstPointer();
1766       const int *famPtr=0;
1767       if(families)
1768         famPtr=families->getConstPointer();
1769       for(int ii=0;ii<nbOfElem;ii++)
1770         {
1771           int delta=connIdxPtr[1]-connIdxPtr[0];
1772           if(*connPtr==INTERP_KERNEL::NORM_POLYGON)
1773             {
1774               conn4MEDFile.insert(conn4MEDFile.end(),connPtr+1,connPtr+delta);
1775               connIndex4MEDFile.push_back(connIndex4MEDFile.back()+delta-1);
1776               if(families)
1777                 fam4MEDFile.push_back(famPtr[ii]);
1778               renumber.push_back(ii+1+renumOffset);
1779               ret++;
1780             }
1781           connIdxPtr++;
1782           connPtr+=delta;
1783         }
1784       renumOffset+=nbOfElem;
1785     }
1786   std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1));
1787   return ret;
1788 }
1789   
1790 int MEDLoaderNS::buildMEDSubConnectivityOfOneTypesPolyh(const std::vector<const DataArrayInt *>& connV, const std::vector<const DataArrayInt *>& connVIndex, const std::vector<const DataArrayInt *>& familiesV,
1791                                                         std::vector<int>& conn4MEDFile, std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile,
1792                                                         std::vector<int>& fam4MEDFile, std::vector<int>& renumber)
1793 {
1794   int ret=0;
1795   int nbOfMeshes=connV.size();
1796   connIndexRk24MEDFile.push_back(1);
1797   connIndex4MEDFile.push_back(1);
1798   int renumOffset=0;
1799   for(int i=0;i<nbOfMeshes;i++)
1800     {
1801       const DataArrayInt *conn=connV[i];
1802       const DataArrayInt *connIndex=connVIndex[i];
1803       const DataArrayInt *families=familiesV[i];
1804       int nbOfElem=connIndex->getNbOfElems()-1;
1805       const int *connPtr=conn->getConstPointer();
1806       const int *connIdxPtr=connIndex->getConstPointer();
1807       const int *famPtr=0;
1808       if(families)
1809         famPtr=families->getConstPointer();
1810       for(int ii=0;ii<nbOfElem;ii++)
1811         {
1812           int delta=connIdxPtr[1]-connIdxPtr[0];
1813           if(*connPtr==INTERP_KERNEL::NORM_POLYHED)
1814             {
1815               int nbOfFacesOfPolyh=std::count(connPtr+1,connPtr+delta,-1)+1;
1816               const int *work=connPtr+1;
1817               while(work!=connPtr+delta)
1818                 {
1819                   const int *end=std::find(work,connPtr+delta,-1);
1820                   conn4MEDFile.insert(conn4MEDFile.end(),work,end);
1821                   connIndex4MEDFile.push_back(connIndex4MEDFile.back()+std::distance(work,end));
1822                   if(end==connPtr+delta)
1823                     work=connPtr+delta;
1824                   else
1825                     work=end+1;
1826                 }
1827               connIndexRk24MEDFile.push_back(connIndexRk24MEDFile.back()+nbOfFacesOfPolyh);
1828               if(families)
1829                 fam4MEDFile.push_back(famPtr[ii]);
1830               renumber.push_back(ii+1+renumOffset);
1831               ret++;
1832             }
1833           connIdxPtr++;
1834           connPtr+=delta;
1835         }
1836       renumOffset+=nbOfElem;
1837     }
1838   std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1));
1839   return ret;
1840 }
1841   
1842 /*!
1843  * This method builds a sub set of connectivity for a given type 'type'.
1844  * @param conn input containing connectivity with MEDCoupling format.
1845  * @param connIndex input containing connectivity index in MEDCoupling format.
1846  * @param families input containing, if any, the family number of each cells
1847  * @param type input specifying which cell types will be extracted in conn4MEDFile. 
1848  * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called.
1849  * @param connIndex4MEDFile output containing index connectivity understandable by MEDFile; only used by polygons and polyhedrons (it is face nodal connec).
1850  * @param connIndexRk24MEDFile output containing index of rank 2 understandable by MEDFile; only used by polyhedrons.
1851  * @param fam4MEDFile output containing families id of cells whose type is 'type'.
1852  * @return nb of elements extracted.
1853  */
1854 int MEDLoaderNS::buildMEDSubConnectivityOfOneType(const std::vector<const DataArrayInt *>& conn, const std::vector<const DataArrayInt *>& connIndex, const std::vector<const DataArrayInt *>& families,
1855                                                   INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile,
1856                                                   std::vector<int>& connIndex4MEDFile, std::vector<int>& connIndexRk24MEDFile, std::vector<int>& fam4MEDFile, std::vector<int>& renumber)
1857 {
1858     
1859   const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::GetCellModel(type);
1860   if(!cellMod.isDynamic())
1861     return buildMEDSubConnectivityOfOneTypeStaticTypes(conn,connIndex,families,type,conn4MEDFile,fam4MEDFile,renumber);
1862   else
1863     {
1864       if(type==INTERP_KERNEL::NORM_POLYGON)
1865         return buildMEDSubConnectivityOfOneTypesPolyg(conn,connIndex,families,conn4MEDFile,connIndex4MEDFile,fam4MEDFile,renumber);
1866       else
1867         return buildMEDSubConnectivityOfOneTypesPolyh(conn,connIndex,families,conn4MEDFile,connIndex4MEDFile,connIndexRk24MEDFile,fam4MEDFile,renumber);
1868     }
1869 }
1870   
1871 /*!
1872  * @param ids is a in vector containing families ids whose cells have to be kept. If empty all cells are kept.
1873  * @param typesToKeep is a in vector that indicates which types to keep after dimension filtering.
1874  * @param meshDimExtract out parameter that gives the mesh dimension.
1875  * @param cellRenum out parameter that specifies the renumbering (if !=0) of cells in file.
1876  */
1877 MEDCouplingUMesh *MEDLoaderNS::readUMeshFromFileLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<int>& ids,
1878                                                      const std::vector<INTERP_KERNEL::NormalizedCellType>& typesToKeep, unsigned& meshDimExtract, int *&cellRenum) throw(INTERP_KERNEL::Exception)
1879 {
1880   if(meshDimRelToMax>0)
1881     throw INTERP_KERNEL::Exception("meshDimRelToMax must be <=0 !");
1882   //Extraction data from MED file.
1883   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1884   std::string trueMeshName;
1885   med_int mid=getIdFromMeshName(fid,meshName,trueMeshName);
1886   DataArrayDouble *coords=0;
1887   std::list<MEDLoader::MEDConnOfOneElemType> conn;
1888   std::string descr;
1889   readUMeshDataInMedFile(fid,mid,coords,conn,descr);
1890   meshDimExtract=MEDLoaderNS::calculateHighestMeshDim<MEDLoader::MEDConnOfOneElemType>(conn);
1891   meshDimExtract=meshDimExtract+meshDimRelToMax;
1892   MEDLoaderNS::keepSpecifiedMeshDim<MEDLoader::MEDConnOfOneElemType>(conn,meshDimExtract);
1893   MEDLoaderNS::keepTypes<MEDLoader::MEDConnOfOneElemType>(conn,typesToKeep);
1894   //Put data in returned data structure.
1895   MEDCouplingUMesh *ret=MEDCouplingUMesh::New();
1896   ret->setName(trueMeshName.c_str());
1897   ret->setDescription(descr.c_str());
1898   ret->setMeshDimension(meshDimExtract);
1899   //
1900   ret->setCoords(coords);
1901   coords->decrRef();
1902   //
1903   DataArrayInt *connArr,*connIndexArr;
1904   tradMEDFileCoreFrmt2MEDCouplingUMesh(conn,ids,connArr,connIndexArr,cellRenum);
1905   ret->setConnectivity(connArr,connIndexArr);
1906   //clean-up
1907   if(connArr)
1908     connArr->decrRef();
1909   if(connIndexArr)
1910     connIndexArr->decrRef();
1911   releaseMEDFileCoreFrmt<MEDLoader::MEDConnOfOneElemType>(conn);
1912   return ret;
1913 }
1914
1915 ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev2(const char *fileName, ParaMEDMEM::TypeOfField typeOfOutField, unsigned meshDim, const int *cellRenum, const ParaMEDMEM::MEDCouplingUMesh *mesh,
1916                                                                      const std::vector<std::string>& infos, const char *fieldName, int iteration, int order, double time,
1917                                                                      std::list<MEDLoader::MEDFieldDoublePerCellType>& fieldPerCellType) throw(INTERP_KERNEL::Exception)
1918 {
1919   if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE)
1920     MEDLoaderNS::keepSpecifiedMeshDim<MEDLoader::MEDFieldDoublePerCellType>(fieldPerCellType,meshDim);
1921   if(fieldPerCellType.empty())
1922     {
1923       std::ostringstream oss; oss << "Error on reading file \"" << fileName << "\" meshName=\"" << mesh->getName();
1924       oss << std::endl << "FieldName=\"" << fieldName << "\" (iteration=" << iteration << ",order=" << order << ")" << std::endl;
1925       if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE)
1926         oss << "Request for cell field, maybe it is an ON_NODES field ?";
1927       else
1928         oss << "Request for a node field, maybe it is an ON_CELLS field ?";
1929       throw INTERP_KERNEL::Exception(oss.str().c_str());
1930     }
1931   //for profiles
1932   MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingUMesh> newMesh;
1933   std::string mName(mesh->getName());
1934   if(typeOfOutField==ON_NODES)
1935     {
1936       for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
1937         {
1938           const std::vector<int>& cellIds=(*iter).getCellIdPerType();
1939           if(!cellIds.empty())
1940             {
1941               std::vector<int> ci(cellIds.size());
1942               std::transform(cellIds.begin(),cellIds.end(),ci.begin(),std::bind2nd(std::plus<int>(),-1));
1943               MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingUMesh> mesh2;
1944               MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da,da2;
1945               if((const ParaMEDMEM::MEDCouplingUMesh *)newMesh)
1946                 {
1947                   if((int)ci.size()!=newMesh->getNumberOfNodes())
1948                     {
1949                       da=newMesh->getCellIdsFullyIncludedInNodeIds(&ci[0],&ci[ci.size()]);
1950                       DataArrayInt *tmpp=0;
1951                       mesh2=dynamic_cast<MEDCouplingUMesh *>(newMesh->buildPartAndReduceNodes(da->begin(),da->end(),tmpp)); da2=tmpp;
1952                     }
1953                 }
1954               else
1955                 {
1956                   if((int)ci.size()!=mesh->getNumberOfNodes())
1957                     {
1958                       da=mesh->getCellIdsFullyIncludedInNodeIds(&ci[0],&ci[ci.size()]);
1959                       DataArrayInt *tmpp=0;
1960                       mesh2=dynamic_cast<MEDCouplingUMesh *>(mesh->buildPartAndReduceNodes(da->begin(),da->end(),tmpp)); da2=tmpp;
1961                       //
1962                       int nnodes=mesh2->getNumberOfNodes();
1963                       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da3=DataArrayInt::New();
1964                       const int *da2Ptr=da2->getConstPointer();
1965                       da3->alloc(nnodes,1);
1966                       int *da3Ptr=da3->getPointer();
1967                       for(int i=0;i<(int)ci.size();i++)
1968                         {
1969                           int val=da2Ptr[ci[i]];
1970                           if(val!=-1)
1971                             da3Ptr[val]=i;
1972                         }
1973                       mesh2->renumberNodes(da3->getConstPointer(),nnodes);
1974                     }
1975                   else
1976                     {
1977                       mesh2=mesh->clone(true);
1978                       da=DataArrayInt::New();
1979                       da->alloc((int)ci.size(),1);
1980                       std::copy(ci.begin(),ci.end(),da->getPointer());
1981                       da2=da->invertArrayO2N2N2O(ci.size());
1982                       mesh2->renumberNodes(da2->getConstPointer(),(int)ci.size());
1983                     }
1984                 }
1985               newMesh=mesh2;
1986             }
1987         }
1988     }
1989   else
1990     {
1991       newMesh=const_cast<ParaMEDMEM::MEDCouplingUMesh *>(static_cast<const ParaMEDMEM::MEDCouplingUMesh *>(mesh)); mesh->incrRef();
1992       std::vector<INTERP_KERNEL::NormalizedCellType> types;
1993       for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
1994         if(std::find(types.begin(),types.end(),(*iter).getType())==types.end())
1995           types.push_back((*iter).getType());
1996       for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it=types.begin();it!=types.end();it++)
1997         {
1998           std::vector<int> cids;
1999           for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
2000             {
2001               if((*iter).getType()==*it)
2002                 {
2003                   const std::vector<int>& cellIds=(*iter).getCellIdPerType();
2004                   if(!cellIds.empty())
2005                     std::transform(cellIds.begin(),cellIds.end(),std::back_insert_iterator< std::vector<int> >(cids),std::bind2nd(std::plus<int>(),-1));
2006                 }
2007             }
2008           if(!cids.empty())
2009             newMesh=newMesh->keepSpecifiedCells(*it,&cids[0],&cids[0]+cids.size());
2010         }
2011     }
2012   //
2013   ParaMEDMEM::MEDCouplingFieldDouble *ret=ParaMEDMEM::MEDCouplingFieldDouble::New(typeOfOutField,ONE_TIME);
2014   ret->setName(fieldName);
2015   ret->setTime(time,iteration,order);
2016   ParaMEDMEM::DataArrayDouble *arr=buildArrayFromRawData(fieldPerCellType,infos);
2017   ret->setArray(arr);
2018   arr->decrRef();
2019   if((const ParaMEDMEM::MEDCouplingUMesh *)newMesh)
2020     {
2021       newMesh->setName(mName.c_str());//retrieving mesh name to avoid renaming due to mesh restriction in case of profile.
2022       ret->setMesh(newMesh);
2023     }
2024   else
2025     ret->setMesh(mesh);
2026   if(typeOfOutField==ON_GAUSS_PT)
2027     fillGaussDataOnField(fileName,fieldPerCellType,ret);
2028   if(cellRenum)
2029     ret->renumberCellsWithoutMesh(cellRenum,true);
2030   return ret;
2031 }
2032
2033 ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order,
2034                                                                      ParaMEDMEM::TypeOfField typeOfOutField) throw(INTERP_KERNEL::Exception)
2035 {
2036   std::list<MEDLoader::MEDFieldDoublePerCellType> fieldPerCellType;
2037   double time;
2038   std::vector<std::string> infos;
2039   readFieldDoubleDataInMedFile(fileName,meshName,fieldName,iteration,order,typeOfOutField,fieldPerCellType,time,infos);
2040   std::vector<int> familiesToKeep;
2041   std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
2042   if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE)
2043     for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
2044       typesToKeep.push_back((*iter).getType());
2045   unsigned meshDim;
2046   int *cellRenum;
2047   if(fieldPerCellType.empty())
2048     {
2049       std::ostringstream oss; oss << "Error on reading file \"" << fileName << "\" meshName=\"" << meshName << "\" meshDimRelToMax=" << meshDimRelToMax;
2050       oss << std::endl << "FieldName=\"" << fieldName << "\" (iteration=" << iteration << ",order=" << order << ")" << std::endl;
2051       if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE)
2052         oss << "Request for cell field, maybe it is a node instead or by changing meshDimRelToMax ?";
2053       else
2054         oss << "Request for a node field, maybe it is a cell field instead ?";
2055       throw INTERP_KERNEL::Exception(oss.str().c_str());
2056       }
2057   MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingUMesh> mesh=readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum);
2058   ParaMEDMEM::MEDCouplingFieldDouble *ret=readFieldDoubleLev2(fileName,typeOfOutField,meshDim,cellRenum,mesh,infos,fieldName,iteration,order,time,fieldPerCellType);
2059   if(cellRenum)
2060     mesh->renumberCells(cellRenum,true);
2061   //clean-up
2062   delete [] cellRenum;
2063   releaseMEDFileCoreFrmt<MEDLoader::MEDFieldDoublePerCellType>(fieldPerCellType);
2064   return ret;
2065 }
2066
2067 /// @endcond
2068
2069 MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
2070 {
2071   CheckFileForRead(fileName);
2072   std::vector<int> familiesToKeep;
2073   std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
2074   unsigned meshDim;
2075   int *cellRenum;
2076   ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum);
2077   if(cellRenum)
2078     {
2079       ret->renumberCells(cellRenum,true);
2080       delete [] cellRenum;
2081     }
2082   return ret;
2083 }
2084
2085 ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
2086 {
2087   CheckFileForRead(fileName);
2088   std::vector<int> familiesToKeep;
2089   std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
2090   unsigned meshDim;
2091   int *cellRenum;
2092   ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,0,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum);
2093   if(cellRenum)
2094     {
2095       ret->renumberCells(cellRenum,true);
2096       delete [] cellRenum;
2097     }
2098   return ret;
2099 }
2100
2101 int MEDLoader::ReadUMeshDimFromFile(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception)
2102 {
2103   CheckFileForRead(fileName);
2104   std::vector<int> poss;
2105   return MEDLoaderNS::readUMeshDimFromFile(fileName,meshName,poss);
2106 }
2107
2108 ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& fams) throw(INTERP_KERNEL::Exception)
2109 {
2110   CheckFileForRead(fileName);
2111   std::vector<int> familiesToKeep=MEDLoaderNS::getIdsFromFamilies(fileName,meshName,fams);
2112   std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
2113   unsigned meshDim;
2114   int *cellRenum;
2115   ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum);
2116   if(fams.size()==1)
2117     ret->setName(fams.back().c_str());
2118   if(cellRenum)
2119     {
2120       ret->renumberCells(cellRenum,true);
2121       delete [] cellRenum;
2122     }
2123   return ret;
2124 }
2125
2126 ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector<std::string>& grps) throw(INTERP_KERNEL::Exception)
2127 {
2128   CheckFileForRead(fileName);
2129   std::vector<int> familiesToKeep=MEDLoaderNS::getIdsFromGroups(fileName,meshName,grps);
2130   std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
2131   unsigned meshDim;
2132   int *cellRenum;
2133   ParaMEDMEM::MEDCouplingUMesh *ret=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum);
2134   if(grps.size()==1)
2135     ret->setName(grps.back().c_str());
2136   if(cellRenum)
2137     {
2138       ret->renumberCells(cellRenum,true);
2139       delete [] cellRenum;
2140     }
2141   return ret;
2142 }
2143
2144 ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadField(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
2145 {
2146   CheckFileForRead(fileName);
2147   switch(type)
2148     {
2149     case ON_CELLS:
2150       return ReadFieldCell(fileName,meshName,meshDimRelToMax,fieldName,iteration,order);
2151     case ON_NODES:
2152       return ReadFieldNode(fileName,meshName,meshDimRelToMax,fieldName,iteration,order);
2153     case ON_GAUSS_PT:
2154       return ReadFieldGauss(fileName,meshName,meshDimRelToMax,fieldName,iteration,order);
2155     case ON_GAUSS_NE:
2156       return ReadFieldGaussNE(fileName,meshName,meshDimRelToMax,fieldName,iteration,order);
2157     default:
2158       throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES, ON_CELLS, ON_GAUSS_PT or ON_GAUSS_NE !");
2159     } 
2160 }
2161
2162 std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
2163                                                                                   const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception)
2164 {
2165   if(its.empty())
2166     return std::vector<ParaMEDMEM::MEDCouplingFieldDouble *>();
2167   CheckFileForRead(fileName);
2168   std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ret(its.size());
2169   if(its.empty())
2170     return ret;
2171   //Retrieving mesh of rank 0 and field on rank 0 too.
2172   std::list<MEDLoader::MEDFieldDoublePerCellType> fieldPerCellType;
2173   double time;
2174   std::vector<std::string> infos;
2175   MEDLoaderNS::readFieldDoubleDataInMedFile(fileName,meshName,fieldName,its[0].first,its[0].second,type,fieldPerCellType,time,infos);
2176   std::vector<int> familiesToKeep;
2177   std::vector<INTERP_KERNEL::NormalizedCellType> typesToKeep;
2178   if(type==ON_CELLS || type==ON_GAUSS_PT || type==ON_GAUSS_NE)
2179     for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
2180       typesToKeep.push_back((*iter).getType());
2181   unsigned meshDim;
2182   int *cellRenum;
2183   MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingUMesh> m1=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum);
2184   ret[0]=MEDLoaderNS::readFieldDoubleLev2(fileName,type,meshDim,cellRenum,m1,infos,fieldName,its[0].first,its[0].second,time,fieldPerCellType);
2185   if(cellRenum)
2186     m1->renumberCells(cellRenum,true);
2187   MEDLoaderNS::releaseMEDFileCoreFrmt<MEDLoader::MEDFieldDoublePerCellType>(fieldPerCellType);
2188   //
2189   for(int itId=1;itId<(int)its.size();itId++)
2190     {
2191       std::list<MEDLoader::MEDFieldDoublePerCellType> fieldPerCellType2;
2192       double timmee;
2193       std::vector<std::string> infoss;
2194       MEDLoaderNS::readFieldDoubleDataInMedFile(fileName,meshName,fieldName,its[itId].first,its[itId].second,type,fieldPerCellType2,timmee,infoss);
2195       ret[itId]=MEDLoaderNS::readFieldDoubleLev2(fileName,type,meshDim,cellRenum,m1,infoss,fieldName,its[itId].first,its[itId].second,timmee,fieldPerCellType2);
2196       //clean-up
2197       MEDLoaderNS::releaseMEDFileCoreFrmt<MEDLoader::MEDFieldDoublePerCellType>(fieldPerCellType2);
2198     }
2199   delete [] cellRenum;
2200   return ret;
2201 }
2202
2203 std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsCellOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
2204                                                                                             const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception)
2205 {
2206   return ReadFieldsOnSameMesh(ON_CELLS,fileName,meshName,meshDimRelToMax,fieldName,its);
2207 }
2208
2209 std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsNodeOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
2210                                                                                       const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception)
2211 {
2212   return ReadFieldsOnSameMesh(ON_NODES,fileName,meshName,meshDimRelToMax,fieldName,its);
2213 }
2214
2215 std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsGaussOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
2216                                                                                        const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception)
2217 {
2218   return ReadFieldsOnSameMesh(ON_GAUSS_PT,fileName,meshName,meshDimRelToMax,fieldName,its);
2219 }
2220
2221 std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsGaussNEOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName,
2222                                                                                          const std::vector<std::pair<int,int> >& its) throw(INTERP_KERNEL::Exception)
2223 {
2224   return ReadFieldsOnSameMesh(ON_GAUSS_NE,fileName,meshName,meshDimRelToMax,fieldName,its);
2225 }
2226
2227 ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
2228 {
2229   return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_CELLS);
2230 }
2231
2232 ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
2233 {
2234   return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_NODES);
2235 }
2236
2237 ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGauss(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
2238 {
2239   return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_GAUSS_PT);
2240 }
2241
2242 ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGaussNE(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
2243 {
2244   return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_GAUSS_NE);
2245 }
2246
2247 /*!
2248  * @param families input parameter that specifies the field on int on each cells of 'mesh'.
2249  * @param isRenumbering output parameter that specifies if a renumbering of mesh has been needed.
2250  */
2251 void MEDLoaderNS::writeUMeshesDirectly(const char *fileName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& mesh, const std::vector<const DataArrayInt *>& families, bool forceFromScratch, bool &isRenumbering)
2252 {
2253   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,forceFromScratch?MED_ACC_CREAT:MED_ACC_RDWR);
2254   std::string meshName(mesh[0]->getName());
2255   if(meshName=="")
2256     throw INTERP_KERNEL::Exception("MEDCouplingMesh must have a not null name !");
2257   isRenumbering=false;
2258   bool isFamilies=true;
2259   std::vector<const DataArrayInt *> conn;
2260   std::vector<const DataArrayInt *> connIndex;
2261   std::set<INTERP_KERNEL::NormalizedCellType> allTypes;
2262   for(std::vector<const ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=mesh.begin();iter!=mesh.end();iter++)
2263     {
2264       isRenumbering|=!(*iter)->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO);
2265       isFamilies&=(families[std::distance(mesh.begin(),iter)]!=0);
2266       conn.push_back((*iter)->getNodalConnectivity());
2267       connIndex.push_back((*iter)->getNodalConnectivityIndex());
2268       const std::set<INTERP_KERNEL::NormalizedCellType>& curTypes=(*iter)->getAllTypes();
2269       allTypes.insert(curTypes.begin(),curTypes.end());
2270     }
2271   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2272   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2273   MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_NAME_SIZE,maa,MEDLoader::_TOO_LONG_STR);
2274   MEDLoaderBase::safeStrCpy(mesh[0]->getDescription(),MED_COMMENT_SIZE,desc,MEDLoader::_TOO_LONG_STR);
2275   const int spaceDim=mesh[0]->getSpaceDimension();
2276   const int meshDim=mesh[0]->getMeshDimension();
2277   const DataArrayDouble *arr=mesh[0]->getCoords();
2278   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2279   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2280   for(int i=0;i<spaceDim;i++)
2281     {
2282       std::string info=arr->getInfoOnComponent(i);
2283       std::string c,u;
2284       MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2285       MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
2286       MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
2287     }
2288   MEDmeshCr(fid,maa,spaceDim,meshDim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2289   for(std::vector<const ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=mesh.begin();iter!=mesh.end();iter++)
2290     {
2291       for(int i=0;i<MED_N_CELL_FIXED_GEO;i++)
2292         {
2293           med_geometry_type curMedType=typmai[i];
2294           INTERP_KERNEL::NormalizedCellType curType=typmai2[i];
2295           if(allTypes.find(curType)!=allTypes.end())
2296             {
2297               std::vector<int> medConn;
2298               std::vector<int> medConnIndex;
2299               std::vector<int> medConnIndex2;
2300               std::vector<int> fam;
2301               std::vector<int> renumber;
2302               int nbOfElt=MEDLoaderNS::buildMEDSubConnectivityOfOneType(conn,connIndex,families,curType,medConn,medConnIndex,medConnIndex2,fam,renumber);
2303               if(curMedType!=MED_POLYGON && curMedType!=MED_POLYHEDRON)
2304                 MEDmeshElementConnectivityWr(fid,maa,-1,-1,0.,MED_CELL,curMedType,MED_NODAL,MED_FULL_INTERLACE,nbOfElt,&medConn[0]);
2305               else
2306                 {
2307                   if(curMedType==MED_POLYGON)
2308                     MEDmeshPolygonWr(fid,maa,-1,-1,0.,MED_CELL,MED_NODAL,medConnIndex.size(),&medConnIndex[0],&medConn[0]);
2309                   if(curMedType==MED_POLYHEDRON)
2310                     {
2311                       MEDmeshPolyhedronWr(fid,maa,-1,-1,0.,MED_CELL,MED_NODAL,medConnIndex2.size(),&medConnIndex2[0],medConnIndex.size(),&medConnIndex[0],
2312                                          &medConn[0]);
2313                     }
2314                 }
2315               if(isFamilies)
2316                 MEDmeshEntityFamilyNumberWr(fid,maa,-1,-1,MED_CELL,curMedType,nbOfElt,&fam[0]);
2317               if(isRenumbering)
2318                 MEDmeshEntityNumberWr(fid,maa,-1,-1,MED_CELL,curMedType,nbOfElt,&renumber[0]);
2319             }
2320         }
2321     }
2322   char familyName[MED_NAME_SIZE+1];
2323   std::fill(familyName,familyName+MED_NAME_SIZE+1,'\0');
2324   const char DftFamilyName[]="DftFamily";
2325   std::copy(DftFamilyName,DftFamilyName+sizeof(DftFamilyName),familyName);
2326   MEDfamilyCr(fid,maa,familyName,0,0,0);
2327   
2328   MEDmeshNodeCoordinateWr(fid,maa,-1,-1,0.,MED_FULL_INTERLACE,mesh[0]->getNumberOfNodes(),arr->getConstPointer());
2329 }
2330
2331 /*!
2332  * In this method meshes are assumed to shared the same coords.
2333  * This method makes the assumption that 'meshes' is not empty, no check on that is done (responsability of the caller)
2334  */
2335 void MEDLoaderNS::writeUMeshesPartitionDirectly(const char *fileName, const char *meshName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool forceFromScratch)
2336 {
2337   std::string meshNameCpp(meshName);
2338   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2339   MEDLoaderBase::safeStrCpy(meshName,MED_NAME_SIZE,maa,MEDLoader::_TOO_LONG_STR);
2340   if(meshNameCpp=="")
2341     throw INTERP_KERNEL::Exception("writeUMeshesPartitionDirectly : Invalid meshName : Must be different from \"\" !");
2342   std::vector< DataArrayInt * > corr;
2343   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=ParaMEDMEM::MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr);
2344   m->setName(meshName);
2345   std::vector< std::vector<int> > fidsOfGroups;
2346   std::vector< const DataArrayInt * > corr2(corr.begin(),corr.end());
2347   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2=DataArrayInt::MakePartition(corr2,m->getNumberOfCells(),fidsOfGroups);
2348   for(std::vector< DataArrayInt * >::iterator it=corr.begin();it!=corr.end();it++)
2349     (*it)->decrRef();
2350   bool isRenumbering;
2351   std::vector<const MEDCouplingUMesh *> mv(1); mv[0]=m;
2352   std::vector<const DataArrayInt *> famv(1); famv[0]=arr2;
2353   writeUMeshesDirectly(fileName,mv,famv,forceFromScratch,isRenumbering);
2354   // families creation
2355   std::set<int> familyIds;
2356   for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGroups.begin();it1!=fidsOfGroups.end();it1++)
2357     for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2358       familyIds.insert(*it2);
2359   std::vector< std::vector<int> > gidsOfFamilies(familyIds.size());
2360   int fid=0;
2361   for(std::set<int>::const_iterator it=familyIds.begin();it!=familyIds.end();it++,fid++)
2362     {
2363       int gid=0;
2364       for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGroups.begin();it1!=fidsOfGroups.end();it1++,gid++)
2365         for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2366           if(*it2==*it)
2367             gidsOfFamilies[fid].push_back(gid);
2368     }
2369   fid=0;
2370   MEDFileUtilities::AutoFid fid2=MEDfileOpen(fileName,MED_ACC_RDWR);
2371   for(std::set<int>::const_iterator it=familyIds.begin();it!=familyIds.end();it++,fid++)
2372     {
2373       int ngro=gidsOfFamilies[fid].size();
2374       INTERP_KERNEL::AutoPtr<char> groName=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE*ngro);
2375       for(int i=0;i<ngro;i++)
2376         MEDLoaderBase::safeStrCpy2(meshes[gidsOfFamilies[fid][i]]->getName(),MED_LNAME_SIZE-1,groName+i*MED_LNAME_SIZE,MEDLoader::_TOO_LONG_STR);//MED_LNAME_SIZE-1 to avoid to write '\0' on next compo
2377       std::ostringstream oss; oss << "Family_" << *it;
2378       INTERP_KERNEL::AutoPtr<char> famName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2379       MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,famName,MEDLoader::_TOO_LONG_STR);
2380       MEDfamilyCr(fid2,maa,famName,*it,ngro,groName);
2381     }
2382 }
2383
2384 /*!
2385  * This method makes the assumption that f->getMesh() nodes are fully included in already written mesh in 'fileName'.
2386  * @param thisMeshNodeIds points to a tab of size f->getMesh()->getNumberOfNodes() that says for a node i in f->getMesh() that its id is thisMeshNodeIds[i] is already written mesh.
2387  */
2388 void MEDLoaderNS::appendNodeProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshNodeIds)
2389 {
2390   med_int numdt,numo;
2391   med_float dt;
2392   INTERP_KERNEL::AutoPtr<char> nommaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2393   MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,nommaa,MEDLoader::_TOO_LONG_STR);
2394   MEDFileUtilities::AutoFid fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt);
2395   int nbOfNodes=f->getMesh()->getNumberOfNodes();
2396   const double *pt=f->getArray()->getConstPointer();
2397   INTERP_KERNEL::AutoPtr<int> profile=new int[nbOfNodes];
2398   std::ostringstream oss; oss << "Pfln" << f->getName();
2399   INTERP_KERNEL::AutoPtr<char> profileName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2400   MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR);
2401   std::transform(thisMeshNodeIds,thisMeshNodeIds+nbOfNodes,(int *)profile,std::bind2nd(std::plus<int>(),1));
2402   MEDprofileWr(fid,profileName,nbOfNodes,profile);
2403   MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_NODE,MED_NONE,MED_COMPACT_PFLMODE,profileName,MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfNodes,(const unsigned char*)pt);
2404 }
2405
2406 /*!
2407  * This method makes the assumption that f->getMesh() cells are fully included in already written mesh in 'fileName'.
2408  * @param thisMeshCellIdsPerType points to a tab of size f->getMesh()->getNumberOfCells() that says for a cell i in f->getMesh() that its id is thisMeshCellIds[i] of corresponding type is already written mesh.
2409  */
2410 void MEDLoaderNS::appendCellProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIdsPerType)
2411 {
2412   med_int numdt,numo;
2413   med_float dt;
2414   int nbComp=f->getNumberOfComponents();
2415   MEDFileUtilities::AutoFid fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt);
2416   std::list<MEDLoader::MEDFieldDoublePerCellType> split;
2417   prepareCellFieldDoubleForWriting(f,thisMeshCellIdsPerType,split);
2418   const double *pt=f->getArray()->getConstPointer();
2419   int number=0;
2420   for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=split.begin();iter!=split.end();iter++)
2421     {
2422       INTERP_KERNEL::AutoPtr<char> nommaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2423       MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,nommaa,MEDLoader::_TOO_LONG_STR);
2424       INTERP_KERNEL::AutoPtr<char> profileName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2425       std::ostringstream oss; oss << "Pfl" << f->getName() << "_" << number++;
2426       MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR);
2427       const std::vector<int>& ids=(*iter).getCellIdPerType();
2428       INTERP_KERNEL::AutoPtr<int> profile=new int [ids.size()];
2429       std::transform(ids.begin(),ids.end(),(int *)profile,std::bind2nd(std::plus<int>(),1));
2430       MEDprofileWr(fid,profileName,ids.size(),profile);
2431       MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE,profileName,
2432                                  MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,(*iter).getNbOfTuple(),(const unsigned char*)pt);
2433       pt+=(*iter).getNbOfTuple()*nbComp;
2434     }
2435 }
2436
2437 void MEDLoaderNS::appendNodeElementProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIdsPerType)
2438 {
2439   med_int numdt,numo;
2440   med_float dt;
2441   int nbComp=f->getNumberOfComponents();
2442   MEDFileUtilities::AutoFid fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt);
2443   std::list<MEDLoader::MEDFieldDoublePerCellType> split;
2444   prepareCellFieldDoubleForWriting(f,thisMeshCellIdsPerType,split);
2445   const double *pt=f->getArray()->getConstPointer();
2446   int number=0;
2447   for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=split.begin();iter!=split.end();iter++)
2448     {
2449       INTERP_KERNEL::AutoPtr<char> nommaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2450       MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,nommaa,MEDLoader::_TOO_LONG_STR);
2451       INTERP_KERNEL::AutoPtr<char> profileName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2452       std::ostringstream oss; oss << "Pfl" << f->getName() << "_" << number++;
2453       MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR);
2454       const std::vector<int>& ids=(*iter).getCellIdPerType();
2455       INTERP_KERNEL::AutoPtr<int> profile=new int [ids.size()];
2456       std::transform(ids.begin(),ids.end(),(int *)profile,std::bind2nd(std::plus<int>(),1));
2457       MEDprofileWr(fid,profileName,ids.size(),profile);
2458       int nbPtPerCell=(int)INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getNumberOfNodes();
2459       int nbOfEntity=f->getMesh()->getNumberOfCellsWithType((*iter).getType());
2460       int nbOfValues=nbPtPerCell*nbOfEntity;
2461       MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_NODE_ELEMENT,typmai3[(int)(*iter).getType()],
2462                                  MED_COMPACT_PFLMODE,profileName,
2463                                  MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,
2464                                  nbOfEntity,(const unsigned char*)pt);
2465       pt+=nbOfValues*nbComp;
2466     }
2467 }
2468
2469 /*!
2470  * This method performs the classical job for fields before any values setting.
2471  */
2472 med_idt MEDLoaderNS::appendFieldSimpleAtt(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, med_int& numdt, med_int& numo, med_float& dt)
2473 {
2474   std::string fieldName(f->getName());
2475   if(fieldName.empty())
2476     throw INTERP_KERNEL::Exception("MEDLoaderNS::appendFieldSimpleAtt : Trying to store a field with no name ! MED file format requires a NON EMPTY field name !");
2477   med_idt fid=MEDfileOpen(fileName,MED_ACC_RDWR);
2478   int nbComp=f->getNumberOfComponents();
2479   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE);
2480   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE);
2481   for(int i=0;i<nbComp;i++)
2482     {
2483       std::string info=f->getArray()->getInfoOnComponent(i);
2484       std::string c,u;
2485       MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2486       MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,MEDLoader::_TOO_LONG_STR);
2487       MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,MEDLoader::_TOO_LONG_STR);
2488     }
2489   INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE);
2490   INTERP_KERNEL::AutoPtr<char> maaname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2491   INTERP_KERNEL::AutoPtr<char> fname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2492   MEDLoaderBase::safeStrCpy(f->getName(),MED_NAME_SIZE,fname,MEDLoader::_TOO_LONG_STR);
2493   MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,maaname,MEDLoader::_TOO_LONG_STR);
2494   MEDLoaderBase::safeStrCpy(f->getTimeUnit(),MED_SNAME_SIZE,dt_unit,MEDLoader::_TOO_LONG_STR);
2495   MEDfieldCr(fid,fname,MED_FLOAT64,nbComp,comp,unit,dt_unit,maaname);
2496   ParaMEDMEM::TypeOfTimeDiscretization td=f->getTimeDiscretization();
2497   if(td==ParaMEDMEM::NO_TIME)
2498     {
2499       numdt=MED_NO_DT; numo=MED_NO_IT; dt=0.0;
2500     }
2501   else if(td==ParaMEDMEM::ONE_TIME)
2502     {
2503       int tmp1,tmp2;
2504       double tmp0=f->getTime(tmp1,tmp2);
2505       numdt=(med_int)tmp1; numo=(med_int)tmp2;
2506       dt=(med_float)tmp0;
2507     }
2508   return fid;
2509 }
2510
2511 void MEDLoaderNS::appendFieldDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f2)
2512 {
2513   med_int numdt,numo;
2514   med_float dt;
2515   //renumbering
2516   const ParaMEDMEM::MEDCouplingFieldDouble *f=f2;
2517   const MEDCouplingMesh *mesh=f->getMesh();
2518   const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(mesh);
2519   if(!meshC)
2520     throw INTERP_KERNEL::Exception("Not implemented yet for not unstructured mesh !");
2521   bool renum=!meshC->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO);
2522   if(renum)
2523     {
2524       ParaMEDMEM::MEDCouplingFieldDouble *f3=f2->clone(true);
2525       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=meshC->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO);
2526       f3->renumberCells(da->getConstPointer(),false);
2527       f=f3;
2528     }
2529   //end renumbering
2530   int nbComp=f->getNumberOfComponents();
2531   MEDFileUtilities::AutoFid fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt);
2532   const double *pt=f->getArray()->getConstPointer();
2533   INTERP_KERNEL::AutoPtr<char> nommaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2534   MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,nommaa,MEDLoader::_TOO_LONG_STR);
2535   switch(f->getTypeOfField())
2536     {
2537     case ParaMEDMEM::ON_CELLS:
2538       {
2539         std::list<MEDLoader::MEDFieldDoublePerCellType> split;
2540         prepareCellFieldDoubleForWriting(f,0,split);
2541         for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=split.begin();iter!=split.end();iter++)
2542           {
2543             MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE,
2544                                        MED_ALLENTITIES_PROFILE,MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,(*iter).getNbOfTuple(),(const unsigned char*)pt);
2545             pt+=(*iter).getNbOfTuple()*nbComp;
2546           }
2547         break;
2548       }
2549     case ParaMEDMEM::ON_NODES:
2550       {
2551         int nbOfTuples=f->getArray()->getNumberOfTuples();
2552         MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_NODE,MED_NONE,MED_COMPACT_PFLMODE,
2553                                    MED_ALLENTITIES_PROFILE,MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfTuples,(const unsigned char*)pt);
2554         break;
2555       }
2556     case ParaMEDMEM::ON_GAUSS_PT:
2557       {
2558         INTERP_KERNEL::AutoPtr<char> profileName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2559         std::list<MEDLoader::MEDFieldDoublePerCellType> split;
2560         prepareCellFieldDoubleForWriting(f,0,split);
2561         int idGp=0,offset=0,offset2=0;
2562         const double *pt2=0;
2563         INTERP_KERNEL::NormalizedCellType prevType=INTERP_KERNEL::NORM_ERROR;
2564         for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=split.begin();iter!=split.end();iter++)
2565           {
2566             if((*iter).getType()!=prevType)
2567               {
2568                 offset=offset2;
2569                 prevType=(*iter).getType();
2570               }
2571             INTERP_KERNEL::AutoPtr<char> nomGauss=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2572             std::ostringstream oss; oss << "GP_" << f->getName() << idGp++;
2573             MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,nomGauss,MEDLoader::_TOO_LONG_STR);
2574             std::ostringstream ossPfl;
2575             int id=-1,nbOfEntity=-1;
2576             MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arrTmp;
2577             if((*iter).getCellIdPerType().empty())
2578               {
2579                 id=f->getGaussLocalizationIdOfOneType((*iter).getType());
2580                 nbOfEntity=f->getMesh()->getNumberOfCellsWithType((*iter).getType());
2581               }
2582             else
2583               {
2584                 id=f->getGaussLocalizationIdOfOneCell((*iter).getCellIdPerType()[0]+offset);
2585                 nbOfEntity=(int)(*iter).getCellIdPerType().size();
2586                 ossPfl << "Pfl" << f->getName() << "_" << id;
2587                 MEDLoaderBase::safeStrCpy(ossPfl.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR);
2588                 INTERP_KERNEL::AutoPtr<int> profile=new int[(*iter).getCellIdPerType().size()];
2589                 std::transform((*iter).getCellIdPerType().begin(),(*iter).getCellIdPerType().end(),(int *)profile,std::bind2nd(std::plus<int>(),1));
2590                 MEDprofileWr(fid,profileName,(*iter).getCellIdPerType().size(),profile);
2591                 //
2592                 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da3=DataArrayInt::New();
2593                 da3->useArray(const_cast<int *>(&((*iter).getCellIdPerType()[0])),false,CPP_DEALLOC,(int)(*iter).getCellIdPerType().size(),1);
2594                 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da4=da3->deepCpy();
2595                 da4->applyLin(1,offset);
2596                 //
2597                 const MEDCouplingFieldDiscretizationGauss *disc2=static_cast<const MEDCouplingFieldDiscretizationGauss *>(f->getDiscretization());
2598                 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=disc2->getOffsetArr(f->getMesh());
2599                 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=DataArrayInt::New();
2600                 int trueNval=0;
2601                 for(const int *pt3=da4->begin();pt3!=da4->end();pt3++)
2602                   trueNval+=arr->getIJ(*pt3+1,0)-arr->getIJ(*pt3,0);
2603                 tmp->alloc(trueNval,1);
2604                 int *tmpPtr=tmp->getPointer();
2605                 for(const int *pt3=da4->begin();pt3!=da4->end();pt3++)
2606                   for(int j=arr->getIJ(*pt3,0);j<arr->getIJ(*pt3+1,0);j++)
2607                     *tmpPtr++=j;
2608                 arrTmp=f->getArray()->selectByTupleId(tmp->begin(),tmp->end());
2609                 pt2=arrTmp->getConstPointer();
2610               }
2611             const MEDCouplingGaussLocalization& gl=f->getGaussLocalization(id);
2612             MEDlocalizationWr(fid,nomGauss,typmai3[(int)(*iter).getType()],mesh->getMeshDimension(),&gl.getRefCoords()[0],MED_FULL_INTERLACE,
2613                               gl.getNumberOfGaussPt(),&gl.getGaussCoords()[0],&gl.getWeights()[0],MED_NO_INTERPOLATION, MED_NO_MESH_SUPPORT);
2614             int nbOfValues=gl.getNumberOfGaussPt()*nbOfEntity;
2615             INTERP_KERNEL::AutoPtr<char> fieldname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2616             MEDLoaderBase::safeStrCpy(f->getName(),MED_NAME_SIZE,fieldname,MEDLoader::_TOO_LONG_STR);
2617             if((*iter).getCellIdPerType().empty())
2618               {
2619                 MEDfieldValueWithProfileWr(fid,fieldname,numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE,
2620                                            MED_ALLENTITIES_PROFILE,nomGauss,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfEntity,(const unsigned char*)pt);
2621               }
2622             else
2623               MEDfieldValueWithProfileWr(fid,fieldname,numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE,
2624                                          profileName,nomGauss,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfEntity,(const unsigned char*)pt2);
2625             pt+=nbOfValues*nbComp;
2626             offset2+=(*iter).getNbOfGeoElt();
2627           }
2628         break;
2629       }
2630     case ParaMEDMEM::ON_GAUSS_NE:
2631       {
2632         std::list<MEDLoader::MEDFieldDoublePerCellType> split;
2633         prepareCellFieldDoubleForWriting(f,0,split);
2634         for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=split.begin();iter!=split.end();iter++)
2635           {
2636             int nbPtPerCell=(int)INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getNumberOfNodes();
2637             int nbOfEntity=f->getMesh()->getNumberOfCellsWithType((*iter).getType());
2638             int nbOfValues=nbPtPerCell*nbOfEntity;
2639             MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_NODE_ELEMENT,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE,
2640                                        MED_ALLENTITIES_PROFILE,MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfEntity,(const unsigned char*)pt);
2641             pt+=nbOfValues*nbComp;
2642           }
2643         break;
2644       }
2645     default:
2646       throw INTERP_KERNEL::Exception("Not managed this type of FIELD !");
2647     }
2648   if(renum)
2649     f->decrRef();
2650 }
2651
2652 /*!
2653  * This method splits field 'f' into types to be ready for writing.
2654  * @param cellIdsPerType this parameter can be 0 if not in profile mode. If it is != 0 this array is of size f->getMesh()->getNumberOfCells().
2655  */
2656 void MEDLoaderNS::prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *cellIdsPerType, std::list<MEDLoader::MEDFieldDoublePerCellType>& split)
2657 {
2658   int nbComp=f->getNumberOfComponents();
2659   const MEDCouplingMesh *mesh=f->getMesh();
2660   const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(mesh);
2661   if(!meshC)
2662     throw INTERP_KERNEL::Exception("Not implemented yet for not unstructured mesh !");
2663   if(!meshC->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO))
2664     throw INTERP_KERNEL::Exception("Unstructuded mesh has not consecutive cell types !");
2665   const int *connI=meshC->getNodalConnectivityIndex()->getConstPointer();
2666   const int *conn=meshC->getNodalConnectivity()->getConstPointer();
2667   int nbOfCells=meshC->getNumberOfCells();
2668   INTERP_KERNEL::NormalizedCellType curType;
2669   const int *wCellIdsPT=cellIdsPerType;
2670   for(const int *pt=connI;pt!=connI+nbOfCells;)
2671     {
2672       curType=(INTERP_KERNEL::NormalizedCellType)conn[*pt];
2673       const int *pt2=std::find_if(pt+1,connI+nbOfCells,ConnReaderML(conn,(int)curType));
2674       int szOfChunk=std::distance(pt,pt2);
2675       if(f->getTypeOfField()!=ON_GAUSS_PT)
2676         {
2677           if(!cellIdsPerType)
2678             split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,szOfChunk,1,0,0));
2679           else
2680             {
2681               split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,szOfChunk,1,wCellIdsPT,0));
2682               wCellIdsPT+=szOfChunk;
2683             }
2684         }
2685       else
2686         {
2687           const MEDCouplingFieldDiscretizationGauss *disc=static_cast<const MEDCouplingFieldDiscretizationGauss *>(f->getDiscretization());
2688           const DataArrayInt *arr=disc->getArrayOfDiscIds();
2689           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da,daTmp1;
2690           if(!cellIdsPerType)
2691             da=arr->selectByTupleId2(std::distance(connI,pt),std::distance(connI,pt2),1);
2692           else
2693             {
2694               daTmp1=DataArrayInt::New();
2695               daTmp1->useArray(const_cast<int *>(cellIdsPerType),false,CPP_DEALLOC,szOfChunk,1);
2696               MEDCouplingAutoRefCountObjectPtr<DataArrayInt> daTmp2=daTmp1->deepCpy();
2697               daTmp2->applyLin(1,std::distance(connI,pt));
2698               da=arr->selectByTupleId(daTmp2->begin(),daTmp2->end());
2699             }
2700           std::vector<int> differentIds;
2701           std::vector<DataArrayInt *> parts=da->partitionByDifferentValues(differentIds);
2702           std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > partsAuto(parts.size());
2703           int jj=0;
2704           for(std::vector<DataArrayInt *>::const_iterator it=parts.begin();it!=parts.end();it++,jj++)
2705             partsAuto[jj]=parts[jj];
2706           jj=0;
2707           for(std::vector<DataArrayInt *>::const_iterator it=parts.begin();it!=parts.end();it++,jj++)
2708             {
2709               if(!cellIdsPerType)
2710                 {
2711                   if(parts[jj]->getNumberOfTuples()==szOfChunk && parts[jj]->isIdentity())
2712                     split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,szOfChunk,1,0,0));
2713                   else
2714                     split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,parts[jj]->getNumberOfTuples(),1,parts[jj]->getConstPointer(),0));
2715                 }
2716               else
2717                 {
2718                   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=daTmp1->selectByTupleId(parts[jj]->begin(),parts[jj]->end());
2719                   split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,tmp->getNumberOfTuples(),1,tmp->getConstPointer(),0));
2720                 }
2721             }
2722           if(!cellIdsPerType)
2723             wCellIdsPT+=szOfChunk;
2724         }
2725       pt=pt2;
2726     }
2727 }
2728
2729 void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch)
2730 {
2731   f->checkCoherency();
2732   std::string meshName(f->getMesh()->getName());
2733   if(meshName.empty())
2734     throw INTERP_KERNEL::Exception("Trying to write a mesh (f->getMesh()) with no name ! MED file format needs a not empty mesh name !");
2735   std::string fieldName(f->getName());
2736   if(fieldName.empty())
2737     throw INTERP_KERNEL::Exception("Trying to write a field with no name ! MED file format needs a not empty field name !");
2738   MEDCouplingUMesh *mesh=dynamic_cast<MEDCouplingUMesh *>(const_cast<MEDCouplingMesh *>(f->getMesh()));
2739   if(mesh)
2740     {
2741       bool isRenumbering;
2742       std::vector<const MEDCouplingUMesh *> meshV(1); meshV[0]=mesh;
2743       std::vector<const DataArrayInt *> famV(1); famV[0]=0;
2744       writeUMeshesDirectly(fileName,meshV,famV,forceFromScratch,isRenumbering);
2745       if(isRenumbering)
2746         {
2747           MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f2=f->clone(true);
2748           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=mesh->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO);
2749           f2->renumberCells(da->getConstPointer(),false);
2750           appendFieldDirectly(fileName,f2);
2751         }
2752       else
2753         appendFieldDirectly(fileName,f);
2754       return ;
2755     }
2756   throw INTERP_KERNEL::Exception("The mesh underlying field is not unstructured ! Only unstructured mesh supported for writting now !");
2757 }
2758
2759 /*!
2760  * When called this method expectes that file 'fileName' is already existing and has a mesh with name equal to
2761  * f->getMesh()->getName(). If not the behaviour of this method is not warranted.
2762  * This method reads the corresponding mesh into the file and try to fit it with f->getMesh().
2763  * If it appears that f->getMesh() equals exactly mesh into the file 
2764  */
2765 void MEDLoaderNS::writeFieldTryingToFitExistingMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f)
2766 {
2767   std::vector<int> poss;
2768   int mDimInFile=MEDLoaderNS::readUMeshDimFromFile(fileName,f->getMesh()->getName(),poss);
2769   int mdim=f->getMesh()->getMeshDimension();
2770   int f2=mdim-mDimInFile;
2771   if(std::find(poss.begin(),poss.end(),f2)==poss.end())
2772     {
2773       std::ostringstream oss; oss << "Trying to fit with the existing \"" << f->getMesh()->getName() << "mesh in file \"" << fileName;
2774       oss << "\" but meshdimension does not match !";
2775       throw INTERP_KERNEL::Exception(oss.str().c_str());
2776     }
2777   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDLoader::ReadUMeshFromFile(fileName,f->getMesh()->getName(),f2);
2778   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m2=MEDCouplingUMesh::MergeUMeshes(m,static_cast<const MEDCouplingUMesh *>(f->getMesh()));
2779   bool areNodesMerged;
2780   int newNbOfNodes;
2781   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m2->mergeNodes(MEDLoader::_EPS_FOR_NODE_COMP,areNodesMerged,newNbOfNodes);
2782   if(!areNodesMerged || newNbOfNodes!=m->getNumberOfNodes())
2783     {
2784       std::ostringstream oss; oss << "Nodes in already written mesh \"" << f->getMesh()->getName() << "\" in file \"" << fileName << "\" does not fit coordinates of unstructured grid f->getMesh() !";
2785       throw INTERP_KERNEL::Exception(oss.str().c_str());
2786     }
2787   switch(f->getTypeOfField())
2788     {
2789     case ParaMEDMEM::ON_CELLS:
2790       {
2791         MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da2=m2->zipConnectivityTraducer(MEDLoader::_COMP_FOR_CELL);
2792         if(m2->getNumberOfCells()!=m->getNumberOfCells())
2793           {
2794             std::ostringstream oss1; oss1 << "Cells in already written mesh \"" << f->getMesh()->getName() << "\" in file \"" << fileName << "\" does not fit connectivity of unstructured grid f->getMesh() !";
2795             throw INTERP_KERNEL::Exception(oss1.str().c_str());
2796           }
2797         da=m2->convertCellArrayPerGeoType(da2);
2798         MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da3=da->substr(m2->getNumberOfCells());
2799         da2=m2->convertCellArrayPerGeoType(da3);
2800         appendCellProfileField(fileName,f,da2->getConstPointer());
2801         break;
2802       }
2803     case ParaMEDMEM::ON_GAUSS_NE:
2804       {
2805         MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da2=m2->zipConnectivityTraducer(MEDLoader::_COMP_FOR_CELL);
2806         if(m2->getNumberOfCells()!=m->getNumberOfCells())
2807           {
2808             std::ostringstream oss1; oss1 << "Cells in already written mesh \"" << f->getMesh()->getName() << "\" in file \"" << fileName << "\" does not fit connectivity of unstructured grid f->getMesh() !";
2809             throw INTERP_KERNEL::Exception(oss1.str().c_str());
2810           }
2811         da=m2->convertCellArrayPerGeoType(da2);
2812         MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da3=da->substr(m2->getNumberOfCells());
2813         da2=m2->convertCellArrayPerGeoType(da3);
2814         appendNodeElementProfileField(fileName,f,da2->getConstPointer());
2815         break;
2816       }
2817     case ParaMEDMEM::ON_NODES:
2818       {
2819         appendNodeProfileField(fileName,f,da->getConstPointer()+m->getNumberOfNodes());
2820         break;
2821       }
2822     default:
2823       {
2824         throw INTERP_KERNEL::Exception("Not implemented other profile fitting from already written mesh for fields than on NODES and on CELLS.");
2825       }
2826     }
2827 }
2828
2829 void MEDLoader::WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
2830 {
2831   std::string meshName(mesh->getName());
2832   if(meshName.empty())
2833     throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name !");
2834   int status=MEDLoaderBase::getStatusOfFile(fileName);
2835   bool isRenumbering;
2836   if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
2837     {
2838       std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
2839       throw INTERP_KERNEL::Exception(oss.str().c_str());
2840     }
2841   std::vector<const ParaMEDMEM::MEDCouplingUMesh *> meshV(1); meshV[0]=mesh;
2842   std::vector<const ParaMEDMEM::DataArrayInt *> famV(1); famV[0]=0;
2843   if(writeFromScratch)
2844     {
2845       MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering);
2846       return ;
2847     }
2848   if(status==MEDLoaderBase::NOT_EXIST)
2849     {
2850       MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering);
2851       return;
2852     }
2853   else
2854     {
2855       std::vector<std::string> meshNames=GetMeshNames(fileName);
2856       if(std::find(meshNames.begin(),meshNames.end(),meshName)==meshNames.end())
2857         MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,false,isRenumbering);
2858       else
2859         {
2860           std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \"";
2861           oss << meshName << "\" !";
2862           throw INTERP_KERNEL::Exception(oss.str().c_str());
2863         }
2864     }
2865 }
2866
2867 void MEDLoader::WriteUMeshDep(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
2868 {
2869   std::string meshName(mesh->getName());
2870   if(meshName.empty())
2871     throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name !");
2872   int status=MEDLoaderBase::getStatusOfFile(fileName);
2873   bool isRenumbering;
2874   if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
2875     {
2876       std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
2877       throw INTERP_KERNEL::Exception(oss.str().c_str());
2878     }
2879   std::vector<const ParaMEDMEM::MEDCouplingUMesh *> meshV(1); meshV[0]=mesh;
2880   std::vector<const ParaMEDMEM::DataArrayInt *> famV(1); famV[0]=0;
2881   if(writeFromScratch)
2882     {
2883       MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering);
2884       return ;
2885     }
2886   if(status==MEDLoaderBase::NOT_EXIST)
2887     {
2888       MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering);
2889       return;
2890     }
2891   else
2892     MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,false,isRenumbering);
2893 }
2894
2895 void MEDLoader::WriteUMeshesPartition(const char *fileName, const char *meshNameC, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
2896 {
2897   std::string meshName(meshNameC);
2898   if(meshName.empty())
2899     throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change 2nd parameter !");
2900   int status=MEDLoaderBase::getStatusOfFile(fileName);
2901   if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
2902     {
2903       std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
2904       throw INTERP_KERNEL::Exception(oss.str().c_str());
2905     }
2906   if(meshes.empty())
2907     throw INTERP_KERNEL::Exception("List of meshes must be not empty !");
2908   const DataArrayDouble *coords=meshes.front()->getCoords();
2909   for(std::vector<const ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=meshes.begin();iter!=meshes.end();iter++)
2910     if(coords!=(*iter)->getCoords())
2911       throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !");
2912   std::set<std::string> tmp;
2913   for(std::vector<const ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=meshes.begin();iter!=meshes.end();iter++)
2914     {
2915       if(tmp.find((*iter)->getName())==tmp.end())
2916         tmp.insert((*iter)->getName());
2917       else
2918         throw INTERP_KERNEL::Exception("The names of meshes must be different each other !");
2919     }
2920   tmp.clear();
2921   if(writeFromScratch)
2922     {
2923       MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true);
2924       return ;
2925     }
2926   if(status==MEDLoaderBase::NOT_EXIST)
2927     {
2928       MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true);
2929       return;
2930     }
2931   else
2932     {
2933       std::vector<std::string> meshNames=GetMeshNames(fileName);
2934       if(std::find(meshNames.begin(),meshNames.end(),meshName)==meshNames.end())
2935         MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,false);
2936       else
2937         {
2938           std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \"";
2939           oss << meshName << "\" !";
2940           throw INTERP_KERNEL::Exception(oss.str().c_str());
2941         }
2942     }
2943 }
2944
2945 void MEDLoader::WriteUMeshesPartitionDep(const char *fileName, const char *meshNameC, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
2946 {
2947   std::string meshName(meshNameC);
2948   if(meshName.empty())
2949     throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change 2nd parameter !");
2950   int status=MEDLoaderBase::getStatusOfFile(fileName);
2951   if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
2952     {
2953       std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
2954       throw INTERP_KERNEL::Exception(oss.str().c_str());
2955     }
2956   if(meshes.empty())
2957     throw INTERP_KERNEL::Exception("List of meshes must be not empty !");
2958   const DataArrayDouble *coords=meshes.front()->getCoords();
2959   for(std::vector<const ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=meshes.begin();iter!=meshes.end();iter++)
2960     if(coords!=(*iter)->getCoords())
2961       throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !");
2962   std::set<std::string> tmp;
2963   for(std::vector<const ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=meshes.begin();iter!=meshes.end();iter++)
2964     {
2965       if(tmp.find((*iter)->getName())==tmp.end())
2966         tmp.insert((*iter)->getName());
2967       else
2968         throw INTERP_KERNEL::Exception("The names of meshes must be different each other !");
2969     }
2970   tmp.clear();
2971   if(writeFromScratch)
2972     {
2973       MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true);
2974       return ;
2975     }
2976   if(status==MEDLoaderBase::NOT_EXIST)
2977     {
2978       MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true);
2979       return;
2980     }
2981   else
2982     {
2983       MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,false);
2984     }
2985 }
2986
2987 void MEDLoader::WriteUMeshes(const char *fileName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
2988 {
2989   int status=MEDLoaderBase::getStatusOfFile(fileName);
2990   if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
2991     {
2992       std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
2993       throw INTERP_KERNEL::Exception(oss.str().c_str());
2994     }
2995   if(meshes.empty())
2996     throw INTERP_KERNEL::Exception("List of meshes must be not empty !");
2997   std::string meshName(meshes[0]->getName());
2998   if(meshName.empty())
2999     throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change name of first element of 2nd parameter !");
3000   const DataArrayDouble *coords=meshes.front()->getCoords();
3001   for(std::vector<const ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=meshes.begin();iter!=meshes.end();iter++)
3002     if(coords!=(*iter)->getCoords())
3003       throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !");
3004   std::set<int> tmp;
3005   for(std::vector<const ParaMEDMEM::MEDCouplingUMesh *>::const_iterator iter=meshes.begin();iter!=meshes.end();iter++)
3006     {
3007       if(tmp.find((*iter)->getMeshDimension())==tmp.end())
3008         tmp.insert((*iter)->getMeshDimension());
3009       else
3010         throw INTERP_KERNEL::Exception("The mesh dimension of meshes must be different each other !");
3011     }
3012   tmp.clear();
3013   bool isRenumbering;
3014   std::vector<const DataArrayInt *> families(meshes.size());
3015   if(writeFromScratch)
3016     {
3017       MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,true,isRenumbering);
3018       return ;
3019     }
3020   if(status==MEDLoaderBase::NOT_EXIST)
3021     {
3022       MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,true,isRenumbering);
3023       return;
3024     }
3025   else
3026     {
3027       MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,false,isRenumbering);
3028       return;
3029     }
3030 }
3031
3032 void MEDLoader::WriteField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
3033 {
3034   int status=MEDLoaderBase::getStatusOfFile(fileName);
3035   if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
3036     {
3037       std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
3038       throw INTERP_KERNEL::Exception(oss.str().c_str());
3039     }
3040   if(writeFromScratch)
3041     {
3042       MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true);
3043      return ;
3044     }
3045   if(status==MEDLoaderBase::NOT_EXIST)
3046     {
3047      MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true);
3048      return ;
3049     }
3050   else
3051     {
3052       std::vector<std::string> meshNames=GetMeshNames(fileName);
3053       std::string fileNameCpp(f->getMesh()->getName());
3054       if(std::find(meshNames.begin(),meshNames.end(),fileNameCpp)==meshNames.end())
3055         MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,false);
3056       else
3057         MEDLoaderNS::writeFieldTryingToFitExistingMesh(fileName,f);
3058     }
3059 }
3060
3061 void MEDLoader::WriteFieldDep(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception)
3062 {
3063   int status=MEDLoaderBase::getStatusOfFile(fileName);
3064   if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST)
3065     {
3066       std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !";
3067       throw INTERP_KERNEL::Exception(oss.str().c_str());
3068     }
3069   if(writeFromScratch)
3070     {
3071       MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true);
3072      return ;
3073     }
3074   if(status==MEDLoaderBase::NOT_EXIST)
3075     {
3076      MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true);
3077      return ;
3078     }
3079   else
3080     MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,false);
3081 }
3082
3083 void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception)
3084 {
3085   f->checkCoherency();
3086   int status=MEDLoaderBase::getStatusOfFile(fileName);
3087   if(status!=MEDLoaderBase::EXIST_RW)
3088     {
3089       std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions or not exists !";
3090       throw INTERP_KERNEL::Exception(oss.str().c_str());
3091     }
3092   MEDLoaderNS::appendFieldDirectly(fileName,f);
3093 }