Salome HOME
Modifications to properly handle parallel compute for 2D
[modules/smesh.git] / src / SMESH_I / SMESH_Homard_i.cxx
1 // Copyright (C) 2011-2023  CEA, EDF
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 "SMESH_Homard_i.hxx"
21 #include "SMESH_Homard.hxx"
22
23 #include "SMESH_Gen_i.hxx"
24 #include "SMESH_PythonDump.hxx"
25
26 #include "SMESH_File.hxx"
27
28 #include "utilities.h"
29 #include "Basics_Utils.hxx"
30 #include "Basics_DirUtils.hxx"
31 #include "Utils_SINGLETON.hxx"
32 #include "Utils_CorbaException.hxx"
33 #include "SALOMEDS_Tool.hxx"
34 #include "SALOME_LifeCycleCORBA.hxx"
35 #include "SALOMEconfig.h"
36
37 // Have to be included before std headers
38 #include <Python.h>
39 #include <structmember.h>
40
41 #include <vector>
42 #include <cmath>
43 #include <cstdlib>
44 #include <stdlib.h>
45 #include <sys/stat.h>
46 #include <algorithm>
47
48 #include <med.h>
49
50 #ifdef WIN32
51 #include <direct.h>
52 #else
53 #include <dirent.h>
54 #endif
55
56 #include <string>
57 #include <cstring>
58 #include <iostream>
59 #include <fstream>
60 #include <iomanip>
61 #include <set>
62 #include <vector>
63 #include <stdio.h>
64
65 // C'est le ASSERT de SALOMELocalTrace/utilities.h dans KERNEL
66 #ifndef VERIFICATION
67 #define VERIFICATION(condition) \
68         if (!(condition)){INTERRUPTION("CONDITION "<<#condition<<" NOT VERIFIED")}
69 #endif /* VERIFICATION */
70
71 // La gestion des repertoires
72 #ifndef CHDIR
73   #ifdef WIN32
74     #define CHDIR _chdir
75   #else
76     #define CHDIR chdir
77   #endif
78 #endif
79
80 using namespace std;
81
82 SMESHHOMARD::HOMARD_Gen_ptr SMESH_Gen_i::CreateHOMARD_ADAPT()
83 {
84   if (getenv("HOMARD_ROOT_DIR") == NULL) {
85     THROW_SALOME_CORBA_EXCEPTION("HOMARD_ROOT_DIR is not defined", SALOME::INTERNAL_ERROR);
86   }
87   else {
88     std::string homard_exec = getenv("HOMARD_ROOT_DIR");
89     homard_exec += "/bin/salome/homard";
90     if (!SMESH_File(homard_exec).exists())
91       THROW_SALOME_CORBA_EXCEPTION("HOMARD module is not built", SALOME::INTERNAL_ERROR);
92   }
93   SMESHHOMARD_I::HOMARD_Gen_i* aHomardGen = new SMESHHOMARD_I::HOMARD_Gen_i();
94   SMESHHOMARD::HOMARD_Gen_var anObj = aHomardGen->_this();
95   return anObj._retn();
96 }
97
98 namespace SMESHHOMARD_I
99 {
100
101 //=============================================================================
102 /*!
103  *  standard constructor
104  */
105 //=============================================================================
106 HOMARD_Boundary_i::HOMARD_Boundary_i()
107   : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA())
108 {
109   MESSAGE("Default constructor, not for use");
110   ASSERT(0);
111 }
112 //=============================================================================
113 /*!
114  *  standard constructor
115  */
116 //=============================================================================
117 HOMARD_Boundary_i::HOMARD_Boundary_i(SMESHHOMARD::HOMARD_Gen_var engine)
118   : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA())
119 {
120   MESSAGE("HOMARD_Boundary_i");
121   _gen_i = engine;
122   myHomardBoundary = new SMESHHOMARDImpl::HOMARD_Boundary();
123   ASSERT(myHomardBoundary);
124 }
125 //=============================================================================
126 /*!
127  *  standard destructor
128  */
129 //=============================================================================
130 HOMARD_Boundary_i::~HOMARD_Boundary_i()
131 {
132 }
133 //=============================================================================
134 //=============================================================================
135 // Generalites
136 //=============================================================================
137 //=============================================================================
138 void HOMARD_Boundary_i::SetName(const char* Name)
139 {
140   ASSERT(myHomardBoundary);
141   myHomardBoundary->SetName(Name);
142 }
143 //=============================================================================
144 char* HOMARD_Boundary_i::GetName()
145 {
146   ASSERT(myHomardBoundary);
147   return CORBA::string_dup(myHomardBoundary->GetName().c_str());
148 }
149 //=============================================================================
150 char* HOMARD_Boundary_i::GetDumpPython()
151 {
152   ASSERT(myHomardBoundary);
153   return CORBA::string_dup(myHomardBoundary->GetDumpPython().c_str());
154 }
155 //=============================================================================
156 //=============================================================================
157 // Caracteristiques
158 //=============================================================================
159 //=============================================================================
160 void HOMARD_Boundary_i::SetType(CORBA::Long Type)
161 {
162   ASSERT(myHomardBoundary);
163   myHomardBoundary->SetType(Type);
164 }
165 //=============================================================================
166 CORBA::Long HOMARD_Boundary_i::GetType()
167 {
168   ASSERT(myHomardBoundary);
169   return  CORBA::Long(myHomardBoundary->GetType());
170 }
171 //=============================================================================
172 void HOMARD_Boundary_i::SetMeshName(const char* MeshName)
173 {
174   ASSERT(myHomardBoundary);
175   myHomardBoundary->SetMeshName(MeshName);
176 }
177 //=============================================================================
178 char* HOMARD_Boundary_i::GetMeshName()
179 {
180   ASSERT(myHomardBoundary);
181   return CORBA::string_dup(myHomardBoundary->GetMeshName().c_str());
182 }
183 //=============================================================================
184 void HOMARD_Boundary_i::SetDataFile(const char* DataFile)
185 {
186   ASSERT(myHomardBoundary);
187   myHomardBoundary->SetDataFile(DataFile);
188 }
189 //=============================================================================
190 char* HOMARD_Boundary_i::GetDataFile()
191 {
192   ASSERT(myHomardBoundary);
193   return CORBA::string_dup(myHomardBoundary->GetDataFile().c_str());
194 }
195 //=============================================================================
196 void HOMARD_Boundary_i::SetCylinder(double X0, double X1, double X2, double X3, double X4, double X5, double X6)
197 {
198   ASSERT(myHomardBoundary);
199   myHomardBoundary->SetCylinder(X0, X1, X2, X3, X4, X5, X6);
200 }
201 //=============================================================================
202 void HOMARD_Boundary_i::SetSphere(double Xcentre, double Ycentre, double ZCentre, double rayon)
203 {
204   ASSERT(myHomardBoundary);
205   myHomardBoundary->SetSphere(Xcentre, Ycentre, ZCentre, rayon);
206 }
207 //=============================================================================
208 void HOMARD_Boundary_i::SetConeR(double Xcentre1, double Ycentre1, double Zcentre1, double Rayon1, double Xcentre2, double Ycentre2, double Zcentre2, double Rayon2)
209 {
210   ASSERT(myHomardBoundary);
211   myHomardBoundary->SetConeR(Xcentre1, Ycentre1, Zcentre1, Rayon1, Xcentre2, Ycentre2, Zcentre2, Rayon2);
212 }
213 //=============================================================================
214 void HOMARD_Boundary_i::SetConeA(double Xaxe, double Yaxe, double Zaxe, double Angle, double Xcentre, double Ycentre, double Zcentre)
215 {
216   ASSERT(myHomardBoundary);
217   myHomardBoundary->SetConeA(Xaxe, Yaxe, Zaxe, Angle, Xcentre, Ycentre, Zcentre);
218 }
219 //=============================================================================
220 void HOMARD_Boundary_i::SetTorus(double X0, double X1, double X2, double X3, double X4, double X5, double X6, double X7)
221 {
222   ASSERT(myHomardBoundary);
223   myHomardBoundary->SetTorus(X0, X1, X2, X3, X4, X5, X6, X7);
224 }
225 //=============================================================================
226 SMESHHOMARD::double_array* HOMARD_Boundary_i::GetCoords()
227 {
228   ASSERT(myHomardBoundary);
229   SMESHHOMARD::double_array_var aResult = new SMESHHOMARD::double_array();
230   std::vector<double> mesCoor = myHomardBoundary->GetCoords();
231   aResult->length(mesCoor .size());
232   std::vector<double>::const_iterator it;
233   int i = 0;
234   for (it = mesCoor.begin(); it != mesCoor.end(); it++)
235     aResult[i++] = (*it);
236   return aResult._retn();
237 }
238 //=============================================================================
239 void HOMARD_Boundary_i::SetLimit(double Xincr, double Yincr, double Zincr)
240 {
241   ASSERT(myHomardBoundary);
242   myHomardBoundary->SetLimit(Xincr, Yincr, Zincr);
243 }
244 //=============================================================================
245 SMESHHOMARD::double_array* HOMARD_Boundary_i::GetLimit()
246 {
247   ASSERT(myHomardBoundary);
248   SMESHHOMARD::double_array_var aResult = new SMESHHOMARD::double_array();
249   std::vector<double> mesCoor = myHomardBoundary->GetLimit();
250   aResult->length(mesCoor .size());
251   std::vector<double>::const_iterator it;
252   int i = 0;
253   for (it = mesCoor.begin(); it != mesCoor.end(); it++)
254     aResult[i++] = (*it);
255   return aResult._retn();
256 }
257 //=============================================================================
258 void HOMARD_Boundary_i::AddGroup(const char* Group)
259 {
260   ASSERT(myHomardBoundary);
261   myHomardBoundary->AddGroup(Group);
262 }
263 //=============================================================================
264 void HOMARD_Boundary_i::SetGroups(const SMESHHOMARD::ListGroupType& ListGroup)
265 {
266   ASSERT(myHomardBoundary);
267   std::list<std::string> ListString;
268   for (unsigned int i = 0; i < ListGroup.length(); i++) {
269     ListString.push_back(std::string(ListGroup[i]));
270   }
271   myHomardBoundary->SetGroups(ListString);
272 }
273 //=============================================================================
274 SMESHHOMARD::ListGroupType*  HOMARD_Boundary_i::GetGroups()
275 {
276   ASSERT(myHomardBoundary);
277   const std::list<std::string>& ListString = myHomardBoundary->GetGroups();
278   SMESHHOMARD::ListGroupType_var aResult = new SMESHHOMARD::ListGroupType;
279   aResult->length(ListString.size());
280   std::list<std::string>::const_iterator it;
281   int i = 0;
282   for (it = ListString.begin(); it != ListString.end(); it++)
283   {
284     aResult[i++] = CORBA::string_dup((*it).c_str());
285   }
286   return aResult._retn();
287 }
288
289 //=============================================================================
290 /*!
291  *  standard constructor
292  */
293 //=============================================================================
294 HOMARD_Cas_i::HOMARD_Cas_i()
295   : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA())
296 {
297   MESSAGE("Default constructor, not for use");
298   ASSERT(0);
299 }
300
301 //=============================================================================
302 /*!
303  *  standard constructor
304  */
305 //=============================================================================
306 HOMARD_Cas_i::HOMARD_Cas_i(SMESHHOMARD::HOMARD_Gen_var engine)
307   : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA())
308 {
309   MESSAGE("HOMARD_Cas_i");
310   _gen_i = engine;
311   myHomardCas = new SMESHHOMARDImpl::HOMARD_Cas();
312   ASSERT(myHomardCas);
313 }
314
315 //=============================================================================
316 /*!
317  *  standard destructor
318  */
319 //=============================================================================
320 HOMARD_Cas_i::~HOMARD_Cas_i()
321 {
322 }
323 //=============================================================================
324 char* HOMARD_Cas_i::GetDumpPython()
325 {
326   ASSERT(myHomardCas);
327   return CORBA::string_dup(myHomardCas->GetDumpPython().c_str());
328 }
329 //=============================================================================
330 //=============================================================================
331 // Caracteristiques
332 //=============================================================================
333 //=============================================================================
334 void HOMARD_Cas_i::SetDirName(const char* NomDir)
335 {
336   ASSERT(myHomardCas);
337   int codret;
338   // A. recuperation du nom; on ne fait rien si c'est le meme
339   char* oldrep = GetDirName();
340   if (strcmp(oldrep,NomDir) == 0) return;
341   MESSAGE ("SetDirName : passage de oldrep = "<< oldrep << " a NomDir = "<<NomDir);
342   // C. Changement/creation du repertoire
343   codret = myHomardCas->SetDirName(NomDir);
344   if (codret != 0) {
345     SALOME::ExceptionStruct es;
346     es.type = SALOME::BAD_PARAM;
347     std::string text;
348     if (codret == 1)
349       text = "The directory for the case cannot be modified because some iterations are already defined.";
350     else
351       text = "The directory for the case cannot be reached.";
352     es.text = CORBA::string_dup(text.c_str());
353     throw SALOME::SALOME_Exception(es);
354   }
355
356   // D. En cas de reprise, deplacement du point de depart
357   HOMARD_Gen_i* aGenImpl = SMESH::DownCast<HOMARD_Gen_i*>(_gen_i);
358   HOMARD_Iteration_i* Iter0 = aGenImpl->GetIteration(0);
359   int state = Iter0->GetNumber();
360   if (state != 0) { // GetState()
361     MESSAGE ("etat : " << state);
362     // D.1. Nom local du repertoire de l'iteration de depart dans le repertoire actuel du cas
363     char* DirNameIter = Iter0->GetDirNameLoc();
364     MESSAGE ("SetDirName : nom actuel pour le repertoire de l iteration, DirNameIter = "<< DirNameIter);
365     // D.2. Recherche d'un nom local pour l'iteration de depart dans le futur repertoire du cas
366     char* nomDirIter = aGenImpl->CreateDirNameIter(NomDir, 0);
367     MESSAGE ("SetDirName : nom futur pour le repertoire de l iteration, nomDirIter = "<< nomDirIter);
368     // D.3. Creation du futur repertoire local pour l'iteration de depart
369     std::string nomDirIterTotal;
370     nomDirIterTotal = std::string(NomDir) + "/" + std::string(nomDirIter);
371 #ifndef WIN32
372     if (mkdir(nomDirIterTotal.c_str(), S_IRWXU|S_IRGRP|S_IXGRP) != 0)
373 #else
374     if (_mkdir(nomDirIterTotal.c_str()) != 0)
375 #endif
376     {
377       MESSAGE ("nomDirIterTotal : " << nomDirIterTotal);
378       SALOME::ExceptionStruct es;
379       es.type = SALOME::BAD_PARAM;
380       std::string text = "The directory for the starting iteration cannot be created.";
381       es.text = CORBA::string_dup(text.c_str());
382       throw SALOME::SALOME_Exception(es);
383     }
384     // D.4. Deplacement du contenu du repertoire
385     std::string oldnomDirIterTotal;
386     oldnomDirIterTotal = std::string(oldrep) + "/" + std::string(DirNameIter);
387     std::string commande = "mv " + std::string(oldnomDirIterTotal) + "/*" + " " + std::string(nomDirIterTotal);
388     codret = system(commande.c_str());
389     if (codret != 0)
390     {
391       SALOME::ExceptionStruct es;
392       es.type = SALOME::BAD_PARAM;
393       std::string text = "The starting point for the case cannot be moved into the new directory.";
394       es.text = CORBA::string_dup(text.c_str());
395       throw SALOME::SALOME_Exception(es);
396     }
397     commande = "rm -rf " + std::string(oldnomDirIterTotal);
398     codret = system(commande.c_str());
399     if (codret != 0)
400     {
401       SALOME::ExceptionStruct es;
402       es.type = SALOME::BAD_PARAM;
403       std::string text = "The starting point for the case cannot be deleted.";
404       es.text = CORBA::string_dup(text.c_str());
405       throw SALOME::SALOME_Exception(es);
406     }
407     // D.5. Memorisation du nom du repertoire de l'iteration
408     Iter0->SetDirNameLoc(nomDirIter);
409   }
410 }
411 //=============================================================================
412 char* HOMARD_Cas_i::GetDirName()
413 {
414   ASSERT(myHomardCas);
415   return CORBA::string_dup(myHomardCas->GetDirName().c_str());
416 }
417 //=============================================================================
418 void HOMARD_Cas_i::SetBoundingBox(const SMESHHOMARD::extrema& LesExtrema)
419 {
420   ASSERT(myHomardCas);
421   std::vector<double> VExtrema;
422   ASSERT(LesExtrema.length() == 10);
423   VExtrema.resize(LesExtrema.length());
424   for (int i = 0; i < (int)LesExtrema.length(); i++) {
425     VExtrema[i] = LesExtrema[i];
426   }
427   myHomardCas->SetBoundingBox(VExtrema);
428 }
429 //=============================================================================
430 SMESHHOMARD::extrema* HOMARD_Cas_i::GetBoundingBox()
431 {
432   ASSERT(myHomardCas);
433   SMESHHOMARD::extrema_var aResult = new SMESHHOMARD::extrema();
434   std::vector<double> LesExtremes = myHomardCas->GetBoundingBox();
435   ASSERT(LesExtremes.size() == 10);
436   aResult->length(10);
437   for (unsigned int i = 0; i < LesExtremes.size(); i++) {
438     aResult[i] = LesExtremes[i];
439   }
440   return aResult._retn();
441 }
442
443 //=============================================================================
444 void HOMARD_Cas_i::AddGroup(const char* Group)
445 {
446   ASSERT(myHomardCas);
447   myHomardCas->AddGroup(Group);
448 }
449 //=============================================================================
450 void HOMARD_Cas_i::SetGroups(const SMESHHOMARD::ListGroupType& ListGroup)
451 {
452   ASSERT(myHomardCas);
453   std::list<std::string> ListString;
454   for (unsigned int i = 0; i < ListGroup.length(); i++)
455   {
456     ListString.push_back(std::string(ListGroup[i]));
457   }
458   myHomardCas->SetGroups(ListString);
459 }
460 //=============================================================================
461 SMESHHOMARD::ListGroupType* HOMARD_Cas_i::GetGroups()
462 {
463   ASSERT(myHomardCas);
464   const std::list<std::string>& ListString = myHomardCas->GetGroups();
465   SMESHHOMARD::ListGroupType_var aResult = new SMESHHOMARD::ListGroupType();
466   aResult->length(ListString.size());
467   std::list<std::string>::const_iterator it;
468   int i = 0;
469   for (it = ListString.begin(); it != ListString.end(); it++) {
470     aResult[i++] = CORBA::string_dup((*it).c_str());
471   }
472   return aResult._retn();
473 }
474
475 //=============================================================================
476 void HOMARD_Cas_i::AddBoundary(const char* BoundaryName)
477 {
478   MESSAGE ("HOMARD_Cas_i::AddBoundary : BoundaryName = "<< BoundaryName);
479   const char * Group = "";
480   AddBoundaryGroup(BoundaryName, Group);
481 }
482 //=============================================================================
483 void HOMARD_Cas_i::AddBoundaryGroup(const char* BoundaryName, const char* Group)
484 {
485   MESSAGE ("HOMARD_Cas_i::AddBoundaryGroup : BoundaryName = "<< BoundaryName << ", Group = " << Group);
486   ASSERT(myHomardCas);
487   // A. Préalables
488   // A.1. Caractéristiques de la frontière Ã  ajouter
489   SMESHHOMARD::HOMARD_Boundary_ptr myBoundary = _gen_i->GetBoundary(BoundaryName);
490   ASSERT(!CORBA::is_nil(myBoundary));
491   int BoundaryType = myBoundary->GetType();
492   MESSAGE (". BoundaryType = " << BoundaryType);
493   // A.2. La liste des frontiere+groupes
494   const std::list<std::string>& ListBoundaryGroup = myHomardCas->GetBoundaryGroup();
495   std::list<std::string>::const_iterator it;
496   // B. Controles
497   const char * boun;
498   int erreur = 0;
499   while (erreur == 0)
500   {
501     // B.1. Si on ajoute une frontière CAO, elle doit Ãªtre la seule frontière
502     if (BoundaryType == -1)
503     {
504       for (it = ListBoundaryGroup.begin(); it != ListBoundaryGroup.end(); it++)
505       {
506         boun = (*it).c_str();
507         MESSAGE ("..  Frontiere enregistrée : "<< boun);
508         if (*it != BoundaryName)
509         { erreur = 1;
510           break; }
511         // On saute le nom du groupe
512         it++;
513       }
514     }
515     if (erreur != 0) { break; }
516     // B.2. Si on ajoute une frontière non CAO, il ne doit pas y avoir de frontière CAO
517     if (BoundaryType != -1)
518     {
519       for (it = ListBoundaryGroup.begin(); it != ListBoundaryGroup.end(); it++)
520       {
521         boun = (*it).c_str();
522         MESSAGE ("..  Frontiere enregistrée : "<< boun);
523         SMESHHOMARD::HOMARD_Boundary_ptr myBoundary_0 = _gen_i->GetBoundary(boun);
524         int BoundaryType_0 = myBoundary_0->GetType();
525         MESSAGE (".. BoundaryType_0 = " << BoundaryType_0);
526         if (BoundaryType_0 == -1)
527         { erreur = 2;
528           break; }
529         // On saute le nom du groupe
530         it++;
531       }
532       if (erreur != 0) { break; }
533     }
534     // B.3. Si on ajoute une frontière discrète, il ne doit pas y avoir d'autre frontière discrète
535     if (BoundaryType == 0)
536     {
537       for (it = ListBoundaryGroup.begin(); it != ListBoundaryGroup.end(); it++)
538       {
539         boun = (*it).c_str();
540         MESSAGE ("..  Frontiere enregistrée : "<< boun);
541         if (boun != BoundaryName)
542         {
543           SMESHHOMARD::HOMARD_Boundary_ptr myBoundary_0 = _gen_i->GetBoundary(boun);
544           int BoundaryType_0 = myBoundary_0->GetType();
545           MESSAGE (".. BoundaryType_0 = " << BoundaryType_0);
546           if (BoundaryType_0 == 0)
547           { erreur = 3;
548             break; }
549         }
550         // On saute le nom du groupe
551         it++;
552       }
553       if (erreur != 0) { break; }
554     }
555     // B.4. Pour une nouvelle frontiere, publication dans l'arbre d'etudes sous le cas
556     for (it = ListBoundaryGroup.begin(); it != ListBoundaryGroup.end(); it++) {
557       MESSAGE ("..  Frontiere : "<< *it);
558       // On saute le nom du groupe
559       it++;
560     }
561     // B.5. Le groupe est-il deja enregistre pour une frontiere de ce cas ?
562     for (it = ListBoundaryGroup.begin(); it != ListBoundaryGroup.end(); it++) {
563       boun = (*it).c_str();
564       it++;
565       MESSAGE ("..  Groupe enregistré : "<< *it);
566       if (*it == Group) {
567         erreur = 5;
568         break;
569       }
570     }
571     if (erreur != 0) { break; }
572     //
573     break;
574   }
575   // F. Si aucune erreur, enregistrement du couple (frontiere,groupe) dans la reference du cas
576   //    Sinon, arrêt
577   if (erreur == 0) {
578     myHomardCas->AddBoundaryGroup(BoundaryName, Group);
579   }
580   else {
581     std::stringstream ss;
582     ss << erreur;
583     std::string str = ss.str();
584     std::string texte;
585     texte = "Erreur numéro " + str + " pour la frontière Ã  enregistrer : " + std::string(BoundaryName);
586     if (erreur == 1) { texte += "\nIl existe déjà la frontière "; }
587     else if (erreur == 2) { texte += "\nIl existe déjà la frontière CAO "; }
588     else if (erreur == 3) { texte += "\nIl existe déjà une frontière discrète : "; }
589     else if (erreur == 5) { texte += "\nLe groupe " + std::string(Group) + " est déjà enregistré pour la frontière "; }
590     texte += std::string(boun);
591     //
592     SALOME::ExceptionStruct es;
593     es.type = SALOME::BAD_PARAM;
594     
595     if (SALOME::VerbosityActivated())
596       texte += "\nInvalid AddBoundaryGroup";
597
598     INFOS(texte);
599     es.text = CORBA::string_dup(texte.c_str());
600     throw SALOME::SALOME_Exception(es);
601   }
602 }
603 //=============================================================================
604 SMESHHOMARD::ListBoundaryGroupType* HOMARD_Cas_i::GetBoundaryGroup()
605 {
606   MESSAGE ("GetBoundaryGroup");
607   ASSERT(myHomardCas);
608   const std::list<std::string>& ListBoundaryGroup = myHomardCas->GetBoundaryGroup();
609   SMESHHOMARD::ListBoundaryGroupType_var aResult = new SMESHHOMARD::ListBoundaryGroupType();
610   aResult->length(ListBoundaryGroup.size());
611   std::list<std::string>::const_iterator it;
612   int i = 0;
613   for (it = ListBoundaryGroup.begin(); it != ListBoundaryGroup.end(); it++)
614   {
615     aResult[i++] = CORBA::string_dup((*it).c_str());
616   }
617   return aResult._retn();
618 }
619 //=============================================================================
620 void HOMARD_Cas_i::SupprBoundaryGroup()
621 {
622   MESSAGE ("SupprBoundaryGroup");
623   ASSERT(myHomardCas);
624   myHomardCas->SupprBoundaryGroup();
625 }
626
627 void HOMARD_Cas_i::AddIteration(const char* NomIteration)
628 {
629   ASSERT(myHomardCas);
630   myHomardCas->AddIteration(NomIteration);
631 }
632
633 //=============================================================================
634 /*!
635  *  standard constructor
636  */
637 //=============================================================================
638 HOMARD_Iteration_i::HOMARD_Iteration_i()
639 {
640   MESSAGE("Default constructor, not for use");
641   ASSERT(0);
642 }
643 //=============================================================================
644 /*!
645  *  standard constructor
646  */
647 //=============================================================================
648 HOMARD_Iteration_i::HOMARD_Iteration_i(SMESHHOMARD::HOMARD_Gen_var engine)
649 {
650   MESSAGE("constructor");
651   _gen_i = engine;
652   myHomardIteration = new SMESHHOMARDImpl::HOMARD_Iteration();
653   ASSERT(myHomardIteration);
654 }
655 //=============================================================================
656 /*!
657  *  standard destructor
658  */
659 //=============================================================================
660 HOMARD_Iteration_i::~HOMARD_Iteration_i()
661 {
662 }
663 //=============================================================================
664 void HOMARD_Iteration_i::SetName(const char* Name)
665 {
666   ASSERT(myHomardIteration);
667   myHomardIteration->SetName(Name);
668 }
669 //=============================================================================
670 char* HOMARD_Iteration_i::GetName()
671 {
672   ASSERT(myHomardIteration);
673   return CORBA::string_dup(myHomardIteration->GetName().c_str());
674 }
675 //=============================================================================
676 void HOMARD_Iteration_i::SetDirNameLoc(const char* NomDir)
677 {
678   ASSERT(myHomardIteration);
679   myHomardIteration->SetDirNameLoc(NomDir);
680 }
681 //=============================================================================
682 char* HOMARD_Iteration_i::GetDirNameLoc()
683 {
684   ASSERT(myHomardIteration);
685   return CORBA::string_dup(myHomardIteration->GetDirNameLoc().c_str());
686 }
687 //=============================================================================
688 char* HOMARD_Iteration_i::GetDirName()
689 {
690   ASSERT(myHomardIteration);
691   SMESHHOMARD::HOMARD_Cas_ptr caseiter = _gen_i->GetCase();
692   std::string dirnamecase = caseiter->GetDirName();
693   std::string dirname = dirnamecase + "/" +  GetDirNameLoc();
694   return CORBA::string_dup(dirname.c_str());
695 }
696 //=============================================================================
697 void HOMARD_Iteration_i::SetNumber(CORBA::Long NumIter)
698 {
699   ASSERT(myHomardIteration);
700   myHomardIteration->SetNumber(NumIter);
701 }
702 //=============================================================================
703 CORBA::Long HOMARD_Iteration_i::GetNumber()
704 {
705   ASSERT(myHomardIteration);
706   return myHomardIteration->GetNumber();
707 }
708 //=============================================================================
709 void HOMARD_Iteration_i::SetState(CORBA::Long Etat)
710 {
711   ASSERT(myHomardIteration);
712   myHomardIteration->SetState(Etat);
713 }
714 //=============================================================================
715 CORBA::Long HOMARD_Iteration_i::GetState()
716 {
717   ASSERT(myHomardIteration);
718   return myHomardIteration->GetState();
719 }
720 //=============================================================================
721 void HOMARD_Iteration_i::SetMeshName(const char* NomMesh)
722 {
723   ASSERT(myHomardIteration);
724   myHomardIteration->SetMeshName(NomMesh);
725 }
726 //=============================================================================
727 char* HOMARD_Iteration_i::GetMeshName()
728 {
729   ASSERT(myHomardIteration);
730   return CORBA::string_dup(myHomardIteration->GetMeshName().c_str());
731 }
732 //=============================================================================
733 void HOMARD_Iteration_i::SetMeshFile(const char* MeshFile)
734 {
735   ASSERT(myHomardIteration);
736   myHomardIteration->SetMeshFile(MeshFile);
737 }
738 //=============================================================================
739 char* HOMARD_Iteration_i::GetMeshFile()
740 {
741   ASSERT(myHomardIteration);
742   return CORBA::string_dup(myHomardIteration->GetMeshFile().c_str());
743 }
744 //=============================================================================
745 void HOMARD_Iteration_i::SetLogFile(const char* LogFile)
746 {
747   ASSERT(myHomardIteration);
748   myHomardIteration->SetLogFile(LogFile);
749 }
750 //=============================================================================
751 char* HOMARD_Iteration_i::GetLogFile()
752 {
753   ASSERT(myHomardIteration);
754   return CORBA::string_dup(myHomardIteration->GetLogFile().c_str());
755 }
756 //=============================================================================
757 void HOMARD_Iteration_i::SetFileInfo(const char* FileInfo)
758 {
759   ASSERT(myHomardIteration);
760   myHomardIteration->SetFileInfo(FileInfo);
761 }
762 //=============================================================================
763 char* HOMARD_Iteration_i::GetFileInfo()
764 {
765   ASSERT(myHomardIteration);
766   return CORBA::string_dup(myHomardIteration->GetFileInfo().c_str());
767 }
768 //=============================================================================
769 void HOMARD_Iteration_i::SetInfoCompute(CORBA::Long MessInfo)
770 {
771   ASSERT(myHomardIteration);
772   myHomardIteration->SetInfoCompute(MessInfo);
773 }
774 //=============================================================================
775 CORBA::Long HOMARD_Iteration_i::GetInfoCompute()
776 {
777   ASSERT(myHomardIteration);
778   return myHomardIteration->GetInfoCompute();
779 }
780
781 //=============================================================================
782 /*!
783  *  standard constructor
784  */
785 //=============================================================================
786 HOMARD_Gen_i::HOMARD_Gen_i() : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA()),
787                                myIteration0(NULL),
788                                myIteration1(NULL),
789                                _ConfType(0),
790                                _KeepMedOUT(true),
791                                _PublishMeshOUT(false),
792                                _KeepWorkingFiles(false),
793                                _LogInFile(false),
794                                _RemoveLogOnSuccess(false),
795                                _VerboseLevel(0),
796                                _MeshNameOUT(""),
797                                _MeshFileOUT(""),
798                                _LogFile(""),
799                                _CaseOnMedFile(true),
800                                _SmeshMesh(SMESH::SMESH_Mesh::_nil()),
801                                _TmpMeshFile("")
802 {
803   MESSAGE("constructor de HOMARD_Gen_i");
804   myHomard = new SMESHHOMARDImpl::HOMARD_Gen;
805 }
806
807 //=============================================================================
808 /*!
809  *  standard destructor
810  */
811 //=============================================================================
812 HOMARD_Gen_i::~HOMARD_Gen_i()
813 {
814   MESSAGE ("HOMARD_Gen_i::~HOMARD_Gen_i()");
815 }
816
817 //=============================================================================
818 //=============================================================================
819 // Destruction des structures identifiees par leurs noms
820 //=============================================================================
821 //=============================================================================
822 CORBA::Long HOMARD_Gen_i::DeleteBoundary(const char* BoundaryName)
823 {
824   MESSAGE ("DeleteBoundary : BoundaryName = " << BoundaryName);
825   SMESHHOMARD::HOMARD_Boundary_var myBoundary = _mesBoundarys[BoundaryName];
826   if (CORBA::is_nil(myBoundary)) {
827     SALOME::ExceptionStruct es;
828     es.type = SALOME::BAD_PARAM;
829     es.text = "Invalid boundary";
830     throw SALOME::SALOME_Exception(es);
831   }
832
833   // Boundaries should be deleted only after all cases deletion!!!
834
835   // comme on a un _var comme pointeur CORBA, on ne se preoccupe pas du delete
836   _mesBoundarys.erase(BoundaryName);
837
838   return 0;
839 }
840
841 //=============================================================================
842 CORBA::Long HOMARD_Gen_i::DeleteIteration(int numIter)
843 {
844   MESSAGE ("DeleteIteration : numIter = " << numIter);
845
846   if (numIter == 0) {
847     if (myIteration0 != NULL) {
848       delete myIteration0;
849       myIteration0 = NULL;
850     }
851   }
852   else {
853     if (myIteration1 != NULL) {
854       // Invalide Iteration
855       if (myIteration1->GetState() > 0) {
856         myIteration1->SetState(1);
857         if (!_KeepWorkingFiles) {
858           std::string nomDir = myIteration1->GetDirName();
859           std::string commande = "rm -rf " + nomDir;
860           if (numIter > 0 && !_KeepMedOUT) {
861             // Remove associated mesh file
862             std::string nomFichier = myIteration1->GetMeshFile();
863             commande = commande + ";rm -rf " + nomFichier;
864           }
865           MESSAGE ("commande = " << commande);
866           if ((system(commande.c_str())) != 0) {
867             SALOME::ExceptionStruct es;
868             es.type = SALOME::BAD_PARAM;
869             es.text = "The directory for the calculation cannot be cleared.";
870             throw SALOME::SALOME_Exception(es);
871           }
872         }
873       }
874
875       delete myIteration1;
876       myIteration1 = NULL;
877     }
878   }
879
880   return 0;
881 }
882
883 //=============================================================================
884 //=============================================================================
885 // Invalidation des structures identifiees par leurs noms
886 //=============================================================================
887 //=============================================================================
888 void HOMARD_Gen_i::InvalideBoundary(const char* BoundaryName)
889 {
890   MESSAGE("InvalideBoundary : BoundaryName = " << BoundaryName);
891   SMESHHOMARD::HOMARD_Boundary_var myBoundary = _mesBoundarys[BoundaryName];
892   if (CORBA::is_nil(myBoundary)) {
893     SALOME::ExceptionStruct es;
894     es.type = SALOME::BAD_PARAM;
895     es.text = "Invalid boundary";
896     throw SALOME::SALOME_Exception(es);
897   }
898   else {
899     SALOME::ExceptionStruct es;
900     es.type = SALOME::BAD_PARAM;
901     es.text = "No change is allowed in a boundary. Ask for evolution.";
902     throw SALOME::SALOME_Exception(es);
903   }
904 }
905
906 //=============================================================================
907 //=============================================================================
908 // Association de lien entre des structures identifiees par leurs noms
909 //=============================================================================
910 //=============================================================================
911 void HOMARD_Gen_i::AssociateCaseIter(int numIter, const char* labelIter)
912 {
913   MESSAGE("AssociateCaseIter : " << numIter << ", "  << labelIter);
914
915   if (CORBA::is_nil(myCase)) {
916     SALOME::ExceptionStruct es;
917     es.type = SALOME::BAD_PARAM;
918     es.text = "Invalid case";
919     throw SALOME::SALOME_Exception(es);
920   }
921
922   if (numIter == 0) {
923     if (myIteration0 == NULL) {
924       SALOME::ExceptionStruct es;
925       es.type = SALOME::BAD_PARAM;
926       es.text = "Invalid iteration";
927       throw SALOME::SALOME_Exception(es);
928     }
929
930     HOMARD_Cas_i* aCaseImpl = SMESH::DownCast<HOMARD_Cas_i*>(myCase);
931     aCaseImpl->AddIteration(myIteration0->GetName());
932   }
933   else {
934     if (myIteration1 == NULL) {
935       SALOME::ExceptionStruct es;
936       es.type = SALOME::BAD_PARAM;
937       es.text = "Invalid iteration";
938       throw SALOME::SALOME_Exception(es);
939     }
940
941     HOMARD_Cas_i* aCaseImpl = SMESH::DownCast<HOMARD_Cas_i*>(myCase);
942     aCaseImpl->AddIteration(myIteration1->GetName());
943   }
944 }
945
946 //=============================================================================
947 //=============================================================================
948 // Recuperation des listes
949 //=============================================================================
950 //=============================================================================
951 SMESHHOMARD::listeBoundarys* HOMARD_Gen_i::GetAllBoundarysName()
952 {
953   MESSAGE("GetAllBoundarysName");
954
955   SMESHHOMARD::listeBoundarys_var ret = new SMESHHOMARD::listeBoundarys;
956   ret->length(_mesBoundarys.size());
957   std::map<std::string, SMESHHOMARD::HOMARD_Boundary_var>::const_iterator it;
958   int i = 0;
959   for (it = _mesBoundarys.begin();
960        it != _mesBoundarys.end(); it++) {
961     ret[i++] = CORBA::string_dup((*it).first.c_str());
962   }
963
964   return ret._retn();
965 }
966
967 //=============================================================================
968 //=============================================================================
969 // Recuperation des structures identifiees par leurs noms
970 //=============================================================================
971 //=============================================================================
972 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::GetBoundary(const char* nomBoundary)
973 {
974   SMESHHOMARD::HOMARD_Boundary_var myBoundary = _mesBoundarys[nomBoundary];
975   ASSERT(!CORBA::is_nil(myBoundary));
976   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
977 }
978 //=============================================================================
979 SMESHHOMARD::HOMARD_Cas_ptr HOMARD_Gen_i::GetCase()
980 {
981   ASSERT(!CORBA::is_nil(myCase));
982   return SMESHHOMARD::HOMARD_Cas::_duplicate(myCase);
983 }
984 //=============================================================================
985 HOMARD_Iteration_i* HOMARD_Gen_i::GetIteration(CORBA::Long numIter)
986 {
987   if (numIter == 0) {
988     ASSERT(myIteration0);
989     return myIteration0;
990   }
991
992   ASSERT(myIteration1);
993   return myIteration1;
994 }
995
996 //=============================================================================
997 //=============================================================================
998 // Nouvelles structures
999 //=============================================================================
1000 //=============================================================================
1001 SMESHHOMARD::HOMARD_Cas_ptr HOMARD_Gen_i::newCase()
1002 {
1003   SMESHHOMARD::HOMARD_Gen_var engine = POA_SMESHHOMARD::HOMARD_Gen::_this();
1004   HOMARD_Cas_i* aServant = new HOMARD_Cas_i(engine);
1005   SMESHHOMARD::HOMARD_Cas_var aCase = SMESHHOMARD::HOMARD_Cas::_narrow(aServant->_this());
1006   return aCase._retn();
1007 }
1008 //=============================================================================
1009 HOMARD_Iteration_i* HOMARD_Gen_i::newIteration()
1010 {
1011   SMESHHOMARD::HOMARD_Gen_var engine = POA_SMESHHOMARD::HOMARD_Gen::_this();
1012   HOMARD_Iteration_i* aServant = new HOMARD_Iteration_i(engine);
1013   return aServant;
1014 }
1015 //=============================================================================
1016 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::newBoundary()
1017 {
1018   SMESHHOMARD::HOMARD_Gen_var engine = POA_SMESHHOMARD::HOMARD_Gen::_this();
1019   HOMARD_Boundary_i* aServant = new HOMARD_Boundary_i(engine);
1020   SMESHHOMARD::HOMARD_Boundary_var aBoundary =
1021     SMESHHOMARD::HOMARD_Boundary::_narrow(aServant->_this());
1022   return aBoundary._retn();
1023 }
1024
1025 //=============================================================================
1026 // Creation of a case
1027 // MeshName : name of the mesh
1028 // smeshMesh : correspondent mesh
1029 // theWorkingDir : path to working directory
1030 //=============================================================================
1031 SMESHHOMARD::HOMARD_Cas_ptr HOMARD_Gen_i::CreateCaseOnMesh (const char* MeshName,
1032                                                             SMESH::SMESH_Mesh_ptr smeshMesh,
1033                                                             const char* theWorkingDir)
1034 {
1035   INFOS("CreateCaseOnMesh");
1036
1037   // A. Controles
1038   // A.1. Controle du nom :
1039   if (!myCase->_is_nil()) {
1040     DeleteCase();
1041   }
1042
1043   // A.2. Controle du objet maillage
1044   if (CORBA::is_nil(smeshMesh)) {
1045     SALOME::ExceptionStruct es;
1046     es.type = SALOME::BAD_PARAM;
1047     es.text = "The mesh object is null.";
1048     throw SALOME::SALOME_Exception(es);
1049   }
1050   MESSAGE("CreateCaseOnMesh : smeshMesh is not nil");
1051
1052   // A.3. Write mesh object in a temporary file in the working directory
1053   std::string aTmpMeshFile = theWorkingDir;
1054   aTmpMeshFile = theWorkingDir;
1055   aTmpMeshFile += std::string("/") + std::string(MeshName) + "_saved_from_SMESH";
1056   _TmpMeshFile = aTmpMeshFile + ".med";
1057   SMESH_File aFile (_TmpMeshFile, false);
1058   for (int ii = 1; aFile.exists(); ii++) {
1059     _TmpMeshFile = aTmpMeshFile + std::string("_") + std::to_string(ii) + ".med";
1060     aFile = SMESH_File(_TmpMeshFile, false);
1061   }
1062   const char* MeshFile = _TmpMeshFile.c_str();
1063   bool toOverwrite = true;
1064   bool toFindOutDim = true;
1065
1066   // Prevent dump of ExportMED
1067   {
1068     SMESH::TPythonDump pDump; // do not delete this line of code
1069     smeshMesh->ExportMED(MeshFile, false, -1, toOverwrite, toFindOutDim);
1070   }
1071
1072   // A.4. Controle du fichier du maillage
1073   med_idt medIdt = MEDfileOpen(MeshFile, MED_ACC_RDONLY);
1074   bool existeMeshFile = medIdt >= 0;
1075   if (existeMeshFile) MEDfileClose(medIdt);
1076   MESSAGE("CreateCaseOnMesh : existeMeshFile = " << existeMeshFile);
1077   if (!existeMeshFile) {
1078     SALOME::ExceptionStruct es;
1079     es.type = SALOME::BAD_PARAM;
1080     es.text = "The mesh file does not exist.";
1081     throw SALOME::SALOME_Exception(es);
1082   }
1083
1084   // B. Creation de l'objet cas
1085   myCase = newCase();
1086   _CaseOnMedFile = false;
1087   _SmeshMesh = SMESH::SMESH_Mesh::_duplicate(smeshMesh);
1088
1089   // C. Caracteristiques du maillage
1090   if (existeMeshFile) {
1091     // Les valeurs extremes des coordonnées
1092     //MESSAGE ("CreateCaseOnMesh : Les valeurs extremes des coordonnées");
1093     std::vector<double> LesExtremes = GetBoundingBoxInMedFile(MeshFile);
1094     SMESHHOMARD::extrema_var aSeq = new SMESHHOMARD::extrema();
1095     if (LesExtremes.size() != 10) { return 0; }
1096     aSeq->length(10);
1097     for (unsigned int i = 0; i < LesExtremes.size(); i++)
1098       aSeq[i] = LesExtremes[i];
1099     myCase->SetBoundingBox(aSeq);
1100     // Les groupes
1101     //MESSAGE ("CreateCaseOnMesh : Les groupes");
1102     std::set<std::string> LesGroupes = GetListeGroupesInMedFile(MeshFile);
1103     SMESHHOMARD::ListGroupType_var aSeqGroupe = new SMESHHOMARD::ListGroupType;
1104     aSeqGroupe->length(LesGroupes.size());
1105     std::set<std::string>::const_iterator it;
1106     int i = 0;
1107     for (it = LesGroupes.begin(); it != LesGroupes.end(); it++)
1108       aSeqGroupe[i++] = (*it).c_str();
1109     myCase->SetGroups(aSeqGroupe);
1110   }
1111
1112   // D. L'iteration initiale du cas
1113   MESSAGE ("CreateCaseOnMesh : iteration initiale du cas");
1114   // D.1. Recherche d'un nom : par defaut, on prend le nom du maillage correspondant.
1115   // Si ce nom d'iteration existe deja, on incremente avec 0, 1, 2, etc.
1116   MESSAGE("CreateCaseOnMesh : ==> NomIteration = " << MeshName);
1117
1118   // D.2. Creation de l'iteration 0
1119   myIteration0 = newIteration();
1120   myIteration0->SetName(MeshName);
1121   AssociateCaseIter(0, "IterationHomard");
1122
1123   // D.4. Maillage correspondant
1124   if (existeMeshFile) {
1125     myIteration0->SetMeshFile(MeshFile);
1126   }
1127   myIteration0->SetMeshName(MeshName);
1128   myIteration0->SetNumber(0);
1129   myIteration0->SetState(0);
1130
1131   // Only after full initialization of Iteration0
1132   myCase->SetDirName(theWorkingDir);
1133
1134   return SMESHHOMARD::HOMARD_Cas::_duplicate(myCase);
1135 }
1136
1137 //=============================================================================
1138 // Creation of a case
1139 // MeshName : name of the mesh
1140 // MeshFile : med file
1141 // theWorkingDir : path to working directory
1142 //=============================================================================
1143 SMESHHOMARD::HOMARD_Cas_ptr HOMARD_Gen_i::CreateCase(const char* MeshName,
1144                                                      const char* MeshFile,
1145                                                      const char* theWorkingDir)
1146 {
1147   INFOS("CreateCase : MeshName = " << MeshName << ", MeshFile = " << MeshFile);
1148
1149   // A. Controles
1150   // A.1. Controle du nom :
1151   if (!myCase->_is_nil()) {
1152     DeleteCase();
1153   }
1154
1155   // A.3. Controle du fichier du maillage
1156   med_idt medIdt = MEDfileOpen(MeshFile, MED_ACC_RDONLY);
1157   bool existeMeshFile = medIdt >= 0;
1158   if (existeMeshFile) MEDfileClose(medIdt);
1159   MESSAGE("CreateCase : existeMeshFile = " << existeMeshFile);
1160   if (!existeMeshFile) {
1161     SALOME::ExceptionStruct es;
1162     es.type = SALOME::BAD_PARAM;
1163     es.text = "The mesh file does not exist.";
1164     throw SALOME::SALOME_Exception(es);
1165   }
1166
1167   // B. Creation de l'objet cas
1168   myCase = newCase();
1169   _CaseOnMedFile = true;
1170
1171   // C. Caracteristiques du maillage
1172   if (existeMeshFile) {
1173     // Les valeurs extremes des coordonnées
1174     //MESSAGE ("CreateCase : Les valeurs extremes des coordonnées");
1175     std::vector<double> LesExtremes = GetBoundingBoxInMedFile(MeshFile);
1176     SMESHHOMARD::extrema_var aSeq = new SMESHHOMARD::extrema();
1177     if (LesExtremes.size() != 10) { return 0; }
1178     aSeq->length(10);
1179     for (unsigned int i = 0; i < LesExtremes.size(); i++)
1180       aSeq[i] = LesExtremes[i];
1181     myCase->SetBoundingBox(aSeq);
1182     // Les groupes
1183     //MESSAGE ("CreateCase : Les groupes");
1184     std::set<std::string> LesGroupes = GetListeGroupesInMedFile(MeshFile);
1185     SMESHHOMARD::ListGroupType_var aSeqGroupe = new SMESHHOMARD::ListGroupType;
1186     aSeqGroupe->length(LesGroupes.size());
1187     std::set<std::string>::const_iterator it;
1188     int i = 0;
1189     for (it = LesGroupes.begin(); it != LesGroupes.end(); it++)
1190       aSeqGroupe[i++] = (*it).c_str();
1191     myCase->SetGroups(aSeqGroupe);
1192   }
1193
1194   // D. L'iteration initiale du cas
1195   MESSAGE ("CreateCase : iteration initiale du cas");
1196   // D.1. Recherche d'un nom : par defaut, on prend le nom du maillage correspondant.
1197   // Si ce nom d'iteration existe deja, on incremente avec 0, 1, 2, etc.
1198   MESSAGE("CreateCas : ==> NomIteration = " << MeshName);
1199
1200   // D.2. Creation de l'iteration
1201   myIteration0 = newIteration();
1202   myIteration0->SetName(MeshName);
1203   AssociateCaseIter(0, "IterationHomard");
1204
1205   // D.4. Maillage correspondant
1206   if (existeMeshFile) {
1207     myIteration0->SetMeshFile(MeshFile);
1208   }
1209   myIteration0->SetMeshName(MeshName);
1210   myIteration0->SetNumber(0);
1211   myIteration0->SetState(0);
1212
1213   // Only after full initialization of Iteration0
1214   myCase->SetDirName(theWorkingDir);
1215
1216   return SMESHHOMARD::HOMARD_Cas::_duplicate(myCase);
1217 }
1218
1219 //=============================================================================
1220 // Create Iteration1
1221 //=============================================================================
1222 HOMARD_Iteration_i* HOMARD_Gen_i::CreateIteration()
1223 {
1224   if (myIteration0 == NULL) {
1225     SALOME::ExceptionStruct es;
1226     es.type = SALOME::BAD_PARAM;
1227     es.text = "The parent iteration is not defined.";
1228     throw SALOME::SALOME_Exception(es);
1229   }
1230
1231   if (CORBA::is_nil(myCase)) {
1232     SALOME::ExceptionStruct es;
1233     es.type = SALOME::BAD_PARAM;
1234     es.text = "Invalid case context";
1235     throw SALOME::SALOME_Exception(es);
1236   }
1237   const char* nomDirCase = myCase->GetDirName();
1238
1239   if (myIteration1 != NULL) {
1240     DeleteIteration(1);
1241   }
1242
1243   myIteration1 = newIteration();
1244   if (myIteration1 == NULL) {
1245     SALOME::ExceptionStruct es;
1246     es.type = SALOME::BAD_PARAM;
1247     es.text = "Unable to create the iteration 1";
1248     throw SALOME::SALOME_Exception(es);
1249   }
1250
1251   // Nom de l'iteration et du maillage
1252   myIteration1->SetName("Iter_1");
1253   myIteration1->SetMeshName("Iter_1");
1254   myIteration1->SetState(1);
1255   myIteration1->SetNumber(1);
1256
1257   int nbitercase = 1;
1258   char* nomDirIter = CreateDirNameIter(nomDirCase, nbitercase);
1259   myIteration1->SetDirNameLoc(nomDirIter);
1260
1261   // Le nom du fichier du maillage MED est indice par le nombre d'iterations du cas.
1262   // Si on a une chaine unique depuis le depart, ce nombre est le meme que le
1263   // numero d'iteration dans la sucession : maill.01.med, maill.02.med, etc... C'est la
1264   // situation la plus frequente.
1265   // Si on a plusieurs branches, donc des iterations du meme niveau d'adaptation, utiliser
1266   // le nombre d'iterations du cas permet d'eviter les collisions.
1267   int jaux;
1268   if      (nbitercase <    100) { jaux = 2; }
1269   else if (nbitercase <   1000) { jaux = 3; }
1270   else if (nbitercase <  10000) { jaux = 4; }
1271   else if (nbitercase < 100000) { jaux = 5; }
1272   else                          { jaux = 9; }
1273   std::ostringstream iaux;
1274   iaux << std::setw(jaux) << std::setfill('0') << nbitercase;
1275   std::stringstream MeshFile;
1276   MeshFile << nomDirCase << "/maill." << iaux.str() << ".med";
1277   myIteration1->SetMeshFile(MeshFile.str().c_str());
1278
1279   // Association avec le cas
1280   std::string nomIterParent = myIteration0->GetName();
1281   std::string label = "IterationHomard_" + nomIterParent;
1282   AssociateCaseIter(1, label.c_str());
1283
1284   return myIteration1;
1285 }
1286 //=============================================================================
1287 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundary(const char* BoundaryName,
1288                                                               CORBA::Long BoundaryType)
1289 {
1290   MESSAGE ("CreateBoundary : BoundaryName  = " << BoundaryName <<
1291            ", BoundaryType = " << BoundaryType);
1292
1293   // Controle du nom :
1294   if ((_mesBoundarys).find(BoundaryName) != (_mesBoundarys).end()) {
1295     MESSAGE ("CreateBoundary : la frontiere " << BoundaryName << " existe deja");
1296     SALOME::ExceptionStruct es;
1297     es.type = SALOME::BAD_PARAM;
1298     es.text = "This boundary has already been defined";
1299     throw SALOME::SALOME_Exception(es);
1300   }
1301
1302   SMESHHOMARD::HOMARD_Boundary_var myBoundary = newBoundary();
1303   myBoundary->SetName(BoundaryName);
1304   myBoundary->SetType(BoundaryType);
1305
1306   _mesBoundarys[BoundaryName] = myBoundary;
1307
1308   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1309 }
1310 //=============================================================================
1311 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundaryCAO(const char* BoundaryName, const char* CAOFile)
1312 {
1313   MESSAGE ("CreateBoundaryCAO : BoundaryName  = " << BoundaryName << ", CAOFile = " << CAOFile);
1314   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, -1);
1315   myBoundary->SetDataFile(CAOFile);
1316
1317   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1318 }
1319 //=============================================================================
1320 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundaryDi(const char* BoundaryName, const char* MeshName, const char* MeshFile)
1321 {
1322   MESSAGE ("CreateBoundaryDi : BoundaryName  = " << BoundaryName << ", MeshName = " << MeshName << ", MeshFile = " << MeshFile);
1323   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, 0);
1324   myBoundary->SetDataFile(MeshFile);
1325   myBoundary->SetMeshName(MeshName);
1326
1327   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1328 }
1329 //=============================================================================
1330 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundaryCylinder(const char* BoundaryName,
1331                                       CORBA::Double Xcentre, CORBA::Double Ycentre, CORBA::Double Zcentre,
1332                                       CORBA::Double Xaxe, CORBA::Double Yaxe, CORBA::Double Zaxe,
1333                                       CORBA::Double Rayon)
1334 {
1335   MESSAGE ("CreateBoundaryCylinder : BoundaryName  = " << BoundaryName);
1336 //
1337   SALOME::ExceptionStruct es;
1338   int error = 0;
1339   if (Rayon <= 0.0)
1340   { es.text = "The radius must be positive.";
1341     error = 1; }
1342   double daux = fabs(Xaxe) + fabs(Yaxe) + fabs(Zaxe);
1343   if (daux < 0.0000001)
1344   { es.text = "The axis must be a non 0 vector.";
1345     error = 2; }
1346   if (error != 0)
1347   {
1348     es.type = SALOME::BAD_PARAM;
1349     throw SALOME::SALOME_Exception(es);
1350     return 0;
1351   };
1352 //
1353   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, 1);
1354   myBoundary->SetCylinder(Xcentre, Ycentre, Zcentre, Xaxe, Yaxe, Zaxe, Rayon);
1355
1356   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1357 }
1358 //=============================================================================
1359 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundarySphere(const char* BoundaryName,
1360                                       CORBA::Double Xcentre, CORBA::Double Ycentre, CORBA::Double Zcentre,
1361                                       CORBA::Double Rayon)
1362 {
1363   MESSAGE ("CreateBoundarySphere : BoundaryName  = " << BoundaryName);
1364 //
1365   SALOME::ExceptionStruct es;
1366   int error = 0;
1367   if (Rayon <= 0.0)
1368   { es.text = "The radius must be positive.";
1369     error = 1; }
1370   if (error != 0)
1371   {
1372     es.type = SALOME::BAD_PARAM;
1373     throw SALOME::SALOME_Exception(es);
1374     return 0;
1375   };
1376 //
1377   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, 2);
1378   myBoundary->SetSphere(Xcentre, Ycentre, Zcentre, Rayon);
1379
1380   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1381 }
1382 //=============================================================================
1383 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundaryConeA(const char* BoundaryName,
1384                                       CORBA::Double Xaxe, CORBA::Double Yaxe, CORBA::Double Zaxe, CORBA::Double Angle,
1385                                       CORBA::Double Xcentre, CORBA::Double Ycentre, CORBA::Double Zcentre)
1386 {
1387   MESSAGE ("CreateBoundaryConeA : BoundaryName  = " << BoundaryName);
1388 //
1389   SALOME::ExceptionStruct es;
1390   int error = 0;
1391   if (Angle <= 0.0 || Angle >= 90.0)
1392   { es.text = "The angle must be included higher than 0 degree and lower than 90 degrees.";
1393     error = 1; }
1394   double daux = fabs(Xaxe) + fabs(Yaxe) + fabs(Zaxe);
1395   if (daux < 0.0000001)
1396   { es.text = "The axis must be a non 0 vector.";
1397     error = 2; }
1398   if (error != 0)
1399   {
1400     es.type = SALOME::BAD_PARAM;
1401     throw SALOME::SALOME_Exception(es);
1402     return 0;
1403   };
1404 //
1405   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, 3);
1406   myBoundary->SetConeA(Xaxe, Yaxe, Zaxe, Angle, Xcentre, Ycentre, Zcentre);
1407
1408   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1409 }
1410 //=============================================================================
1411 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundaryConeR(const char* BoundaryName,
1412                                       CORBA::Double Xcentre1, CORBA::Double Ycentre1, CORBA::Double Zcentre1, CORBA::Double Rayon1,
1413                                       CORBA::Double Xcentre2, CORBA::Double Ycentre2, CORBA::Double Zcentre2, CORBA::Double Rayon2)
1414 {
1415   MESSAGE ("CreateBoundaryConeR : BoundaryName  = " << BoundaryName);
1416 //
1417   SALOME::ExceptionStruct es;
1418   int error = 0;
1419   if (Rayon1 < 0.0 || Rayon2 < 0.0)
1420   { es.text = "The radius must be positive.";
1421     error = 1; }
1422   double daux = fabs(Rayon2-Rayon1);
1423   if (daux < 0.0000001)
1424   { es.text = "The radius must be different.";
1425     error = 2; }
1426   daux = fabs(Xcentre2-Xcentre1) + fabs(Ycentre2-Ycentre1) + fabs(Zcentre2-Zcentre1);
1427   if (daux < 0.0000001)
1428   { es.text = "The centers must be different.";
1429     error = 3; }
1430   if (error != 0)
1431   {
1432     es.type = SALOME::BAD_PARAM;
1433     throw SALOME::SALOME_Exception(es);
1434     return 0;
1435   };
1436 //
1437   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, 4);
1438   myBoundary->SetConeR(Xcentre1, Ycentre1, Zcentre1, Rayon1, Xcentre2, Ycentre2, Zcentre2, Rayon2);
1439
1440   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1441 }
1442 //=============================================================================
1443 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundaryTorus(const char* BoundaryName,
1444                                       CORBA::Double Xcentre, CORBA::Double Ycentre, CORBA::Double Zcentre,
1445                                       CORBA::Double Xaxe, CORBA::Double Yaxe, CORBA::Double Zaxe,
1446                                       CORBA::Double RayonRev, CORBA::Double RayonPri)
1447 {
1448   MESSAGE ("CreateBoundaryTorus : BoundaryName  = " << BoundaryName);
1449 //
1450   SALOME::ExceptionStruct es;
1451   int error = 0;
1452   if ((RayonRev <= 0.0) || (RayonPri <= 0.0))
1453   { es.text = "The radius must be positive.";
1454     error = 1; }
1455   double daux = fabs(Xaxe) + fabs(Yaxe) + fabs(Zaxe);
1456   if (daux < 0.0000001)
1457   { es.text = "The axis must be a non 0 vector.";
1458     error = 2; }
1459   if (error != 0)
1460   {
1461     es.type = SALOME::BAD_PARAM;
1462     throw SALOME::SALOME_Exception(es);
1463     return 0;
1464   };
1465 //
1466   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, 5);
1467   myBoundary->SetTorus(Xcentre, Ycentre, Zcentre, Xaxe, Yaxe, Zaxe, RayonRev, RayonPri);
1468
1469   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1470 }
1471
1472 //=============================================================================
1473 //=============================================================================
1474 CORBA::Long HOMARD_Gen_i::Compute()
1475 {
1476   INFOS ("Compute");
1477   // A. Prealable
1478   int codret = 0;
1479
1480   // A.0. Create Iteration 1
1481   CreateIteration();
1482   myIteration1->SetInfoCompute(_VerboseLevel);
1483   myIteration1->SetMeshName(_MeshNameOUT.c_str());
1484   myIteration1->SetMeshFile(_MeshFileOUT.c_str());
1485   if (_LogInFile) myIteration1->SetLogFile(_LogFile.c_str());
1486
1487   // A.1. L'objet iteration
1488   ASSERT(myIteration1);
1489
1490   // A.2. Controle de la possibilite d'agir
1491   // A.2.1. Etat de l'iteration
1492   int etat = myIteration1->GetState();
1493   MESSAGE ("etat = " << etat);
1494   // A.2.2. On ne calcule pas l'iteration initiale, ni une iteration deja calculee
1495   if (etat == 2) {
1496     SALOME::ExceptionStruct es;
1497     es.type = SALOME::BAD_PARAM;
1498     es.text = "This iteration is already computed.";
1499     throw SALOME::SALOME_Exception(es);
1500   }
1501
1502   // A.3. Numero de l'iteration
1503   //     siterp1 : numero de l'iteration a traiter
1504   //     Si adaptation :
1505   //        siter: numero de l'iteration parent, ou 0 si deja au debut mais cela ne servira pas !
1506   //     Ou si information :
1507   //        siter = siterp1
1508   int NumeIter = myIteration1->GetNumber();
1509   std::string siterp1;
1510   std::stringstream saux1;
1511   saux1 << NumeIter;
1512   siterp1 = saux1.str();
1513   if (NumeIter < 10) { siterp1 = "0" + siterp1; }
1514
1515   std::string siter;
1516   std::stringstream saux0;
1517   int iaux = max(0, NumeIter-1);
1518   saux0 << iaux;
1519   siter = saux0.str();
1520   if (NumeIter < 11) { siter = "0" + siter; }
1521
1522   // A.4. Le cas
1523   ASSERT(!CORBA::is_nil(myCase));
1524
1525   // B. Les répertoires
1526   // B.1. Le répertoire courant
1527   std::string nomDirWork = getenv("PWD");
1528   // B.2. Le sous-répertoire de l'iteration a traiter
1529   char* DirCompute = ComputeDirManagement();
1530   MESSAGE(". DirCompute = " << DirCompute);
1531
1532   // C. Le fichier des messages
1533   // C.1. Le deroulement de l'execution de HOMARD
1534   std::string LogFile = myIteration1->GetLogFile();
1535   if (LogFile.empty()) {
1536     LogFile = DirCompute;
1537     LogFile += "/Liste." + siter + ".vers." + siterp1 + ".log";
1538     myIteration1->SetLogFile(LogFile.c_str());
1539   }
1540   MESSAGE (". LogFile = " << LogFile);
1541   // C.2. Le bilan de l'analyse du maillage
1542   std::string FileInfo = DirCompute;
1543   FileInfo += "/apad." + siterp1 + ".bilan";
1544   myIteration1->SetFileInfo(FileInfo.c_str());
1545
1546    // D. On passe dans le répertoire de l'iteration a calculer
1547   MESSAGE (". On passe dans DirCompute = " << DirCompute);
1548   CHDIR(DirCompute);
1549
1550   // E. Les données de l'exécution HOMARD
1551   // E.1. L'objet du texte du fichier de configuration
1552   SMESHHOMARDImpl::HomardDriver* myDriver = new SMESHHOMARDImpl::HomardDriver(siter, siterp1);
1553   myDriver->TexteInit(DirCompute, LogFile, "English");
1554
1555   // E.2. Le maillage associe a l'iteration
1556   const char* NomMesh = myIteration1->GetMeshName();
1557   MESSAGE (". NomMesh = " << NomMesh);
1558   const char* MeshFile = myIteration1->GetMeshFile();
1559   MESSAGE (". MeshFile = " << MeshFile);
1560
1561   // E.3. Les données du traitement HOMARD
1562   iaux = 1;
1563   myDriver->TexteMaillageHOMARD(DirCompute, siterp1, iaux);
1564   myDriver->TexteMaillage(NomMesh, MeshFile, 1);
1565   codret = ComputeAdap(myDriver);
1566
1567   // E.4. Ajout des informations liees a l'eventuel suivi de frontiere
1568   int BoundaryOption = DriverTexteBoundary(myDriver);
1569
1570   // E.5. Ecriture du texte dans le fichier
1571   MESSAGE (". Ecriture du texte dans le fichier de configuration; codret = "<<codret);
1572   if (codret == 0)
1573   { myDriver->CreeFichier(); }
1574
1575   // G. Execution
1576   //
1577   int codretexec = 1789;
1578   if (codret == 0) {
1579     codretexec = myDriver->ExecuteHomard();
1580     //
1581     MESSAGE ("Erreur en executant HOMARD : " << codretexec);
1582     // En mode adaptation, on ajuste l'etat de l'iteration
1583     if (codretexec == 0) { myIteration1->SetState(2); }
1584     else                 { myIteration1->SetState(1); }
1585   }
1586
1587   // H. Gestion des resultats
1588   if (codret == 0) {
1589     std::string Commentaire;
1590     // H.1. Le fichier des messages, dans tous les cas
1591     Commentaire = "log";
1592     Commentaire += " " + siterp1;
1593
1594     // H.2. Si tout s'est bien passe :
1595     if (codretexec == 0) {
1596       // H.2.1. Le fichier de bilan
1597       Commentaire = "Summary";
1598       Commentaire += " " + siterp1;
1599       // H.2.2. Le fichier de  maillage obtenu
1600       std::stringstream saux0;
1601       Commentaire = "Mesh";
1602       Commentaire += " " + siterp1;
1603       if (_PublishMeshOUT) PublishResultInSmesh(MeshFile);
1604     }
1605     // H.3 Message d'erreur
1606     if (codretexec != 0) {
1607       std::string text = "";
1608       // Message d'erreur en cas de probleme en adaptation
1609       text = "Error during the adaptation.\n";
1610       bool stopvu = false;
1611       std::ifstream fichier(LogFile.c_str());
1612       if (fichier) { // ce test Ã©choue si le fichier n'est pas ouvert
1613         std::string ligne; // variable contenant chaque ligne lue
1614         while (std::getline(fichier, ligne)) {
1615           //INFOS(ligne);
1616           if (stopvu) { text += ligne+ "\n"; }
1617           else {
1618             int position = ligne.find("===== HOMARD ===== STOP =====");
1619             if (position > 0) { stopvu = true; }
1620           }
1621         }
1622       }
1623       text += "\n\nSee the file " + LogFile + "\n";
1624       INFOS (text);
1625       SALOME::ExceptionStruct es;
1626       es.type = SALOME::BAD_PARAM;
1627       es.text = CORBA::string_dup(text.c_str());
1628       throw SALOME::SALOME_Exception(es);
1629     }
1630   }
1631
1632   // I. Menage et retour dans le répertoire du cas
1633   if (codret == 0) {
1634     delete myDriver;
1635     MESSAGE (". On retourne dans nomDirWork = " << nomDirWork);
1636     CHDIR(nomDirWork.c_str());
1637   }
1638
1639   // J. Suivi de la frontière CAO
1640   if (codret == 0) {
1641     if ((BoundaryOption % 5 == 0) && (codretexec == 0)) {
1642       MESSAGE ("Suivi de frontière CAO");
1643       codret = ComputeCAO();
1644     }
1645   }
1646
1647   if (codretexec == 0) {
1648     // Python Dump
1649     PythonDump();
1650
1651     // Delete log file, if required
1652     if (myIteration1 != NULL) {
1653       MESSAGE("myIteration1->GetLogFile() = " << myIteration1->GetLogFile());
1654       if (_LogInFile && _RemoveLogOnSuccess) {
1655         // Remove log file on success
1656         SMESH_File(myIteration1->GetLogFile(), false).remove();
1657       }
1658     }
1659
1660     // Clean all data
1661     DeleteCase();
1662   }
1663
1664   return codretexec;
1665 }
1666
1667 void HOMARD_Gen_i::DeleteCase()
1668 {
1669   MESSAGE ("DeleteCase");
1670   if (myCase->_is_nil()) return;
1671
1672   // Delete all boundaries
1673   _mesBoundarys.clear();
1674
1675   // Delete iterations
1676   DeleteIteration(1);
1677   DeleteIteration(0);
1678
1679   // Delete case
1680   myCase = SMESHHOMARD::HOMARD_Cas::_nil();
1681
1682   // Delete tmp mesh file
1683   if (!_CaseOnMedFile && !_TmpMeshFile.empty()) {
1684     SMESH_File aFile (_TmpMeshFile, false);
1685     if (aFile.exists()) aFile.remove();
1686     _TmpMeshFile = "";
1687   }
1688   _SmeshMesh = SMESH::SMESH_Mesh::_nil();
1689 }
1690
1691 //=============================================================================
1692 // Calcul d'une iteration : partie spécifique Ã  l'adaptation
1693 //=============================================================================
1694 CORBA::Long HOMARD_Gen_i::ComputeAdap(SMESHHOMARDImpl::HomardDriver* myDriver)
1695 {
1696   MESSAGE ("ComputeAdap");
1697
1698   // A. Prealable
1699   // A.1. Bases
1700   int codret = 0;
1701   // Numero de l'iteration
1702   int NumeIter = 1;
1703   std::stringstream saux0;
1704   saux0 << NumeIter-1;
1705   std::string siter = saux0.str();
1706   if (NumeIter < 11) { siter = "0" + siter; }
1707
1708   // B. L'iteration parent
1709   ASSERT(myIteration0);
1710
1711   // C. Le sous-répertoire de l'iteration precedente
1712   char* DirComputePa = ComputeDirPaManagement();
1713   MESSAGE(". DirComputePa = " << DirComputePa);
1714
1715   // D. Les données de l'adaptation HOMARD
1716   // D.1. Le type de conformite
1717   MESSAGE (". ConfType = " << _ConfType);
1718
1719   // D.3. Le maillage de depart
1720   const char* NomMeshParent = myIteration0->GetMeshName();
1721   MESSAGE (". NomMeshParent = " << NomMeshParent);
1722   const char* MeshFileParent = myIteration0->GetMeshFile();
1723   MESSAGE (". MeshFileParent = " << MeshFileParent);
1724
1725   // D.4. Le maillage associe a l'iteration
1726   const char* MeshFile = myIteration1->GetMeshFile();
1727   MESSAGE (". MeshFile = " << MeshFile);
1728   FILE *file = fopen(MeshFile,"r");
1729   if (file != NULL) {
1730     fclose(file);
1731     // CleanOption = 0 : report an error if output mesh file exists
1732     // CleanOption = 1 : destruction du répertoire d'execution
1733     int CleanOption = 1;
1734     if (CleanOption == 0) {
1735       SALOME::ExceptionStruct es;
1736       es.type = SALOME::BAD_PARAM;
1737       std::string text = "MeshFile : " + std::string(MeshFile) + " already exists ";
1738       es.text = CORBA::string_dup(text.c_str());
1739       throw SALOME::SALOME_Exception(es);
1740     }
1741     else {
1742       std::string commande = "rm -f " + std::string(MeshFile);
1743       codret = system(commande.c_str());
1744       if (codret != 0) {
1745         SALOME::ExceptionStruct es;
1746         es.type = SALOME::BAD_PARAM;
1747         es.text = "The mesh file cannot be deleted.";
1748         throw SALOME::SALOME_Exception(es);
1749       }
1750     }
1751   }
1752
1753   // E. Texte du fichier de configuration
1754   // E.1. Incontournables du texte
1755   myDriver->TexteAdap();
1756   int iaux = 0;
1757   myDriver->TexteMaillageHOMARD(DirComputePa, siter, iaux);
1758   myDriver->TexteMaillage(NomMeshParent, MeshFileParent, 0);
1759   myDriver->TexteConfRaffDera(_ConfType);
1760
1761   // E.6. Ajout des options avancees
1762   //myDriver->TexteAdvanced(NivMax, DiamMin, AdapInit, ExtraOutput);
1763   myDriver->TexteAdvanced(-1, -1.0, 0, 1);
1764
1765   // E.7. Ajout des informations sur le deroulement de l'execution
1766   int MessInfo = myIteration1->GetInfoCompute();
1767   MESSAGE (". MessInfo = " << MessInfo);
1768   myDriver->TexteInfoCompute(MessInfo);
1769
1770   return codret;
1771 }
1772 //=============================================================================
1773 // Calcul d'une iteration : partie spécifique au suivi de frontière CAO
1774 //=============================================================================
1775 CORBA::Long HOMARD_Gen_i::ComputeCAO()
1776 {
1777   MESSAGE ("ComputeCAO");
1778
1779   // A. Prealable
1780   // A.1. Bases
1781   int codret = 0;
1782 #ifndef DISABLE_HOMARD_ADAPT
1783   // A.2. Le sous-répertoire de l'iteration en cours de traitement
1784   char* DirCompute = myIteration1->GetDirName();
1785   // A.3. Le maillage résultat de l'iteration en cours de traitement
1786   char* MeshFile = myIteration1->GetMeshFile();
1787
1788   // B. Les données pour FrontTrack
1789   // B.1. Le maillage Ã  modifier
1790   const std::string theInputMedFile = MeshFile;
1791   MESSAGE (". theInputMedFile  = " << theInputMedFile);
1792
1793   // B.2. Le maillage après modification : fichier identique
1794   const std::string theOutputMedFile = MeshFile;
1795   MESSAGE (". theOutputMedFile = " << theInputMedFile);
1796
1797   // B.3. La liste des fichiers contenant les numéros des noeuds Ã  bouger
1798   std::vector< std::string > theInputNodeFiles;
1799   MESSAGE (". DirCompute = " << DirCompute);
1800   std::basic_string<char>::size_type bilan;
1801   int icpt = 0;
1802 #ifndef WIN32
1803   DIR *dp;
1804   struct dirent *dirp;
1805   dp  = opendir(DirCompute);
1806   while ((dirp = readdir(dp)) != NULL)
1807   {
1808     std::string file_name(dirp->d_name);
1809     bilan = file_name.find("fr");
1810     if (bilan != string::npos)
1811     {
1812       std::stringstream filename_total;
1813       filename_total << DirCompute << "/" << file_name;
1814       theInputNodeFiles.push_back(filename_total.str());
1815       icpt += 1;
1816     }
1817   }
1818 #else
1819   HANDLE hFind = INVALID_HANDLE_VALUE;
1820   WIN32_FIND_DATA ffd;
1821   hFind = FindFirstFile(DirNameStart, &ffd);
1822   if (INVALID_HANDLE_VALUE != hFind) {
1823     while (FindNextFile(hFind, &ffd) != 0) {
1824       std::string file_name(ffd.cFileName);
1825       bilan = file_name.find("fr");
1826       if (bilan != string::npos)
1827       {
1828         std::stringstream filename_total;
1829         filename_total << DirCompute << "/" << file_name;
1830         theInputNodeFiles.push_back(filename_total.str());
1831         icpt += 1;
1832       }
1833     }
1834     FindClose(hFind);
1835   }
1836 #endif
1837   for (int i = 0; i < icpt; i++)
1838   { MESSAGE (". theInputNodeFiles["<< i << "] = " << theInputNodeFiles[i]); }
1839
1840   // B.4. Le fichier de la CAO
1841   SMESHHOMARD::ListBoundaryGroupType* ListBoundaryGroupType = myCase->GetBoundaryGroup();
1842   std::string BoundaryName = std::string((*ListBoundaryGroupType)[0]);
1843   MESSAGE (". BoundaryName = " << BoundaryName);
1844   SMESHHOMARD::HOMARD_Boundary_var myBoundary = _mesBoundarys[BoundaryName];
1845   const std::string theXaoFileName = myBoundary->GetDataFile();
1846   MESSAGE (". theXaoFileName = " << theXaoFileName);
1847
1848   // C. Lancement des projections
1849   MESSAGE (". Lancement des projections");
1850
1851   assert(Py_IsInitialized());
1852   PyGILState_STATE gstate;
1853   gstate = PyGILState_Ensure();
1854   PyRun_SimpleString("from FrontTrack import FrontTrack");
1855   // FrontTrack().track( fic_med_brut, fic_med_new, l_fr, xao_file )
1856   std::string pyCommand ("FrontTrack().track( \"");
1857   pyCommand += theInputMedFile + "\", \"" + theOutputMedFile + "\", [";
1858   for (int i = 0; i < icpt; i++) {
1859     if (i > 0) pyCommand += ", ";
1860     pyCommand += "\"";
1861     pyCommand += theInputNodeFiles[i];
1862     pyCommand += "\"";
1863   }
1864   pyCommand += "], \"" + theXaoFileName + "\", False )";
1865   MESSAGE (". Lancement des projections: pyCommand = " << pyCommand);
1866   PyRun_SimpleString(pyCommand.c_str());
1867   PyGILState_Release(gstate);
1868
1869   // D. Transfert des coordonnées modifiées dans le fichier historique de HOMARD
1870   //    On lance une exécution spéciale de HOMARD en attendant
1871   //    de savoir le faire avec MEDCoupling
1872   MESSAGE (". Transfert des coordonnées");
1873   codret = ComputeCAObis();
1874 #endif
1875   return codret;
1876 }
1877 //=============================================================================
1878 //=============================================================================
1879 // Transfert des coordonnées en suivi de frontière CAO
1880 //=============================================================================
1881 CORBA::Long HOMARD_Gen_i::ComputeCAObis()
1882 {
1883   MESSAGE ("ComputeCAObis");
1884
1885   // A. Prealable
1886   int codret = 0;
1887
1888   // A.1. Controle de la possibilite d'agir
1889   // A.1.1. Etat de l'iteration
1890   int etat = myIteration1->GetState();
1891   MESSAGE ("etat = " << etat);
1892   // A.1.2. L'iteration doit Ãªtre calculee
1893   if (etat == 1) {
1894     SALOME::ExceptionStruct es;
1895     es.type = SALOME::BAD_PARAM;
1896     es.text = "This iteration is not computed.";
1897     throw SALOME::SALOME_Exception(es);
1898     return 1;
1899   }
1900   // A.2. Numero de l'iteration
1901   //     siterp1 : numero de l'iteration a traiter
1902   int NumeIter = myIteration1->GetNumber();
1903   std::string siterp1;
1904   std::stringstream saux1;
1905   saux1 << NumeIter;
1906   siterp1 = saux1.str();
1907   if (NumeIter < 10) { siterp1 = "0" + siterp1; }
1908   MESSAGE ("siterp1 = "<<siterp1);
1909
1910   // A.3. Le cas
1911   ASSERT(!CORBA::is_nil(myCase));
1912
1913   // A.4. Le sous-répertoire de l'iteration a traiter
1914   char* DirCompute = myIteration1->GetDirName();
1915   MESSAGE(". DirCompute = " << DirCompute);
1916
1917   // C. Le fichier des messages
1918   std::string LogFile = DirCompute;
1919   LogFile += "/Liste." + siterp1 + ".maj_coords.log";
1920   MESSAGE (". LogFile = " << LogFile);
1921   myIteration1->SetFileInfo(LogFile.c_str());
1922
1923   // D. On passe dans le répertoire de l'iteration a calculer
1924   MESSAGE (". On passe dans DirCompute = " << DirCompute);
1925   CHDIR(DirCompute);
1926
1927   // E. Les données de l'exécution HOMARD
1928   // E.1. L'objet du texte du fichier de configuration
1929   SMESHHOMARDImpl::HomardDriver* myDriver = new SMESHHOMARDImpl::HomardDriver("", siterp1);
1930   myDriver->TexteInit(DirCompute, LogFile, "English");
1931
1932   // E.2. Le maillage associe a l'iteration
1933   const char* NomMesh = myIteration1->GetMeshName();
1934   MESSAGE (". NomMesh = " << NomMesh);
1935   const char* MeshFile = myIteration1->GetMeshFile();
1936   MESSAGE (". MeshFile = " << MeshFile);
1937
1938   // E.3. Les données du traitement HOMARD
1939   myDriver->TexteMajCoords(NumeIter);
1940   int iaux = 0;
1941   myDriver->TexteMaillageHOMARD(DirCompute, siterp1, iaux);
1942   myDriver->TexteMaillage(NomMesh, MeshFile, 0);
1943   //
1944   // E.4. Ecriture du texte dans le fichier
1945   MESSAGE (". Ecriture du texte dans le fichier de configuration; codret = "<<codret);
1946   if (codret == 0) myDriver->CreeFichier();
1947
1948   // F. Execution
1949   //
1950   int codretexec = 1789;
1951   if (codret == 0) {
1952     codretexec = myDriver->ExecuteHomard();
1953     MESSAGE ("Erreur en executant HOMARD : " << codretexec);
1954   }
1955
1956   // G. Gestion des resultats
1957   if (codret == 0) {
1958     // G.1. Le fichier des messages, dans tous les cas
1959     std::string Commentaire = "logmaj_coords";
1960     // G.2 Message d'erreur
1961     if (codretexec != 0) {
1962       std::string text = "\n\nSee the file " + LogFile + "\n";
1963       INFOS (text);
1964       SALOME::ExceptionStruct es;
1965       es.type = SALOME::BAD_PARAM;
1966       es.text = CORBA::string_dup(text.c_str());
1967       throw SALOME::SALOME_Exception(es);
1968
1969       // On force le succes pour pouvoir consulter le fichier log
1970       codretexec = 0;
1971     }
1972   }
1973
1974   // H. Menage et retour dans le répertoire du cas
1975   if (codret == 0) { delete myDriver; }
1976
1977   return codret;
1978 }
1979 //=============================================================================
1980 // Creation d'un nom de sous-répertoire pour l'iteration au sein d'un répertoire parent
1981 //  nomrep : nom du répertoire parent
1982 //  num : le nom du sous-répertoire est sous la forme 'In', n est >= num
1983 //=============================================================================
1984 char* HOMARD_Gen_i::CreateDirNameIter(const char* nomrep, CORBA::Long num)
1985 {
1986 #ifndef DISABLE_HOMARD_ADAPT 
1987   MESSAGE ("CreateDirNameIter : nomrep ="<< nomrep << ", num = "<<num);
1988   // On verifie que le répertoire parent existe
1989   int codret = CHDIR(nomrep);
1990   if (codret != 0) {
1991     SALOME::ExceptionStruct es;
1992     es.type = SALOME::BAD_PARAM;
1993     es.text = "The directory of the case does not exist.";
1994     throw SALOME::SALOME_Exception(es);
1995   }
1996   std::string nomDirActuel = getenv("PWD");
1997   std::string DirName;
1998   // On boucle sur tous les noms possibles jusqu'a trouver un nom correspondant a un répertoire inconnu
1999   bool a_chercher = true;
2000   while (a_chercher) {
2001     // On passe dans le répertoire parent
2002
2003     CHDIR(nomrep);
2004     // On recherche un nom sous la forme Iabc, avec abc representant le numero
2005     int jaux;
2006     if      (num <    100) { jaux = 2; }
2007     else if (num <   1000) { jaux = 3; }
2008     else if (num <  10000) { jaux = 4; }
2009     else if (num < 100000) { jaux = 5; }
2010     else                     { jaux = 9; }
2011     std::ostringstream iaux;
2012     iaux << std::setw(jaux) << std::setfill('0') << num;
2013     std::ostringstream DirNameA;
2014     DirNameA << "I" << iaux.str();
2015     // Si on ne pas peut entrer dans le répertoire, on doit verifier
2016     // que c'est bien un probleme d'absence
2017     if (CHDIR(DirNameA.str().c_str()) != 0)
2018     {
2019       bool existe = false;
2020 #ifndef WIN32
2021       DIR *dp;
2022       struct dirent *dirp;
2023       dp  = opendir(nomrep);
2024       while ((dirp = readdir(dp)) != NULL)
2025       {
2026         std::string file_name(dirp->d_name);
2027 #else
2028       HANDLE hFind = INVALID_HANDLE_VALUE;
2029       WIN32_FIND_DATA ffd;
2030       hFind = FindFirstFile(nomrep, &ffd);
2031       if (INVALID_HANDLE_VALUE != hFind) {
2032         while (FindNextFile(hFind, &ffd) != 0) {
2033          if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; //skip directories
2034          std::string file_name(ffd.cFileName);
2035 #endif
2036         if (file_name == DirNameA.str()) { existe = true; }
2037       }
2038 #ifndef WIN32
2039       closedir(dp);
2040 #else
2041       FindClose(hFind);
2042 #endif
2043       if (!existe)
2044       {
2045         DirName = DirNameA.str();
2046         a_chercher = false;
2047         break;
2048       }
2049     }
2050     num += 1;
2051   }
2052
2053   MESSAGE ("==> DirName = " << DirName);
2054   MESSAGE (". On retourne dans nomDirActuel = " << nomDirActuel);
2055   CHDIR(nomDirActuel.c_str());
2056   return CORBA::string_dup(DirName.c_str());
2057 #else
2058         return "";
2059 #endif
2060 }
2061 //=============================================================================
2062 // Calcul d'une iteration : gestion du répertoire de calcul
2063 //=============================================================================
2064 char* HOMARD_Gen_i::ComputeDirManagement()
2065 {
2066 #ifndef DISABLE_HOMARD_ADAPT
2067   MESSAGE ("ComputeDirManagement : répertoires pour le calcul");
2068
2069   //Si le sous-répertoire existe :
2070   //  CleanOption =  0 : on sort en erreur si le répertoire n'est pas vide
2071   //  CleanOption =  1 : on fait le menage du répertoire
2072   //  CleanOption = -1 : on ne fait rien
2073   int CleanOption = 0;
2074
2075   // B.2. Le répertoire du cas
2076   const char* nomDirCase = myCase->GetDirName();
2077   MESSAGE (". nomDirCase = " << nomDirCase);
2078
2079   // B.3. Le sous-répertoire de l'iteration a calculer, puis le répertoire complet a creer
2080   // B.3.1. Le nom du sous-répertoire
2081   const char* nomDirIt = myIteration1->GetDirNameLoc();
2082
2083   // B.3.2. Le nom complet du sous-répertoire
2084   std::stringstream DirCompute;
2085   DirCompute << nomDirCase << "/" << nomDirIt;
2086   MESSAGE (". DirCompute = " << DirCompute.str());
2087
2088   // B.3.3. Si le sous-répertoire n'existe pas, on le cree
2089   if (CHDIR(DirCompute.str().c_str()) != 0)
2090   {
2091 #ifndef WIN32
2092     if (mkdir(DirCompute.str().c_str(), S_IRWXU|S_IRGRP|S_IXGRP) != 0)
2093 #else
2094     if (_mkdir(DirCompute.str().c_str()) != 0)
2095 #endif
2096     {
2097        // GERALD -- QMESSAGE BOX
2098        std::cerr << "Pb Creation du répertoire DirCompute = " << DirCompute.str() << std::endl;
2099        VERIFICATION("Pb a la creation du répertoire" == 0);
2100     }
2101   }
2102   else
2103   {
2104     //  Le répertoire existe
2105     //  On demande de faire le menage de son contenu :
2106     if (CleanOption == 1) {
2107       MESSAGE (". Menage du répertoire DirCompute = " << DirCompute.str());
2108       std::string commande = "rm -rf " + DirCompute.str()+"/*";
2109       int codret = system(commande.c_str());
2110       if (codret != 0)
2111       {
2112         // GERALD -- QMESSAGE BOX
2113         std::cerr << ". Menage du répertoire de calcul" << DirCompute.str() << std::endl;
2114         VERIFICATION("Pb au menage du répertoire de calcul" == 0);
2115       }
2116     }
2117     //  On n'a pas demande de faire le menage de son contenu : on sort en erreur :
2118     else {
2119       if (CleanOption == 0) {
2120 #ifndef WIN32
2121         DIR *dp;
2122         struct dirent *dirp;
2123         dp  = opendir(DirCompute.str().c_str());
2124         bool result = true;
2125         while ((dirp = readdir(dp)) != NULL && result)
2126         {
2127           std::string file_name(dirp->d_name);
2128           result = file_name.empty() || file_name == "." || file_name == ".."; //if any file - break and return false
2129         }
2130         closedir(dp);
2131 #else
2132        HANDLE hFind = INVALID_HANDLE_VALUE;
2133        WIN32_FIND_DATA ffd;
2134        hFind = FindFirstFile(DirCompute.str().c_str(), &ffd);
2135        bool result = true;
2136        if (INVALID_HANDLE_VALUE != hFind) {
2137          while (FindNextFile(hFind, &ffd) != 0) {
2138           if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; //skip directories
2139           std::string file_name(ffd.cFileName);
2140           result = file_name.empty() || file_name == "." || file_name == ".."; //if any file - break and return false
2141          }
2142        }
2143        FindClose(hFind);
2144 #endif
2145         if (result == false)
2146         {
2147           SALOME::ExceptionStruct es;
2148           es.type = SALOME::BAD_PARAM;
2149           std::string text = "Directory : " + DirCompute.str() + " is not empty";
2150           es.text = CORBA::string_dup(text.c_str());
2151           throw SALOME::SALOME_Exception(es);
2152           VERIFICATION("Directory is not empty" == 0);
2153         }
2154       }
2155     }
2156   }
2157
2158   return CORBA::string_dup(DirCompute.str().c_str());
2159 #else
2160         return "";
2161 #endif
2162 }
2163 //=============================================================================
2164 // Calcul d'une iteration : gestion du répertoire de calcul de l'iteration parent
2165 //=============================================================================
2166 char* HOMARD_Gen_i::ComputeDirPaManagement()
2167 {
2168   MESSAGE ("ComputeDirPaManagement : répertoires pour le calcul");
2169   // Le répertoire du cas
2170   const char* nomDirCase = myCase->GetDirName();
2171   MESSAGE (". nomDirCase = " << nomDirCase);
2172
2173   // Le sous-répertoire de l'iteration precedente
2174
2175   const char* nomDirItPa = myIteration0->GetDirNameLoc();
2176   std::stringstream DirComputePa;
2177   DirComputePa << nomDirCase << "/" << nomDirItPa;
2178   MESSAGE(". nomDirItPa = " << nomDirItPa);
2179   MESSAGE(". DirComputePa = " << DirComputePa.str());
2180
2181   return CORBA::string_dup(DirComputePa.str().c_str());
2182 }
2183
2184 //=============================================================================
2185 // Calcul d'une iteration : ecriture des frontieres dans le fichier de configuration
2186 // On ecrit dans l'ordre :
2187 //    1. la definition des frontieres
2188 //    2. les liens avec les groupes
2189 //    3. un entier resumant le type de comportement pour les frontieres
2190 //=============================================================================
2191 int HOMARD_Gen_i::DriverTexteBoundary(SMESHHOMARDImpl::HomardDriver* myDriver)
2192 {
2193   MESSAGE ("... DriverTexteBoundary");
2194   // 1. Recuperation des frontieres
2195   std::list<std::string>  ListeBoundaryTraitees;
2196   SMESHHOMARD::ListBoundaryGroupType* ListBoundaryGroupType = myCase->GetBoundaryGroup();
2197   int numberOfitems = ListBoundaryGroupType->length();
2198   MESSAGE ("... number of string for Boundary+Group = " << numberOfitems);
2199   int BoundaryOption = 1;
2200   // 2. Parcours des frontieres pour ecrire leur description
2201   int NumBoundaryAnalytical = 0;
2202   for (int NumBoundary = 0; NumBoundary< numberOfitems; NumBoundary=NumBoundary+2)
2203   {
2204     std::string BoundaryName = std::string((*ListBoundaryGroupType)[NumBoundary]);
2205     MESSAGE ("... BoundaryName = " << BoundaryName);
2206     // 2.1. La frontiere a-t-elle deja ete ecrite ?
2207     //      Cela arrive quand elle est liee a plusieurs groupes. Il ne faut l'ecrire que la premiere fois
2208     int A_faire = 1;
2209     std::list<std::string>::const_iterator it = ListeBoundaryTraitees.begin();
2210     while (it != ListeBoundaryTraitees.end())
2211     {
2212       MESSAGE ("..... BoundaryNameTraitee = " << *it);
2213       if (BoundaryName == *it) { A_faire = 0; }
2214       it++;
2215     }
2216     // 2.2. Ecriture de la frontiere
2217     if (A_faire == 1)
2218     {
2219       // 2.2.1. Caracteristiques de la frontiere
2220       SMESHHOMARD::HOMARD_Boundary_var myBoundary = _mesBoundarys[BoundaryName];
2221       ASSERT(!CORBA::is_nil(myBoundary));
2222       int BoundaryType = myBoundary->GetType();
2223       MESSAGE ("... BoundaryType = " << BoundaryType);
2224       // 2.2.2. Ecriture selon le type
2225       // 2.2.2.1. Cas d une frontiere CAO
2226       if (BoundaryType == -1)
2227       {
2228 //         const char* CAOFile = myBoundary->GetDataFile();
2229 //         MESSAGE (". CAOFile = " << CAOFile);
2230         if (BoundaryOption % 5 != 0) { BoundaryOption = BoundaryOption*5; }
2231       }
2232       // 2.2.2.2. Cas d une frontiere discrete
2233       else if (BoundaryType == 0)
2234       {
2235         const char* MeshName = myBoundary->GetMeshName();
2236         MESSAGE (". MeshName = " << MeshName);
2237         const char* MeshFile = myBoundary->GetDataFile();
2238         MESSAGE (". MeshFile = " << MeshFile);
2239         myDriver->TexteBoundaryDi(MeshName, MeshFile);
2240         if (BoundaryOption % 2 != 0) { BoundaryOption = BoundaryOption*2; }
2241       }
2242       // 2.2.2.3. Cas d une frontiere analytique
2243       else
2244       {
2245         NumBoundaryAnalytical++;
2246         SMESHHOMARD::double_array* coor = myBoundary->GetCoords();
2247         if (BoundaryType == 1) // Cas d un cylindre
2248         {
2249           myDriver->TexteBoundaryAn(BoundaryName, NumBoundaryAnalytical, BoundaryType, (*coor)[0], (*coor)[1], (*coor)[2], (*coor)[3], (*coor)[4], (*coor)[5], (*coor)[6], 0.);
2250           if (BoundaryOption % 3 != 0) { BoundaryOption = BoundaryOption*3; }
2251         }
2252         else if (BoundaryType == 2) // Cas d une sphere
2253         {
2254           myDriver->TexteBoundaryAn(BoundaryName, NumBoundaryAnalytical, BoundaryType, (*coor)[0], (*coor)[1], (*coor)[2], (*coor)[3], 0., 0., 0., 0.);
2255           if (BoundaryOption % 3 != 0) { BoundaryOption = BoundaryOption*3; }
2256         }
2257         else if (BoundaryType == 3) // Cas d un cone defini par un axe et un angle
2258         {
2259           myDriver->TexteBoundaryAn(BoundaryName, NumBoundaryAnalytical, BoundaryType, (*coor)[0], (*coor)[1], (*coor)[2], (*coor)[3], (*coor)[4], (*coor)[5], (*coor)[6], 0.);
2260           if (BoundaryOption % 3 != 0) { BoundaryOption = BoundaryOption*3; }
2261         }
2262         else if (BoundaryType == 4) // Cas d un cone defini par les 2 rayons
2263         {
2264           myDriver->TexteBoundaryAn(BoundaryName, NumBoundaryAnalytical, BoundaryType, (*coor)[0], (*coor)[1], (*coor)[2], (*coor)[3], (*coor)[4], (*coor)[5], (*coor)[6], (*coor)[7]);
2265           if (BoundaryOption % 3 != 0) { BoundaryOption = BoundaryOption*3; }
2266         }
2267         else if (BoundaryType == 5) // Cas d un tore
2268         {
2269           myDriver->TexteBoundaryAn(BoundaryName, NumBoundaryAnalytical, BoundaryType, (*coor)[0], (*coor)[1], (*coor)[2], (*coor)[3], (*coor)[4], (*coor)[5], (*coor)[6], (*coor)[7]);
2270           if (BoundaryOption % 3 != 0) { BoundaryOption = BoundaryOption*3; }
2271         }
2272       }
2273       // 2.2.3. Memorisation du traitement
2274       ListeBoundaryTraitees.push_back(BoundaryName);
2275     }
2276   }
2277   // 3. Parcours des frontieres pour ecrire les liens avec les groupes
2278   NumBoundaryAnalytical = 0;
2279   for (int NumBoundary = 0; NumBoundary< numberOfitems; NumBoundary=NumBoundary+2)
2280   {
2281     std::string BoundaryName = std::string((*ListBoundaryGroupType)[NumBoundary]);
2282     MESSAGE ("... BoundaryName = " << BoundaryName);
2283     SMESHHOMARD::HOMARD_Boundary_var myBoundary = _mesBoundarys[BoundaryName];
2284     ASSERT(!CORBA::is_nil(myBoundary));
2285     int BoundaryType = myBoundary->GetType();
2286     MESSAGE ("... BoundaryType = " << BoundaryType);
2287     // 3.1. Recuperation du nom du groupe
2288     std::string GroupName = std::string((*ListBoundaryGroupType)[NumBoundary+1]);
2289     MESSAGE ("... GroupName = " << GroupName);
2290     // 3.2. Cas d une frontiere CAO
2291     if (BoundaryType == -1)
2292     {
2293       if (GroupName.size() > 0) { myDriver->TexteBoundaryCAOGr (GroupName); }
2294     }
2295     // 3.3. Cas d une frontiere discrete
2296     else if (BoundaryType == 0)
2297     {
2298       if (GroupName.size() > 0) { myDriver->TexteBoundaryDiGr (GroupName); }
2299     }
2300     // 3.4. Cas d une frontiere analytique
2301     else
2302     {
2303       NumBoundaryAnalytical++;
2304       myDriver->TexteBoundaryAnGr (BoundaryName, NumBoundaryAnalytical, GroupName);
2305     }
2306   }
2307   // 4. Ecriture de l'option finale
2308   myDriver->TexteBoundaryOption(BoundaryOption);
2309 //
2310   return BoundaryOption;
2311 }
2312 //===========================================================================
2313 //===========================================================================
2314
2315 //===========================================================================
2316 // Publication
2317 //===========================================================================
2318 void HOMARD_Gen_i::PublishResultInSmesh(const char* NomFich)
2319 {
2320   // Prevent dump of CreateMeshesFromMED
2321   SMESH::TPythonDump pDump; // do not delete this line of code
2322
2323   MESSAGE("PublishResultInSmesh " << NomFich);
2324   if (CORBA::is_nil(SMESH_Gen_i::GetSMESHGen()->getStudyServant())) {
2325     SALOME::ExceptionStruct es;
2326     es.type = SALOME::BAD_PARAM;
2327     es.text = "Invalid study context";
2328     throw SALOME::SALOME_Exception(es);
2329   }
2330
2331   // Le module SMESH est-il actif ?
2332   SALOMEDS::SObject_var aSmeshSO =
2333     SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindComponent("SMESH");
2334   //
2335   // TODO?
2336   // Temporary suppressed depublication of mesh with the same name of file
2337   /*
2338   if (!CORBA::is_nil(aSmeshSO)) {
2339     // On verifie que le fichier n est pas deja publie
2340     SALOMEDS::ChildIterator_var aIter =
2341       SMESH_Gen_i::GetSMESHGen()->getStudyServant()->NewChildIterator(aSmeshSO);
2342     for (; aIter->More(); aIter->Next()) {
2343       SALOMEDS::SObject_var aSO = aIter->Value();
2344       SALOMEDS::GenericAttribute_var aGAttr;
2345       if (aSO->FindAttribute(aGAttr, "AttributeExternalFileDef")) {
2346         SALOMEDS::AttributeExternalFileDef_var anAttr =
2347           SALOMEDS::AttributeExternalFileDef::_narrow(aGAttr);
2348         CORBA::String_var value = anAttr->Value();
2349         if (strcmp((const char*)value, NomFich) == 0) {
2350           MESSAGE ("PublishResultInSmesh : le fichier " << NomFich << " est deja publie.");
2351           // Pour un fichier importe, on ne republie pas
2352           // Option = 0 : fichier issu d'une importation
2353           // Option = 1 : fichier issu d'une execution HOMARD
2354           if (Option == 0) { return; }
2355           // Pour un fichier calcule, on commence par faire la depublication
2356           else {
2357             MESSAGE("PublishResultInSmesh : depublication");
2358             if (aSO->FindAttribute(aGAttr, "AttributeName")) {
2359               SALOMEDS::AttributeName_var anAttr2 = SALOMEDS::AttributeName::_narrow(aGAttr);
2360               CORBA::String_var value2 = anAttr2->Value();
2361               std::string MeshName = string(value2);
2362               MESSAGE("PublishResultInSmesh : depublication de " << MeshName);
2363               DeleteResultInSmesh(NomFich, MeshName);
2364             }
2365           }
2366         }
2367       }
2368     }
2369   }
2370   */
2371
2372   // On enregistre le fichier
2373   MESSAGE("Enregistrement du fichier");
2374   //
2375   //SMESH::SMESH_Gen_var aSmeshEngine = this->retrieveSMESHInst();
2376   SMESH_Gen_i* aSmeshEngine = SMESH_Gen_i::GetSMESHGen();
2377   //
2378   //ASSERT(!CORBA::is_nil(aSmeshEngine));
2379   aSmeshEngine->UpdateStudy();
2380   SMESH::DriverMED_ReadStatus theStatus;
2381
2382   // On met a jour les attributs AttributeExternalFileDef et AttributePixMap
2383   SMESH::mesh_array* mesMaillages = aSmeshEngine->CreateMeshesFromMED(NomFich, theStatus);
2384   if (CORBA::is_nil(aSmeshSO)) {
2385     aSmeshSO = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindComponent("SMESH");
2386     if (CORBA::is_nil(aSmeshSO)) return;
2387   }
2388
2389   for (int i = 0; i < (int)mesMaillages->length(); i++) {
2390     MESSAGE(". Mise a jour des attributs du maillage");
2391     SMESH::SMESH_Mesh_var monMaillage = (*mesMaillages)[i];
2392     SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_narrow
2393       (SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectIOR
2394        (SMESH_Gen_i::GetORB()->object_to_string(monMaillage)));
2395     SALOMEDS::StudyBuilder_var aStudyBuilder =
2396       SMESH_Gen_i::GetSMESHGen()->getStudyServant()->NewBuilder();
2397     SALOMEDS::GenericAttribute_var aGAttr =
2398       aStudyBuilder->FindOrCreateAttribute(aSO, "AttributeExternalFileDef");
2399     SALOMEDS::AttributeExternalFileDef_var anAttr =
2400       SALOMEDS::AttributeExternalFileDef::_narrow(aGAttr);
2401     anAttr->SetValue(NomFich);
2402     SALOMEDS::GenericAttribute_var aPixMap =
2403       aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePixMap");
2404     SALOMEDS::AttributePixMap_var anAttr2 = SALOMEDS::AttributePixMap::_narrow(aPixMap);
2405     anAttr2->SetPixMap("mesh_tree_mesh.png");
2406   }
2407 }
2408
2409 //=============================================================================
2410 void HOMARD_Gen_i::DeleteResultInSmesh(std::string NomFich, std::string MeshName)
2411 {
2412   MESSAGE ("DeleteResultInSmesh pour le maillage " << MeshName << " dans le fichier " << NomFich);
2413   if (CORBA::is_nil(SMESH_Gen_i::GetSMESHGen()->getStudyServant())) {
2414     SALOME::ExceptionStruct es;
2415     es.type = SALOME::BAD_PARAM;
2416     es.text = "Invalid study context";
2417     throw SALOME::SALOME_Exception(es);
2418   }
2419
2420   // Le module SMESH est-il actif ?
2421   SALOMEDS::SObject_var aSmeshSO =
2422     SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindComponent("SMESH");
2423   //
2424   if (CORBA::is_nil(aSmeshSO)) return;
2425   // On verifie que le fichier est deja publie
2426   SALOMEDS::StudyBuilder_var myBuilder =
2427     SMESH_Gen_i::GetSMESHGen()->getStudyServant()->NewBuilder();
2428   SALOMEDS::ChildIterator_var aIter =
2429     SMESH_Gen_i::GetSMESHGen()->getStudyServant()->NewChildIterator(aSmeshSO);
2430   for (; aIter->More(); aIter->Next()) {
2431     SALOMEDS::SObject_var  aSO = aIter->Value();
2432     SALOMEDS::GenericAttribute_var aGAttr;
2433     if (aSO->FindAttribute(aGAttr, "AttributeExternalFileDef")) {
2434       SALOMEDS::AttributeExternalFileDef_var anAttr =
2435         SALOMEDS::AttributeExternalFileDef::_narrow(aGAttr);
2436       CORBA::String_var value = anAttr->Value();
2437       if (strcmp((const char*)value, NomFich.c_str()) == 0) {
2438         if (aSO->FindAttribute(aGAttr, "AttributeName")) {
2439           SALOMEDS::AttributeName_var anAttr2 = SALOMEDS::AttributeName::_narrow(aGAttr);
2440           CORBA::String_var value2 = anAttr2->Value();
2441           if (strcmp((const char*)value2, MeshName.c_str()) == 0) {
2442             myBuilder->RemoveObjectWithChildren(aSO);
2443           }
2444         }
2445       }
2446     }
2447   }
2448 }
2449
2450 void HOMARD_Gen_i::PythonDump()
2451 {
2452   MESSAGE ("Begin PythonDump");
2453   SMESH::TPythonDump pd;
2454
2455   // SMESH_Homard
2456   pd << "import SMESHHOMARD\n";
2457   //pd << "smeshhomard = " << SMESH_Gen_i::GetSMESHGen() << ".CreateHOMARD_ADAPT()\n";
2458   pd << "smeshhomard = " << SMESH_Gen_i::GetSMESHGen() << ".Adaptation(\"Uniform\")\n";
2459
2460   // Boundaries
2461   if (_mesBoundarys.size() > 0) MESSAGE(". Creation of the boundaries");
2462   std::map<std::string, SMESHHOMARD::HOMARD_Boundary_var>::const_iterator it_boundary;
2463   for (it_boundary  = _mesBoundarys.begin();
2464        it_boundary != _mesBoundarys.end(); ++it_boundary) {
2465     SMESHHOMARD::HOMARD_Boundary_var maBoundary = (*it_boundary).second;
2466     //MESSAGE ("PythonDump  of boundary " << (*it_boundary).first <<
2467     //         " : " << maBoundary->GetDumpPython());
2468     pd << maBoundary->GetDumpPython();
2469   }
2470
2471   // Case
2472   ASSERT(!myCase->_is_nil());
2473   MESSAGE (". Creation of the case");
2474
2475   if (_CaseOnMedFile) {
2476     pd << "smeshhomard.CreateCase(\"" << myIteration0->GetMeshName();
2477     pd << "\", \"" << myIteration0->GetMeshFile();
2478     pd << "\", \"" << myCase->GetDirName() << "\")\n";
2479   }
2480   else {
2481     pd << "smeshhomard.CreateCaseOnMesh(\"" << myIteration0->GetMeshName();
2482     pd << "\", " << _SmeshMesh;
2483     pd << ".GetMesh(), \"" << myCase->GetDirName() << "\")\n";
2484   }
2485
2486   pd << myCase->GetDumpPython();
2487
2488   // Preferences
2489   pd << "smeshhomard.SetConfType(" << _ConfType << ")\n";
2490   pd << "smeshhomard.SetKeepMedOUT(" << (_KeepMedOUT ? "True" : "False") << ")\n";
2491   pd << "smeshhomard.SetPublishMeshOUT(" << (_PublishMeshOUT ? "True" : "False") << ")\n";
2492   pd << "smeshhomard.SetMeshNameOUT(\"" << _MeshNameOUT << "\")\n";
2493   pd << "smeshhomard.SetMeshFileOUT(\"" << _MeshFileOUT << "\")\n";
2494
2495   pd << "smeshhomard.SetKeepWorkingFiles(" << (_KeepWorkingFiles ? "True" : "False") << ")\n";
2496   pd << "smeshhomard.SetLogInFile(" << (_LogInFile ? "True" : "False") << ")\n";
2497   if (_LogInFile) pd << "smeshhomard.SetLogFile(\"" << _LogFile << "\")\n";
2498   pd << "smeshhomard.SetRemoveLogOnSuccess(" << (_RemoveLogOnSuccess ? "True" : "False") << ")\n";
2499   pd << "smeshhomard.SetVerboseLevel(" << _VerboseLevel << ")\n";
2500
2501   // Compute
2502   pd << "smeshhomard.Compute()\n";
2503   MESSAGE ("End PythonDump");
2504 }
2505
2506 void HOMARD_Gen_i::AddBoundary(const char* BoundaryName)
2507 {
2508   MESSAGE("HOMARD_Gen_i::AddBoundary : BoundaryName = " << BoundaryName);
2509   if (myCase->_is_nil()) {
2510     SALOME::ExceptionStruct es;
2511     es.type = SALOME::BAD_PARAM;
2512     std::string text = "The input mesh must be defined before boundary addition";
2513     es.text = CORBA::string_dup(text.c_str());
2514     throw SALOME::SALOME_Exception(es);
2515   }
2516   myCase->AddBoundary(BoundaryName);
2517 }
2518
2519 void HOMARD_Gen_i::AddBoundaryGroup(const char* BoundaryName, const char* Group)
2520 {
2521   MESSAGE("HOMARD_Gen_i::AddBoundaryGroup : BoundaryName = " <<
2522           BoundaryName << ", Group = " << Group);
2523   if (myCase->_is_nil()) {
2524     SALOME::ExceptionStruct es;
2525     es.type = SALOME::BAD_PARAM;
2526     std::string text = "The input mesh must be defined before boundary group addition";
2527     es.text = CORBA::string_dup(text.c_str());
2528     throw SALOME::SALOME_Exception(es);
2529   }
2530   myCase->AddBoundaryGroup(BoundaryName, Group);
2531 }
2532
2533 //===============================================================================
2534 // Preferences
2535 //===============================================================================
2536 void HOMARD_Gen_i::SetConfType(CORBA::Long theConfType)
2537 {
2538   _ConfType = theConfType;
2539 }
2540 void HOMARD_Gen_i::SetKeepMedOUT(bool theKeepMedOUT)
2541 {
2542   _KeepMedOUT = theKeepMedOUT;
2543 }
2544 void HOMARD_Gen_i::SetPublishMeshOUT(bool thePublishMeshOUT)
2545 {
2546   _PublishMeshOUT = thePublishMeshOUT;
2547 }
2548 void HOMARD_Gen_i::SetKeepWorkingFiles(bool theKeepWorkingFiles)
2549 {
2550   _KeepWorkingFiles = theKeepWorkingFiles;
2551 }
2552 void HOMARD_Gen_i::SetLogInFile(bool theLogInFile)
2553 {
2554   _LogInFile = theLogInFile;
2555 }
2556 void HOMARD_Gen_i::SetRemoveLogOnSuccess(bool theRemoveLogOnSuccess)
2557 {
2558   _RemoveLogOnSuccess = theRemoveLogOnSuccess;
2559 }
2560 void HOMARD_Gen_i::SetVerboseLevel(CORBA::Long theVerboseLevel)
2561 {
2562   _VerboseLevel = theVerboseLevel;
2563 }
2564 void HOMARD_Gen_i::SetMeshNameOUT(const char* theMeshNameOUT)
2565 {
2566   _MeshNameOUT = theMeshNameOUT;
2567 }
2568 void HOMARD_Gen_i::SetMeshFileOUT(const char* theMeshFileOUT)
2569 {
2570   _MeshFileOUT = theMeshFileOUT;
2571 }
2572 void HOMARD_Gen_i::SetLogFile(const char* theLogFile)
2573 {
2574   _LogFile = theLogFile;
2575 }
2576
2577 // =======================================================================
2578 std::set<std::string> GetListeGroupesInMedFile(const char * aFile)
2579 {
2580   std::set<std::string> ListeGroupes;
2581   med_err erreur = 0;
2582   med_idt medIdt;
2583   while (erreur == 0) {
2584     //  Ouverture du fichier
2585     medIdt = MEDfileOpen(aFile,MED_ACC_RDONLY);
2586     if (medIdt < 0) {
2587       erreur = 1;
2588       break;
2589     }
2590     // Caracteristiques du maillage
2591     char meshname[MED_NAME_SIZE+1];
2592     med_int spacedim,meshdim;
2593     med_mesh_type meshtype;
2594     char descriptionription[MED_COMMENT_SIZE+1];
2595     char dtunit[MED_SNAME_SIZE+1];
2596     med_sorting_type sortingtype;
2597     med_int nstep;
2598     med_axis_type axistype;
2599     int naxis = MEDmeshnAxis(medIdt,1);
2600     char *axisname=new char[naxis*MED_SNAME_SIZE+1];
2601     char *axisunit=new char[naxis*MED_SNAME_SIZE+1];
2602     erreur = MEDmeshInfo(medIdt,
2603                             1,
2604                             meshname,
2605                             &spacedim,
2606                             &meshdim,
2607                             &meshtype,
2608                             descriptionription,
2609                             dtunit,
2610                             &sortingtype,
2611                             &nstep,
2612                             &axistype,
2613                             axisname,
2614                             axisunit);
2615     delete[] axisname;
2616     delete[] axisunit;
2617     if (erreur < 0) { break; }
2618     // Nombre de familles
2619     med_int nfam;
2620     nfam = MEDnFamily(medIdt,meshname);
2621     if (nfam < 0) {
2622       erreur = 2;
2623       break;
2624     }
2625     // Lecture des caracteristiques des familles
2626     for (int i=0;i<nfam;i++) {
2627       // Lecture du nombre de groupes
2628       med_int ngro = MEDnFamilyGroup(medIdt,meshname,i+1);
2629       if (ngro < 0) {
2630         erreur = 3;
2631         break;
2632       }
2633       // Lecture de la famille
2634       else if (ngro > 0) {
2635         char familyname[MED_NAME_SIZE+1];
2636         med_int numfam;
2637         char* gro = (char*) malloc(MED_LNAME_SIZE*ngro+1);
2638         erreur = MEDfamilyInfo(medIdt,
2639                                meshname,
2640                                i+1,
2641                                familyname,
2642                                &numfam,
2643                                gro);
2644         if (erreur < 0) {
2645           free(gro);
2646           break;
2647         }
2648         // Lecture des groupes pour une famille de mailles
2649         if (numfam < 0) {
2650           for (int j=0;j<ngro;j++) {
2651             char str2[MED_LNAME_SIZE+1];
2652             strncpy(str2,gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
2653             str2[MED_LNAME_SIZE] = '\0';
2654             ListeGroupes.insert(std::string(str2));
2655           }
2656         }
2657         free(gro);
2658       }
2659     }
2660     break;
2661   }
2662   // Fermeture du fichier
2663   if (medIdt > 0) MEDfileClose(medIdt);
2664
2665   return ListeGroupes;
2666 }
2667
2668 // =======================================================================
2669 // Le vecteur en retour contiendra les informations suivantes :
2670 // en position 0 et 1 Xmin, Xmax et en position 2 Dx si < 0  2D
2671 // en position 3 et 4 Ymin, Ymax et en position 5 Dy si < 0  2D
2672 // en position 6 et 7 Zmin, Zmax et en position 8 Dz si < 0  2D
2673 //  9 distance max dans le maillage
2674 // =======================================================================
2675 std::vector<double> GetBoundingBoxInMedFile(const char * aFile)
2676 {
2677   std::vector<double> LesExtremes;
2678   med_err erreur = 0;
2679   med_idt medIdt;
2680   while (erreur == 0) {
2681     //  Ouverture du fichier
2682     medIdt = MEDfileOpen(aFile,MED_ACC_RDONLY);
2683     if (medIdt < 0) {
2684       erreur = 1;
2685       break;
2686     }
2687     //Nombre de maillage : on ne peut en lire qu'un seul
2688     med_int numberOfMeshes = MEDnMesh(medIdt);
2689     if (numberOfMeshes != 1) {
2690       erreur = 2;
2691       break;
2692     }
2693     // Caracteristiques du maillage
2694     char meshname[MED_NAME_SIZE+1];
2695     med_int spacedim,meshdim;
2696     med_mesh_type meshtype;
2697     char descriptionription[MED_COMMENT_SIZE+1];
2698     char dtunit[MED_SNAME_SIZE+1];
2699     med_sorting_type sortingtype;
2700     med_int nstep;
2701     med_axis_type axistype;
2702     int naxis = MEDmeshnAxis(medIdt,1);
2703     char *axisname=new char[naxis*MED_SNAME_SIZE+1];
2704     char *axisunit=new char[naxis*MED_SNAME_SIZE+1];
2705     erreur = MEDmeshInfo(medIdt,
2706                             1,
2707                             meshname,
2708                             &spacedim,
2709                             &meshdim,
2710                             &meshtype,
2711                             descriptionription,
2712                             dtunit,
2713                             &sortingtype,
2714                             &nstep,
2715                             &axistype,
2716                             axisname,
2717                             axisunit);
2718     delete[] axisname;
2719     delete[] axisunit;
2720     if (erreur < 0) { break; }
2721
2722     // Nombre de noeuds
2723     med_bool chgt,trsf;
2724     med_int nnoe  = MEDmeshnEntity(medIdt,
2725                               meshname,
2726                               MED_NO_DT,
2727                               MED_NO_IT,
2728                               MED_NODE,
2729                               MED_NO_GEOTYPE,
2730                               MED_COORDINATE,
2731                               MED_NO_CMODE,
2732                               &chgt,
2733                               &trsf);
2734     if (nnoe < 0) {
2735       erreur =  4;
2736       break;
2737     }
2738
2739     // Les coordonnees
2740     med_float* coo = (med_float*) malloc(sizeof(med_float)*nnoe*spacedim);
2741
2742     erreur = MEDmeshNodeCoordinateRd(medIdt,
2743                                       meshname,
2744                                       MED_NO_DT,
2745                                       MED_NO_IT,
2746                                       MED_NO_INTERLACE,
2747                                       coo);
2748     if (erreur < 0) {
2749       free(coo);
2750       break;
2751     }
2752
2753     // Calcul des extremes
2754     med_float xmin,xmax,ymin,ymax,zmin,zmax;
2755
2756     xmin = coo[0];
2757     xmax = coo[0];
2758     for (int i = 1; i < nnoe; i++) {
2759       xmin = std::min(xmin, coo[i]);
2760       xmax = std::max(xmax, coo[i]);
2761     }
2762     //
2763     if (spacedim > 1) {
2764       ymin = coo[nnoe];
2765       ymax = coo[nnoe];
2766       for (int i = nnoe + 1; i < 2*nnoe; i++) {
2767         ymin = std::min(ymin,coo[i]);
2768         ymax = std::max(ymax,coo[i]);
2769       }
2770     }
2771     else {
2772       ymin = 0;
2773       ymax = 0;
2774       zmin = 0;
2775       zmax = 0;
2776     }
2777     //
2778     if (spacedim > 2) {
2779       zmin = coo[2*nnoe];
2780       zmax = coo[2*nnoe];
2781       for (int i = 2*nnoe + 1; i < 3*nnoe; i++) {
2782         zmin = std::min(zmin,coo[i]);
2783         zmax = std::max(zmax,coo[i]);
2784       }
2785     }
2786     else {
2787       zmin = 0;
2788       zmax = 0;
2789     }
2790
2791     MESSAGE("_______________________________________");
2792     MESSAGE("xmin : " << xmin << " xmax : " << xmax);
2793     MESSAGE("ymin : " << ymin << " ymax : " << ymax);
2794     MESSAGE("zmin : " << zmin << " zmax : " << zmax);
2795     MESSAGE("_______________________________________");
2796     double epsilon = 1.e-6;
2797     LesExtremes.push_back(xmin);
2798     LesExtremes.push_back(xmax);
2799     LesExtremes.push_back(0);
2800     LesExtremes.push_back(ymin);
2801     LesExtremes.push_back(ymax);
2802     LesExtremes.push_back(0);
2803     LesExtremes.push_back(zmin);
2804     LesExtremes.push_back(zmax);
2805     LesExtremes.push_back(0);
2806
2807     double max1 = std::max (LesExtremes[1] - LesExtremes[0], LesExtremes[4] - LesExtremes[3]);
2808     double max2 = std::max (max1 , LesExtremes[7] - LesExtremes[6]);
2809     LesExtremes.push_back(max2);
2810
2811     // LesExtremes[0] = Xmini du maillage
2812     // LesExtremes[1] = Xmaxi du maillage
2813     // LesExtremes[2] = increment de progression en X
2814     // LesExtremes[3,4,5] : idem pour Y
2815     // LesExtremes[6,7,8] : idem pour Z
2816     // LesExtremes[9] = ecart maximal entre coordonnees
2817     // On fait un traitement pour dans le cas d'une coordonnee constante
2818     // inhiber ce cas en mettant un increment negatif
2819     //
2820     double diff = LesExtremes[1] - LesExtremes[0];
2821     if (fabs(diff) > epsilon*max2) { LesExtremes[2] = diff/100.; }
2822     else                           { LesExtremes[2] = -1.; }
2823
2824     diff = LesExtremes[4] - LesExtremes[3];
2825     if (fabs(diff) > epsilon*max2) { LesExtremes[5]=diff/100.; }
2826     else                           { LesExtremes[5] = -1.; }
2827
2828     diff = LesExtremes[7] - LesExtremes[6];
2829     if (fabs(diff) > epsilon*max2) { LesExtremes[8]=diff/100.; }
2830     else                           { LesExtremes[8] = -1.;  }
2831
2832     MESSAGE ("_______________________________________");
2833     MESSAGE ("xmin : " << LesExtremes[0] << " xmax : " << LesExtremes[1] << " xincr : " << LesExtremes[2]);
2834     MESSAGE ("ymin : " << LesExtremes[3] << " ymax : " << LesExtremes[4] << " yincr : " << LesExtremes[5]);
2835     MESSAGE ("zmin : " << LesExtremes[6] << " zmax : " << LesExtremes[7] << " zincr : " << LesExtremes[8]);
2836     MESSAGE ("dmax : " << LesExtremes[9]);
2837     MESSAGE ("_______________________________________");
2838
2839     free(coo);
2840     break;
2841   }
2842   // Fermeture du fichier
2843   if (medIdt > 0) MEDfileClose(medIdt);
2844
2845   return  LesExtremes;
2846 }
2847
2848 }; // namespace SMESHHOMARD_I