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