Salome HOME
e88101649156c5d3675355b2c956c576ce2b2a0d
[tools/medcoupling.git] / src / MEDPartitioner / MEDPARTITIONER_Utils.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "MEDPARTITIONER_Utils.hxx"
21
22 #include "MEDLoader.hxx"
23 #include "MEDLoaderBase.hxx"
24 #include "MEDFileUtilities.hxx"
25 #include "CellModel.hxx"
26 #include "MEDCouplingUMesh.hxx"
27 #include "MEDCouplingFieldDouble.hxx"
28 #include "InterpKernelException.hxx"
29 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
30 #include "InterpKernelAutoPtr.hxx"
31
32 #include <fstream>
33 #include <iostream>
34 #include <iomanip>
35 #include <sstream>
36 #include <string>
37 #include <cstring>
38
39 using namespace MEDPARTITIONER;
40
41 int MEDPARTITIONER::MyGlobals::_Verbose=0;
42 int MEDPARTITIONER::MyGlobals::_Is0verbose=0;
43 int MEDPARTITIONER::MyGlobals::_Rank=-1;
44 int MEDPARTITIONER::MyGlobals::_World_Size=-1;
45 int MEDPARTITIONER::MyGlobals::_Randomize=0;
46 int MEDPARTITIONER::MyGlobals::_Atomize=0;
47 int MEDPARTITIONER::MyGlobals::_Creates_Boundary_Faces=0;
48 std::vector<std::string> MEDPARTITIONER::MyGlobals::_File_Names;
49 std::vector<std::string> MEDPARTITIONER::MyGlobals::_Mesh_Names;
50 std::vector<std::string> MEDPARTITIONER::MyGlobals::_Field_Descriptions;
51 std::vector<std::string> MEDPARTITIONER::MyGlobals::_General_Informations;
52
53 std::string MEDPARTITIONER::Trim(const std::string& s,const std::string& drop)
54 {
55   std::string r(s);
56   r.erase(r.find_last_not_of(drop)+1);
57   return r.erase(0,r.find_first_not_of(drop));
58 }
59
60 std::string MEDPARTITIONER::IntToStr(const int i)
61 {
62   std::ostringstream oss;
63   oss << i;
64   return oss.str();
65 }
66
67 std::string MEDPARTITIONER::DoubleToStr(const double i)
68 {
69   std::ostringstream oss;
70   oss << i;
71   return oss.str();
72 }
73
74 int MEDPARTITIONER::StrToInt(const std::string& s)
75 {
76   int res;
77   std::istringstream iss(s);
78   iss >> res;
79   return res;
80 }
81
82 double MEDPARTITIONER::StrToDouble(const std::string& s)
83 {
84   double res;
85   std::istringstream iss(s);
86   iss >> res;
87   return res;
88 }
89
90 bool MEDPARTITIONER::TestArg(const char *arg, const char *argExpected, std::string& argValue)
91 {
92   argValue="";
93   std::size_t i;
94   for (i=0; i<strlen(arg); i++)
95     {
96       if (arg[i]=='=')
97         break;
98       if (arg[i]!=argExpected[i])
99         return false;
100     }
101   for (std::size_t j=i+1; j<strlen(arg); j++)
102     argValue+=arg[j];
103   return true;
104 }
105
106 std::vector<int> MEDPARTITIONER::CreateRandomSize(const int size)
107 {
108   std::vector<int> res(size);
109   for (int i=0; i<size; i++)
110     res[i]=i;
111   //cvw TODO or not? srand( (unsigned)time( NULL ) );
112   srand( MyGlobals::_Randomize );
113   for (int i=0; i<size; i++)
114     {
115       int ii=rand()%size;
116       int tmp=res[ii];
117       res[ii]=res[i];
118       res[i]=tmp;
119     }
120   return res;
121 }
122
123 /*!
124  * randomize a xadj and adjncy, renumbering vertices belong rand. Works only on one processor!!!!
125  */
126 void MEDPARTITIONER::RandomizeAdj(int* xadj, int* adjncy, std::vector<int>& ran, std::vector<int>& vx, std::vector<int>& va)
127 {
128   if (MyGlobals::_World_Size>1)
129     {
130       std::cerr << "MEDPARTITIONER::RandomizeAdj only works on one proc!" << std::endl;
131       return;
132     }
133   int size=ran.size();
134   std::vector<int> invran(size);
135   for (int i=0; i<size; i++)
136     invran[ran[i]]=i;
137   vx.resize(size+1);
138   int lga=xadj[size];
139   va.resize(lga);
140   int jj=0;
141   vx[0]=0;
142   for (int i=0; i<size; i++)
143     {
144       int ir=ran[i];
145       int ii=xadj[ir];
146       int lgj=xadj[ir+1]-ii;
147       for (int j=0; j<lgj; j++)
148         {
149           va[jj]=invran[adjncy[ii]];
150           jj=jj+1;
151           ii=ii+1;
152         }
153       vx[i+1]=jj;
154     }
155 }
156
157 void MEDPARTITIONER::TestRandomize()
158 {
159   //int xadj[6]={0,2,5,9,12,13}; //for first debug only
160   //int adjncy[13]={1,4,0,2,4,1,3,4,2,4,4,3,4};
161   int xadj[6]={0,2,5,9,12,13};
162   int adjncy[13]={0,0,1,1,1,2,2,2,2,3,3,3,4};
163   int size=5;
164   std::vector<int> r=CreateRandomSize(size);
165   std::vector<int> vx,va;
166   RandomizeAdj(&xadj[0],&adjncy[0],r,vx,va);
167 }
168
169 std::string MEDPARTITIONER::ReprVectorOfString(const std::vector<std::string>& vec)
170 {
171   if (vec.size()==0)
172     return std::string(" NONE\n");
173   std::ostringstream oss;
174   for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) 
175     oss << " -> '" << *i << "'" << std::endl;
176   return oss.str();
177 }
178
179 std::string MEDPARTITIONER::ReprVectorOfString(const std::vector<std::string>& vec, const std::string separator)
180 {
181   if (vec.size()==0)
182     return std::string(" NONE\n");
183   std::ostringstream oss;
184   for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) 
185     oss << separator << *i;
186   return oss.str();
187 }
188
189 std::string MEDPARTITIONER::ReprMapOfStringInt(const std::map<std::string,int>& mymap)
190 {
191   if (mymap.size()==0)
192     return std::string(" NONE\n");
193   std::ostringstream oss;
194   for (std::map<std::string,int>::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) 
195     oss << " -> [" << (*i).first << "]=" << (*i).second << std::endl;
196   return oss.str();
197 }
198
199 std::string MEDPARTITIONER::ReprMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap)
200 {
201   if (mymap.size()==0)
202     return std::string(" NONE\n");
203   std::ostringstream oss;
204   for (std::map< std::string,std::vector<std::string> >::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) 
205     oss << " -> [" << (*i).first << "]=" << std::endl << ReprVectorOfString((*i).second) << std::endl;
206   return oss.str();
207 }
208
209 std::string MEDPARTITIONER::ReprFieldDescriptions(const std::vector<std::string>& vec, const std::string separator)
210 {
211   if (vec.size()==0)
212     return std::string(" NONE\n");
213   std::ostringstream oss;
214   for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i)
215     {
216       oss << " ->"; 
217       oss << ReprVectorOfString(DeserializeToVectorOfString(*i), separator) << std::endl;
218     }
219   return oss.str();
220 }
221
222 /*!
223  * a string "hello" gives a string "    5/hello/"
224  * serialized_FromVectorOfString_string+SerializeFromString("toto") is
225  * equivalent to vector<string>.push_back("toto") on serialized_FromVectorOfString_string
226  */
227 std::string MEDPARTITIONER::SerializeFromString(const std::string& s)
228 {
229   std::ostringstream oss;
230   oss << std::setw(5) << s.size() << "/" << s << "/";
231   return oss.str();
232 }
233
234 /*!
235  * a vector of string gives a string
236  */
237 std::string MEDPARTITIONER::SerializeFromVectorOfString(const std::vector<std::string>& vec)
238 {
239   std::ostringstream oss;
240   for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i)
241     oss<< std::setw(5) << (*i).size() << "/" << *i << "/";
242   return oss.str();
243 }
244
245 /*!
246  * a string gives a vector of string
247  */
248 std::vector<std::string> MEDPARTITIONER::DeserializeToVectorOfString(const std::string& str)
249 {
250   std::vector<std::string> res;
251   std::size_t pos=0;
252   std::size_t posmax=str.size();
253   if (posmax==0)
254     return res;  //empty vector
255   std::size_t length;
256   while (pos < posmax-6)  //setw(5)+" "
257     {
258       std::istringstream iss(str.substr(pos,5));
259       iss >> length;
260       if ((str[pos+5]!='/') || (str[pos+6+length]!='/'))
261         {
262           std::cerr << "Error on string '" << str << "'" << std::endl;;
263           throw INTERP_KERNEL::Exception("Error on string");
264         }
265       res.push_back(str.substr(pos+6,length));
266       pos=pos+6+length+1;
267     }
268   return res;
269 }
270
271 std::string MEDPARTITIONER::EraseTagSerialized(const std::string& fromStr, const std::string& tag)
272 {
273   std::vector<std::string> vec=DeserializeToVectorOfString(fromStr);
274   std::vector<std::string> res;
275   for (std::size_t i=0; i<vec.size(); i++)
276     {
277       if (vec[i].find(tag)==std::string::npos)
278         res.push_back(vec[i]);
279     }
280   return MEDPARTITIONER::SerializeFromVectorOfString(res);
281 }
282
283 /*!
284  * elements first and second of map give one elements in result vector of string
285  * converting formatted the int second as firsts characters ending at first slash
286  */
287 std::vector<std::string> MEDPARTITIONER::VectorizeFromMapOfStringInt(const std::map<std::string,int>& mymap)
288 {
289   std::vector<std::string> res;
290   for (std::map<std::string,int>::const_iterator i=mymap.begin(); i!=mymap.end(); ++i)
291     {
292       std::ostringstream oss;
293       oss << (*i).second << "/" << (*i).first;
294       res.push_back(oss.str());
295     }
296   return res;
297 }
298
299 /*
300  * if existing identicals (first,second) in vector no problem, else Exception
301  */
302 std::map<std::string,int> MEDPARTITIONER::DevectorizeToMapOfStringInt(const std::vector<std::string>& vec)
303 {
304   std::map<std::string,int> res;
305   for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i)
306     {
307       std::size_t pos=0;
308       std::size_t posmax=(*i).size();
309       std::size_t found=(*i).find('/'); //first slash
310       if ((found==std::string::npos) || (found<1))
311         throw INTERP_KERNEL::Exception("Error aIntNumber/anyString is expected");
312       int second;
313       std::istringstream iss((*i).substr(pos,found));
314       iss >> second;
315       std::string first=(*i).substr(pos+found+1,posmax-found);
316       std::map<std::string,int>::iterator it=res.find(first);
317       if (it!=res.end())
318         if ((*it).second!=second)
319           throw INTERP_KERNEL::Exception("Error not the same map value");
320       res[first]=second;
321     }
322   return res;
323 }
324
325 /*!
326  * elements first and second of map give one elements in result vector of string
327  * adding key map and length of second vector as first string in each serialized vector
328  * one serialized vector per key map
329  */
330 std::vector<std::string> MEDPARTITIONER::VectorizeFromMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap)
331 {
332   std::vector<std::string> res;
333   for (std::map< std::string,std::vector<std::string> >::const_iterator i=mymap.begin(); i!=mymap.end(); ++i)
334     {
335       std::vector<std::string> vs=(*i).second;  //a vector of string;
336       std::ostringstream oss;
337       oss << "Keymap/" << (*i).first << "/" << (*i).second.size();
338       vs.insert(vs.begin(), oss.str());
339       res.push_back(SerializeFromVectorOfString(vs));
340     }
341   return res;
342 }
343
344 /*!
345  * if existing identicals keymap in vector no problem
346  * duplicates in second vector
347  */
348 std::map< std::string,std::vector<std::string> > MEDPARTITIONER::DevectorizeToMapOfStringVectorOfString(const std::vector<std::string>& vec)
349 {
350   std::map< std::string,std::vector<std::string> > res;
351   for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i)
352     {
353       std::vector<std::string> vs=DeserializeToVectorOfString(*i);
354     
355       std::string enTete=vs[0];
356       std::size_t posmax=enTete.size();
357       std::size_t foundKey=enTete.find("Keymap/");
358       std::size_t foundSizeVector=enTete.find_last_of('/');
359       if ((foundKey==std::string::npos) || (foundKey!=0) || ((foundKey+7)>=foundSizeVector))
360         throw INTERP_KERNEL::Exception("Error Keymap/anyString/aIntNumber is expected");
361       int sizeVector;
362       std::istringstream iss(enTete.substr(foundSizeVector+1,posmax-foundSizeVector));
363       iss >> sizeVector;
364       std::string keymap=enTete.substr(foundKey+7,foundSizeVector-foundKey-7);
365       for (int ii=1; ii<=sizeVector; ii++)
366         res[keymap].push_back(vs[ii]); //add unconditionnaly,so merge duplicates in second vector
367     }
368   return res;
369 }
370
371 /*!
372  * shit for unique and unique_copy for the duplicate CONSECUTIVE elements
373  * I do not want to sort
374  */
375 std::vector<std::string> MEDPARTITIONER::SelectTagsInVectorOfString(const std::vector<std::string>& vec, const std::string tag)
376 {
377   std::vector<std::string> res;
378   if (vec.size()==0)
379     return res;
380   for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i)
381     {
382       if ((*i).find(tag)!=std::string::npos) res.push_back(*i);
383     }
384   return res;
385 }
386
387 /*!
388  * 
389  */
390 std::vector<std::string> MEDPARTITIONER::DeleteDuplicatesInVectorOfString(const std::vector<std::string>& vec)
391 {
392   std::vector<std::string> res;
393   if (vec.size()==0) return res;
394   //shit for unique and unique_copy for the duplicate CONSECUTIVE elements
395   //I do not want to sort
396   for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i)
397     {
398       bool found=false;
399       for (std::vector<std::string>::const_iterator j=res.begin(); j!=res.end(); ++j)
400         {
401           if ((*i).compare(*j)==0)
402             {
403               found=true;
404               break;
405             }
406         }
407       if (!found) res.push_back(*i);
408     }
409   return res;
410 }
411
412 std::map< std::string,std::vector<std::string> > MEDPARTITIONER::DeleteDuplicatesInMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap)
413 {
414   std::map< std::string,std::vector<std::string> > res;
415   for (std::map< std::string,std::vector<std::string> >::const_iterator i=mymap.begin(); i!=mymap.end(); ++i)
416     res[(*i).first]=DeleteDuplicatesInVectorOfString((*i).second);
417   return res;
418 }
419
420 //void MEDPARTITIONER::sendRecvVectorOfString(const std::vector<string>& vec, const int source, const int target)
421 //TODO
422 std::string MEDPARTITIONER::Cle1ToStr(const std::string& s, const int inew)
423 {
424   std::ostringstream oss;
425   oss << s << " " << inew;
426   return oss.str();
427 }
428
429 void MEDPARTITIONER::Cle1ToData(const std::string& key, std::string& s, int& inew)
430 {
431   std::size_t posmax=key.size();
432   std::size_t found=key.find(' ');
433   if ((found==std::string::npos) || (found<1))
434     throw INTERP_KERNEL::Exception("Error 'aStringWithoutWhitespace aInt' is expected");
435   s=key.substr(0,found);
436   std::istringstream iss(key.substr(found,posmax-found));
437   iss >> inew;
438 }
439
440 std::string MEDPARTITIONER::Cle2ToStr(const std::string& s, const int inew, const int iold)
441 {
442   std::ostringstream oss;
443   oss << s << " " << inew << " " << iold;
444   return oss.str();
445 }
446
447 void MEDPARTITIONER::Cle2ToData(const std::string& key, std::string& s, int& inew, int& iold)
448 {
449   std::size_t posmax=key.size();
450   std::size_t found=key.find(' ');
451   if ((found==std::string::npos) || (found<1))
452     throw INTERP_KERNEL::Exception("Error 'aStringWithoutWhitespace aInt aInt' is expected");
453   s=key.substr(0,found);
454   std::istringstream iss(key.substr(found,posmax-found));
455   iss >> inew >> iold;
456 }
457
458 std::string MEDPARTITIONER::ExtractFromDescription(const std::string& description,const std::string& tag)
459 {
460   std::size_t found=description.find(tag);
461   if ((found==std::string::npos) || (found<1))
462     {
463       std::cerr << "ERROR : not found '" << tag << "' in '"<< description << "'\n";
464       throw INTERP_KERNEL::Exception("Error ExtractFromDescription");
465     }
466   std::size_t beg=found;
467   std::size_t end=beg;
468   if (description[found-1]!='/')
469     {
470       //find without '/'... and pray looking for first whitespace
471       //something like 'idomain=0 fileName=tmp.med meshName=...'
472       end=description.size();
473       beg+=tag.length();
474       std::string res=description.substr(beg,end-beg);
475       found=res.find(' ');
476       if (found==std::string::npos)
477         found=res.length();
478       res=res.substr(0,found);
479       return res;
480     }
481   std::size_t lg=StrToInt(description.substr(found-6,found));
482   beg+=tag.length();
483   return description.substr(beg,lg-tag.length());
484 }
485
486 void MEDPARTITIONER::FieldDescriptionToData(const std::string& description, 
487                                             int& idomain, std::string& fileName, std::string& meshName, std::string& fieldName, int& typeField, int& DT, int& IT)
488 {
489   idomain=StrToInt(ExtractFromDescription(description,"idomain="));
490   fileName=ExtractFromDescription(description,"fileName=");
491   meshName=ExtractFromDescription(description,"meshName=");
492   fieldName=ExtractFromDescription(description,"fieldName=");
493   typeField=StrToInt(ExtractFromDescription(description,"typeField="));
494   DT=StrToInt(ExtractFromDescription(description,"DT="));
495   IT=StrToInt(ExtractFromDescription(description,"IT="));
496 }
497
498 void MEDPARTITIONER::FieldShortDescriptionToData(const std::string& description, 
499                                                  std::string& fieldName, int& typeField, int& entity, int& DT, int& IT)
500 {
501   fieldName=ExtractFromDescription(description,"fieldName=");
502   typeField=StrToInt(ExtractFromDescription(description,"typeField="));
503   entity=StrToInt(ExtractFromDescription(description,"entity="));
504   DT=StrToInt(ExtractFromDescription(description,"DT="));
505   IT=StrToInt(ExtractFromDescription(description,"IT="));
506 }
507
508 ParaMEDMEM::DataArrayInt *MEDPARTITIONER::CreateDataArrayIntFromVector(const std::vector<int>& v)
509 {
510   ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New();
511   p->alloc(v.size(),1);
512   std::copy(v.begin(),v.end(),p->getPointer());
513   return p;
514 }
515
516 ParaMEDMEM::DataArrayInt *MEDPARTITIONER::CreateDataArrayIntFromVector(const std::vector<int>& v,const int nbComponents)
517 {
518   ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New();
519   if (v.size()%nbComponents!=0)
520     throw INTERP_KERNEL::Exception("Problem size modulo nbComponents != 0");
521   p->alloc(v.size()/nbComponents,nbComponents);
522   std::copy(v.begin(),v.end(),p->getPointer());
523   return p;
524 }
525
526 ParaMEDMEM::DataArrayDouble* MEDPARTITIONER::CreateDataArrayDoubleFromVector(const std::vector<double>& v)
527 {
528   ParaMEDMEM::DataArrayDouble* p=ParaMEDMEM::DataArrayDouble::New();
529   p->alloc(v.size(),1);
530   std::copy(v.begin(),v.end(),p->getPointer());
531   return p;
532 }
533
534 /*!
535  */
536 std::vector<std::string> MEDPARTITIONER::BrowseFieldDouble(const ParaMEDMEM::MEDCouplingFieldDouble* fd)
537 {
538   std::vector<std::string> res;
539   if (fd->getArray())
540     {
541       int nb=fd->getArray()->getNumberOfComponents();
542       res.push_back("nbComponents="); res.back()+=IntToStr(nb);
543       for (int i=0; i<nb; i++)
544         {
545           res.push_back("componentInfo");
546           res.back()+=IntToStr(i)+"="+fd->getArray()->getInfoOnComponent(i);
547         }
548     }
549   else
550     {
551       res.push_back("nbComponents=0");  //unknown
552     }
553   return res;
554 }
555
556 /*!
557  * quick almost human readable information on all fields in a .med file
558  */
559 std::vector<std::string> MEDPARTITIONER::BrowseAllFields(const std::string& myfile)
560 {
561   std::vector<std::string> res;
562   std::vector<std::string> meshNames=MEDLoader::GetMeshNames(myfile);
563   
564   for (std::size_t i=0; i<meshNames.size(); i++)
565     {
566       std::vector<std::string> fieldNames=
567         MEDLoader::GetAllFieldNamesOnMesh(myfile,meshNames[i]);
568       for (std::size_t j = 0; j < fieldNames.size(); j++)
569         {
570           std::vector< ParaMEDMEM::TypeOfField > typeFields=
571             MEDLoader::GetTypesOfField(myfile, meshNames[i], fieldNames[j]);
572           for (std::size_t k = 0; k < typeFields.size(); k++)
573             {
574               std::vector< std::pair< int, int > > its=
575                 MEDLoader::GetFieldIterations(typeFields[k], myfile, meshNames[i], fieldNames[j]);
576               if (MyGlobals::_Is0verbose>100)
577                 std::cout<< "fieldName " << fieldNames[j] << " typeField " << typeFields[k] << " its.size() " << its.size() << std::endl;
578               for (std::size_t m = 0; m < its.size(); m++)
579                 {
580                   std::vector<std::string> resi;
581                   resi.push_back("fileName="); resi.back()+=myfile;
582                   resi.push_back("meshName="); resi.back()+=meshNames[i];
583                   resi.push_back("fieldName="); resi.back()+=fieldNames[j];
584                   resi.push_back("typeField="); resi.back()+=IntToStr((int)typeFields[k]);
585                   resi.push_back("DT="); resi.back()+=IntToStr((int)its[m].first);
586                   resi.push_back("IT="); resi.back()+=IntToStr((int)its[m].second);
587                   res.push_back(SerializeFromVectorOfString(resi));
588                 }
589             }
590         }
591     }
592   return res;
593 }
594
595 std::vector<std::string> MEDPARTITIONER::GetInfosOfField(const char *fileName, const char *meshName, const int idomain)
596 {
597   const int lggeom=10;
598   const med_geometry_type GEOMTYPE[lggeom]={ //MED_N_CELL_FIXED_GEO] = { 
599     //MED_POINT1,
600     //MED_SEG2,
601     //MED_SEG3,
602     //MED_SEG4,
603     //MED_TRIA3,
604     //MED_QUAD4,
605     //MED_TRIA6,
606     //MED_TRIA7,
607     //MED_QUAD8,
608     //MED_QUAD9,
609     MED_TETRA4,
610     MED_PYRA5,
611     MED_PENTA6,
612     MED_HEXA8,
613     MED_OCTA12,
614     MED_TETRA10,
615     MED_PYRA13,
616     MED_PENTA15,
617     MED_HEXA20,
618     MED_HEXA27,
619     //MED_POLYGON,
620     //MED_POLYHEDRON 
621   };
622
623   const char * const GEOMTYPENAME[lggeom]={
624     //"MED_POINT1",
625     //"MED_SEG2",
626     //"MED_SEG3",
627     //"MED_SEG4",
628     //"MED_TRIA3",
629     //"MED_QUAD4",
630     //"MED_TRIA6",
631     //"MED_TRIA7",
632     //"MED_QUAD8",
633     //"MED_QUAD9",
634     "MED_TETRA4",
635     "MED_PYRA5",
636     "MED_PENTA6",
637     "MED_HEXA8",
638     "MED_OCTA12",
639     "MED_TETRA10",
640     "MED_PYRA13",
641     "MED_PENTA15",
642     "MED_HEXA20",
643     "MED_HEXA27",
644     //"MED_POLYGONE",
645     //"MED_POLYEDRE",
646   };
647
648
649   const int lgentity=3;
650   const med_entity_type ENTITYTYPE[lgentity]={ //MED_N_ENTITY_TYPES+2]={
651     //MED_UNDEF_ENTITY_TYPE,
652     MED_CELL,
653     //MED_DESCENDING_FACE,
654     //MED_DESCENDING_EDGE,
655     MED_NODE,
656     MED_NODE_ELEMENT,
657     //MED_STRUCT_ELEMENT,
658     //MED_UNDEF_ENTITY_TYPE
659   };
660
661   const char * const ENTITYTYPENAME[lgentity]={ //MED_N_ENTITY_TYPES+2]={
662     //"MED_UNDEF_ENTITY_TYPE",
663     "MED_CELL",
664     //"MED_FACE",
665     //"MED_ARETE",
666     "MED_NODE",
667     "MED_NODE_ELEMENT",
668     //"MED_STRUCT_ELEMENT",
669     //"MED_UNDEF_ENTITY_TYPE"
670   };
671   
672   std::vector<std::string> res;
673   med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
674   med_int nbFields=MEDnField(fid);
675   if (MyGlobals::_Verbose>20)
676     std::cout << "on filename " << fileName << " nbOfField " << nbFields << std::endl;
677   //
678   med_field_type typcha;
679   med_int numdt=0,numo=0;
680   med_float dt=0.0;
681   char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
682   char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
683   med_bool localmesh;
684   //
685   for(int i=1; i<=nbFields; i++)
686     {
687       med_int ncomp=MEDfieldnComponent(fid,i);
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> dt_unit=new char[MED_LNAME_SIZE+1];
691       med_int nbPdt;
692       MEDfieldInfo(fid,i,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt);
693       std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1);
694       std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1);
695       for (int k=1; k<=nbPdt; k++)
696         {
697           MEDfieldComputingStepInfo(fid,nomcha,k,&numdt,&numo,&dt);
698           if (MyGlobals::_Verbose>20) 
699             std::cout<< "on filename " << fileName << " field " << i << " fieldName " << curFieldName << " meshName " << curMeshName <<
700               " typ " << typcha << " nbComponent " << ncomp << " nbPdt " << nbPdt << " noPdt " << k <<
701               " ndt " << numdt << " nor " << numo << " dt " << dt << std::endl;
702           for (int ie=0; ie<lgentity; ie++)
703             {
704               for (int j=0; j<lggeom; j++)
705                 {
706                   int profilesize=0,nbi=0;
707                   med_entity_type enttype=ENTITYTYPE[ie];
708                   //enttype=MED_NODE;enttype=MED_CELL;enttype=MED_NODE_ELEMENT;
709                   char pflname[MED_NAME_SIZE+1]="";
710                   char locname[MED_NAME_SIZE+1]="";
711                   med_int nbofprofile=MEDfieldnProfile(fid,nomcha,numdt,numo,enttype,GEOMTYPE[j],pflname,locname);
712                   int profileit=1;
713                   if (enttype==MED_NODE)
714                     {
715                       med_geometry_type mygeomtype=MED_UNDEF_ENTITY_TYPE;
716                       med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,enttype,mygeomtype,profileit,
717                                                                 MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi);
718                       if (nbOfVal>0)
719                         {
720                           if (MyGlobals::_Verbose>20)
721                             std::cout << "on filename " << fileName << " entity " << enttype << " nbOfVal with " <<
722                               nbofprofile << " profile(s) for geomType (AUCUN) nbOfVal " <<
723                               nbOfVal << " profilName '" << pflname << "' profileSize " << profilesize << " nbPtGauss " << nbi << std::endl;
724                           std::vector<std::string> resi;
725                           resi.push_back("idomain="); resi.back()+=IntToStr(idomain);
726                           resi.push_back("fileName="); resi.back()+=fileName;
727                           resi.push_back("meshName="); resi.back()+=curMeshName;
728                           resi.push_back("fieldName="); resi.back()+=curFieldName;
729                           resi.push_back("typeField="); resi.back()+=IntToStr((int)ParaMEDMEM::ON_NODES);
730                           resi.push_back("typeData="); resi.back()+=IntToStr((int)typcha);  //6 for double?
731                           resi.push_back("nbComponent="); resi.back()+=IntToStr((int)ncomp);
732                           resi.push_back("DT="); resi.back()+=IntToStr((int)numdt);
733                           resi.push_back("IT="); resi.back()+=IntToStr((int)numo);
734                           resi.push_back("time="); resi.back()+=DoubleToStr(dt);
735                           resi.push_back("entity="); resi.back()+=IntToStr((int)enttype);
736                           resi.push_back("entityName="); resi.back()+=ENTITYTYPENAME[ie];
737                           resi.push_back("nbOfVal="); resi.back()+=IntToStr((int)nbOfVal);
738                           resi.push_back("profilName="); resi.back()+=pflname;
739                           resi.push_back("profileSize="); resi.back()+=IntToStr((int)profilesize);
740                           resi.push_back("nbPtGauss="); resi.back()+=IntToStr((int)nbi);
741                           res.push_back(SerializeFromVectorOfString(resi));
742                         }
743                       break; //on nodes no need to scute all geomtype
744                     }
745                   else
746                     {
747                       med_geometry_type mygeomtype=GEOMTYPE[j];
748                       med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,enttype,mygeomtype,profileit,
749                                                                 MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi);
750                       if (nbOfVal>0)
751                         {
752                           if (MyGlobals::_Verbose>20)
753                             std::cout << "on filename " << fileName << " entity " << enttype << " nbOfVal with " <<
754                               nbofprofile << " profile(s) for geomType " <<
755                               GEOMTYPE[j] << " " << GEOMTYPENAME[j] << " nbOfVal " <<
756                               nbOfVal << " profilName '" << pflname << "' profileSize " << profilesize << " nbPtGauss " << nbi << std::endl;
757                           int typeField=-1; //unknown
758                           if (enttype==MED_CELL)
759                             typeField=ParaMEDMEM::ON_CELLS;
760                           if (enttype==MED_NODE_ELEMENT)
761                             typeField=ParaMEDMEM::ON_GAUSS_NE;
762                           //if (enttype==??) typeField=ON_GAUSS_PT;
763                           std::vector<std::string> resi;
764                           resi.push_back("idomain="); resi.back()+=IntToStr(idomain);
765                           resi.push_back("fileName="); resi.back()+=fileName;
766                           resi.push_back("meshName="); resi.back()+=curMeshName;
767                           resi.push_back("fieldName="); resi.back()+=curFieldName;
768                           resi.push_back("typeField="); resi.back()+=IntToStr((int)typeField);
769                           resi.push_back("typeData="); resi.back()+=IntToStr((int)typcha);  //6 for double?
770                           resi.push_back("nbComponent="); resi.back()+=IntToStr((int)ncomp);
771                           resi.push_back("DT="); resi.back()+=IntToStr((int)numdt);
772                           resi.push_back("IT="); resi.back()+=IntToStr((int)numo);
773                           resi.push_back("time="); resi.back()+=DoubleToStr(dt);
774                           resi.push_back("entity="); resi.back()+=IntToStr((int)enttype);
775                           resi.push_back("entityName="); resi.back()+=ENTITYTYPENAME[ie];
776                           resi.push_back("geomType="); resi.back()+=IntToStr((int)GEOMTYPE[j]);
777                           resi.push_back("geomTypeName="); resi.back()+=GEOMTYPENAME[j];
778                           resi.push_back("nbOfVal="); resi.back()+=IntToStr((int)nbOfVal);
779                           resi.push_back("profilName="); resi.back()+=pflname;
780                           resi.push_back("profileSize="); resi.back()+=IntToStr((int)profilesize);
781                           resi.push_back("nbPtGauss="); resi.back()+=IntToStr((int)nbi);
782                           if (typeField==(-1))
783                             {
784                               std::cout << "WARNING : unknown typeField for entity type " << enttype << std::endl <<
785                                 SerializeFromVectorOfString(resi) << std::endl;
786                               continue;  //do not register push_back
787                             }
788                           res.push_back(SerializeFromVectorOfString(resi));
789                         }
790                     }
791                 }
792             }
793         }
794     }
795   delete [] maa_ass;
796   delete [] nomcha;
797   MEDfileClose(fid);
798   if (MyGlobals::_Verbose>10)
799     std::cout << "detected fields:\n" << ReprVectorOfString(res) << std::endl;
800   return res;
801 }
802
803 /*!
804  * quick almost human readable information on all fields on a mesh in a .med file
805  */
806 std::vector<std::string> MEDPARTITIONER::BrowseAllFieldsOnMesh(const std::string& myfile, const std::string& mymesh, const int idomain)
807 {
808   std::vector<std::string> res=GetInfosOfField(myfile.c_str(),mymesh.c_str(),idomain);
809   return res;
810 }
811
812 /*!
813  * create empty MEDCouplingUMesh* dim 3
814  */
815 ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::CreateEmptyMEDCouplingUMesh()
816 {
817   ParaMEDMEM::MEDCouplingUMesh* umesh=ParaMEDMEM::MEDCouplingUMesh::New();
818   umesh->setMeshDimension(3);
819   umesh->allocateCells(0);
820   umesh->finishInsertingCells();
821   ParaMEDMEM::DataArrayDouble *myCoords=ParaMEDMEM::DataArrayDouble::New();
822   myCoords->alloc(0,3);
823   umesh->setCoords(myCoords);
824   umesh->setName("EMPTY");
825   myCoords->decrRef();
826   umesh->checkCoherency();
827   return umesh;
828 }
829
830 namespace MEDPARTITIONER
831 {
832   BBTreeOfDim::BBTreeOfDim( int           dim,
833                             const double* bbs,
834                             int*          elems,
835                             int           level,
836                             int           nbelems,
837                             double        epsilon)
838   {
839     switch ( dim )
840       {
841       case 3:
842         _tree=new BBTree<3> (bbs,elems,level,nbelems,epsilon);
843         _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 3 >;
844         _PgetIntersectingElems   = & BBTreeOfDim::_getIntersectingElems< 3 >;
845         break;
846       case 2:
847         _tree=new BBTree<2> (bbs,elems,level,nbelems,epsilon);
848         _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 2 >;
849         _PgetIntersectingElems   = & BBTreeOfDim::_getIntersectingElems< 2 >;
850         break;
851       case 1:
852         _tree=new BBTree<1> (bbs,elems,level,nbelems,epsilon);
853         _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 1 >;
854         _PgetIntersectingElems   = & BBTreeOfDim::_getIntersectingElems< 1 >;
855         break;
856       default:
857         _tree=0;
858         throw INTERP_KERNEL::Exception("BBTreeOfDim(): wrong space dimension");
859       }
860   }
861
862   BBTreeOfDim::~BBTreeOfDim()
863   {
864     delete (BBTree<3>*)_tree;
865   }
866
867   void BBTreeOfDim::getElementsAroundPoint( const double* coordsPtr,
868                                             std::vector<int>& elems ) const
869   {
870     BBTreeOfDim* me = (BBTreeOfDim*) this;
871     (me->*_PgetElementsAroundPoint) ( coordsPtr, elems );
872   }
873   void BBTreeOfDim::getIntersectingElems(const double* bb,
874                                          std::vector<int>& elems) const
875   {
876     BBTreeOfDim* me = (BBTreeOfDim*) this;
877     (me->*_PgetIntersectingElems) ( bb, elems );
878   }
879 }