Salome HOME
f48fb7e734bae2fc805a6e64b04d700c371a2260
[modules/homard.git] / src / HOMARD / YACSDriver.cxx
1 //  HOMARD HOMARD : implementation of HOMARD idl descriptions
2 //
3 // Copyright (C) 2011-2013  CEA/DEN, EDF R&D
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 //
19 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 //
21
22 // Pilote l'ecriture du fichier xml pour lancer un schema YACS
23
24 #include <cstring>
25 #include <unistd.h>
26 #include <sys/stat.h>
27
28 #include "Utils_SALOME_Exception.hxx"
29 #include "utilities.h"
30 #include "YACSDriver.hxx"
31
32 //=============================================================================
33 //=============================================================================
34 YACSDriver::YACSDriver(const std::string YACSFile, const std::string DirName):
35   _YACSFile( "" ), _DirName( "" ),
36   _Texte( "" ),
37   _Texte_parametres( "" ),
38   _bLu( false )
39 {
40   MESSAGE("YACSFile = "<<YACSFile<<", DirName ="<<DirName);
41   _YACSFile = YACSFile;
42   _DirName = DirName;
43 }
44 //=============================================================================
45 //=============================================================================
46 YACSDriver::~YACSDriver()
47 {
48 }
49 //===============================================================================
50 // Ajout d'une ligne simple
51 //===============================================================================
52 void YACSDriver::TexteAdd( const std::string ligne )
53 {
54 //   MESSAGE("TexteAdd, ligne ="<<ligne);
55 //
56   _Texte += ligne + "\n" ;
57 //
58 }
59 //===============================================================================
60 // Nom du fichier du maillage initial
61 //===============================================================================
62 void YACSDriver::Texte_DataInit_MeshFile( const std::string Meshfile )
63 {
64   MESSAGE("TexteInitMeshfile, Meshfile ="<<Meshfile);
65 //
66   _Texte += "         <value><string>" ;
67   _Texte += Meshfile ;
68   _Texte += "</string></value>\n" ;
69 //
70 }
71 //===============================================================================
72 // Le repertoire de calcul
73 // Le script de lancement
74 //===============================================================================
75 void YACSDriver::Texte_Alternance_Calcul_HOMARD_Calcul( const std::string FileName )
76 {
77   MESSAGE("Texte_Alternance_Calcul_HOMARD_Calcul, FileName : "<<FileName);
78 //
79   int position = FileName.find_last_of( '/' ) ;
80   std::string nomfic = FileName.substr( position+1 ) ;
81   position = nomfic.find_last_of( '.' ) ;;
82   nomfic = nomfic.substr( 0, position ) ;
83   MESSAGE("nomfic : "<<nomfic) ;
84 //
85   _Texte += "rep_calc = \"" + _DirName + "\"\n" ;
86   _Texte += "rep_script = os.path.dirname(\"" + FileName + "\")\n" ;
87   _Texte += "sys.path.append(rep_script)\n" ;
88   _Texte += "from " + nomfic + " import LanceCas\n" ;
89 //
90 }
91 //===============================================================================
92 // Les options du cas
93 //===============================================================================
94 void YACSDriver::Texte_HOMARD_Init_au_debut_Case_Options( const std::string pythonTexte )
95 {
96   MESSAGE("Texte_HOMARD_Init_au_debut_Case_Options, pythonTexte\n"<<pythonTexte);
97 //
98   _Texte += "DirName = \"" + _DirName + "/HOMARD\"\n" ;
99   _Texte += "Case.SetDirName(DirName)\n" ;
100
101   Texte_python( pythonTexte, 1, "Case" ) ;
102 //
103 }
104 //===============================================================================
105 // La description des zones
106 // ZoneType : le type de la zone
107 // pythonZone : le python correspondant a la zone
108 // methode : methode associee a la creation de la zone
109 // ZoneName : nom de la zone
110 // noeud_1 : noeud de depart
111 //===============================================================================
112 std::string YACSDriver::Texte_HOMARD_Init_au_debut_Zone( int ZoneType, const std::string pythonZone, const std::string methode, const std::string ZoneName, const std::string noeud_1 )
113 {
114   MESSAGE("Texte_HOMARD_Init_au_debut_Zone, ZoneType = "<<ZoneType<<", pythonZone = "<<pythonZone);
115   MESSAGE("methode = "<<methode<<", ZoneName = "<<ZoneName<<", noeud_1 = "<<noeud_1 );
116 //
117 // 1. Le nom du noeud
118   std::string noeud_2 = methode + "_" + ZoneName ;
119   std::string node = "Tant_que_le_calcul_n_a_pas_converge.Alternance_Calcul_HOMARD.Adaptation.p0_Adaptation_HOMARD.HOMARD_Initialisation.p1_HOMARD_Init_au_debut." ;
120   node += noeud_2 ;
121 // 2. Texte de controle
122   std::string texte_control = Texte_control (noeud_1, noeud_2) ;
123 // 3. Definition du service
124   _Texte += "                           <service name=\"" + noeud_2 + "\">\n" ;
125   _Texte += "                              <node>Etude_Initialisation.SetCurrentStudy</node>\n" ;
126   _Texte += "                              <method>" + methode + "</method>\n" ;
127 // 4. Les inports
128 // 4.1. Le nom de la zone
129   _Texte += Texte_inport( "string", "ZoneName" ) ;
130    TexteParametre( node, "ZoneName", "string", ZoneName ) ;
131 // 4.2. Les valeurs numeriques
132 //      ATTENTION : les noms doivent etre les memes que dans Gen.xml, donc HOMARD_Gen.idl
133 // 4.2.1. Decodage des valeurs
134 // La chaine pythonZone est de ce genre :
135 //   CreateZoneBox( "Zone_1", 0.144, 0.216, 0.096, 0.1464, 0.076, 0.12)
136   std::string ligne = pythonZone ;
137 // On commence par ne garder que ce qui suit la premiere virgule
138   ligne = GetStringInTexte( ligne, ",", 1 );
139 // On boucle pour isoler toutes les chaines dans les virgules
140   std::string lignebis ;
141   std::string x0, x1, x2, x3, x4, x5, x6, x7, x8  ;
142   int iaux = 0  ;
143   while ( ligne != lignebis )
144   {
145     lignebis = GetStringInTexte ( ligne, ",", 0 ) ;
146 //     MESSAGE("lignebis = "<<lignebis );
147     if      ( iaux == 0 ) { x0 = lignebis ; }
148     else if ( iaux == 1 ) { x1 = lignebis ; }
149     else if ( iaux == 2 ) { x2 = lignebis ; }
150     else if ( iaux == 3 ) { x3 = lignebis ; }
151     else if ( iaux == 4 ) { x4 = lignebis ; }
152     else if ( iaux == 5 ) { x5 = lignebis ; }
153     else if ( iaux == 6 ) { x6 = lignebis ; }
154     else if ( iaux == 7 ) { x7 = lignebis ; }
155     ligne = GetStringInTexte( ligne, ",", 1 );
156     iaux += 1 ;
157   }
158 // La derniere valeur est toujours mise dans x8
159   x8 = GetStringInTexte ( ligne, ")", 0 ) ;
160   MESSAGE("coor = "<< x0<<","<<x1<< ","<< x2<< ","<< x3<<","<<x4<<","<<x5<<","<<x6<<","<<x7<<","<<x8);
161 // 4.2. Cas du parallelepipede (2)
162   if ( ZoneType == 2 )
163   {
164     _Texte += Texte_inport( "double", "Xmini" ) ;
165     _Texte += Texte_inport( "double", "Xmaxi" ) ;
166     _Texte += Texte_inport( "double", "Ymini" ) ;
167     _Texte += Texte_inport( "double", "Ymaxi" ) ;
168     _Texte += Texte_inport( "double", "Zmini" ) ;
169     _Texte += Texte_inport( "double", "Zmaxi" ) ;
170     TexteParametre( node, "Xmini", "double", x0 ) ;
171     TexteParametre( node, "Xmaxi", "double", x1 ) ;
172     TexteParametre( node, "Ymini", "double", x2 ) ;
173     TexteParametre( node, "Ymaxi", "double", x3 ) ;
174     TexteParametre( node, "Zmini", "double", x4 ) ;
175     TexteParametre( node, "Zmaxi", "double", x8 ) ;
176   }
177 //
178 // 4.2. Cas du rectangle (11, 12, 13)
179   else if ( ( ZoneType > 10 ) and ( ZoneType < 14 ) )
180   {
181     _Texte += Texte_inport( "double", "Umini" ) ;
182     _Texte += Texte_inport( "double", "Umaxi" ) ;
183     _Texte += Texte_inport( "double", "Vmini" ) ;
184     _Texte += Texte_inport( "double", "Vmaxi" ) ;
185     _Texte += Texte_inport( "long", "Orient" ) ;
186     TexteParametre( node, "Umini", "double", x0 ) ;
187     TexteParametre( node, "Umaxi", "double", x1 ) ;
188     TexteParametre( node, "Vmini", "double", x2 ) ;
189     TexteParametre( node, "Vmaxi", "double", x3 ) ;
190     TexteParametre( node, "Orient", "int", x8 ) ;
191   }
192 //
193 // 4.2. Cas du disque (31, 32, 33) ou du disque perce (61, 62, 63)
194   else if ( ( ( ZoneType > 30 ) and ( ZoneType < 34 ) ) or ( ( ZoneType > 60 ) and ( ZoneType < 64 ) ) )
195   {
196     _Texte += Texte_inport( "double", "Ucentre" ) ;
197     _Texte += Texte_inport( "double", "Vcentre" ) ;
198     _Texte += Texte_inport( "double", "Radius" ) ;
199     TexteParametre( node, "Ucentre", "double", x0 ) ;
200     TexteParametre( node, "Vcentre", "double", x1 ) ;
201     TexteParametre( node, "Radius", "double", x2 ) ;
202     if ( ZoneType > 60 )
203     {
204       _Texte += Texte_inport( "double", "InternalRadius" ) ;
205       TexteParametre( node, "InternalRadius", "double", x3 ) ;
206     }
207     _Texte += Texte_inport( "long", "Orient" ) ;
208     TexteParametre( node, "Orient", "int", x8 ) ;
209   }
210 //
211 // 4.2. Cas de la sphere (4)
212   else if ( ZoneType == 4 )
213   {
214     _Texte += Texte_inport( "double", "Xcentre" ) ;
215     _Texte += Texte_inport( "double", "Ycentre" ) ;
216     _Texte += Texte_inport( "double", "Zcentre" ) ;
217     _Texte += Texte_inport( "double", "Radius" ) ;
218     TexteParametre( node, "Xcentre", "double", x0 ) ;
219     TexteParametre( node, "Ycentre", "double", x1 ) ;
220     TexteParametre( node, "Zcentre", "double", x2 ) ;
221     TexteParametre( node, "Radius", "double", x8 ) ;
222   }
223 //
224 // 4.2. Cas du cylindre (5) ou du tuyau (7)
225   else if ( ZoneType == 5 or ZoneType == 7 )
226   {
227     _Texte += Texte_inport( "double", "Xcentre" ) ;
228     _Texte += Texte_inport( "double", "Ycentre" ) ;
229     _Texte += Texte_inport( "double", "Zcentre" ) ;
230     _Texte += Texte_inport( "double", "Xaxis" ) ;
231     _Texte += Texte_inport( "double", "Yaxis" ) ;
232     _Texte += Texte_inport( "double", "Zaxis" ) ;
233     _Texte += Texte_inport( "double", "Radius" ) ;
234     _Texte += Texte_inport( "double", "Height" ) ;
235     TexteParametre( node, "Xcentre", "double", x0 ) ;
236     TexteParametre( node, "Ycentre", "double", x1 ) ;
237     TexteParametre( node, "Zcentre", "double", x2 ) ;
238     TexteParametre( node, "Xaxis", "double", x3 ) ;
239     TexteParametre( node, "Yaxis", "double", x4 ) ;
240     TexteParametre( node, "Zaxis", "double", x5 ) ;
241     TexteParametre( node, "Radius", "double", x6 ) ;
242     if ( ZoneType == 5 )
243     {
244       TexteParametre( node, "Height", "double", x8 ) ;
245     }
246     else
247     {
248       _Texte += Texte_inport( "double", "InternalRadius" ) ;
249       TexteParametre( node, "Height", "double", x7 ) ;
250       TexteParametre( node, "InternalRadius", "double", x8 ) ;
251     }
252   }
253 //
254 // 4.2. Erreur
255   else
256   { ASSERT("Type de zone inconnu." == 0); }
257
258 //
259 // 5. La fin
260   _Texte += "                              <outport name=\"return\" type=\"HOMARD_Zone\"/>\n" ;
261   _Texte += "                           </service>\n" ;
262 //
263   return texte_control ;
264 //
265 }
266 //===============================================================================
267 // Controle des enchainements de noeud dans le noeud HOMARD_Init_au_debut
268 //===============================================================================
269   std::string YACSDriver::Texte_HOMARD_Init_au_debut_control()
270 {
271   MESSAGE("Texte_HOMARD_Init_au_debut_control");
272 //
273   std::string texte ;
274   texte  = Texte_control ("CreateCase", "Case_Options") ;
275   texte += Texte_control ("Case_Options", "CreateHypothesis") ;
276 //
277   return texte ;
278 //
279 }
280 //===============================================================================
281 // Controle des enchainements de noeuds
282 // noeud_1 : noeud de depart
283 // noeud_2 : noeud d'arrivee
284 //===============================================================================
285   std::string YACSDriver::Texte_control( const std::string noeud_1, const std::string noeud_2 )
286 {
287   MESSAGE("Texte_control, noeud_1 = "<<noeud_1<<", noeud_2 = "<<noeud_2);
288 //
289   std::string texte ;
290   texte  = "                           <control> " ;
291   texte += "<fromnode>" + noeud_1 + "</fromnode>" ;
292   texte += " <tonode>"  + noeud_2 + "</tonode>" ;
293   texte += " </control>\n" ;
294
295   return texte ;
296 //
297 }
298 //===============================================================================
299 // Inport
300 // inport_type : type de la donnee a importer
301 // inport_nom : nom de la donnee a importer
302 //===============================================================================
303   std::string YACSDriver::Texte_inport( const std::string inport_type, const std::string inport_nom )
304 {
305 //   MESSAGE("Texte_control, inport_type = "<<inport_type<<", inport_nom = "<<inport_nom);
306 //
307   std::string texte ;
308   texte  = "                              <inport " ;
309   texte += "name=\"" + inport_nom + "\" " ;
310   texte += "type=\"" + inport_type + "\"" ;
311   texte += "/>\n" ;
312
313   return texte ;
314 //
315 }
316 //===============================================================================
317 // Le repertoire d'execution
318 //===============================================================================
319 void YACSDriver::Texte_HOMARD_Exec_DirName( )
320 {
321   MESSAGE("Texte_HOMARD_Exec_DirName");
322 //
323   _Texte += "DirName = \"" + _DirName + "\"\n" ;
324 //
325 }
326 //===============================================================================
327 // Manipulation des instructions python
328 // pythonTexte : le texte des instructions python a manipuler
329 // indice : numero de la premiere ligne voulue
330 // concept : nom du concept a inserer
331 //===============================================================================
332 void YACSDriver::Texte_python( const std::string pythonTexte, int indice, const std::string concept )
333 {
334   MESSAGE("Texte_python, pythonTexte\n"<<pythonTexte);
335   MESSAGE("indice = "<<indice<<", concept = "<<concept);
336 //
337 // Conversion de type
338   std::istringstream tout (pythonTexte) ;
339 //   MESSAGE("\ntout :"<<tout);
340   std::string ligne; // variable contenant chaque ligne de python
341   std::string ligne_bis ; // variable contenant la portion de ligne de python apres '.'
342   int cptr = 0 ;
343   indice -= 1 ;
344   while ( std::getline( tout, ligne ) )
345   {
346     if ( cptr > indice )
347     {
348       int position = ligne.find_first_of( "." ) ;
349 //       MESSAGE("\nposition : "<< position);
350       if ( position > 0 )
351       {
352         ligne_bis = ligne.substr( position );
353 //         MESSAGE("\nligne_bis : "<< ligne_bis);
354         _Texte += concept + ligne_bis + "\n" ;
355       }
356     }
357     cptr += 1 ;
358   }
359 //
360 }
361 //===============================================================================
362 // Creation d'un parametre
363 //===============================================================================
364 void YACSDriver::TexteParametre( const std::string node, const std::string port, const std::string type_value, const std::string value )
365 {
366 //
367 //   MESSAGE("TexteParametre");
368   _Texte_parametres += "   <parameter>\n" ;
369   _Texte_parametres += "      <tonode>" + node + "</tonode>" ;
370   _Texte_parametres += "<toport>" + port + "</toport>\n" ;
371   _Texte_parametres += "      <value><" + type_value + ">" + value + "</" + type_value + "></value>\n" ;
372   _Texte_parametres += "   </parameter>\n" ;
373 //
374 }
375 //===============================================================================
376 // Ajout des parametres
377 //===============================================================================
378 void YACSDriver::TexteAddParametres( )
379 {
380 //
381   MESSAGE("TexteAddParametres");
382   TexteAdd(_Texte_parametres) ;
383 //
384 }
385 //===============================================================================
386 void YACSDriver::CreeFichier( )
387 {
388 //
389   MESSAGE("CreeFichier sur le fichier "<<_YACSFile);
390   std::ofstream Fic(_YACSFile.c_str(), std::ios::out ) ;
391   if (Fic.is_open() == true) { Fic << _Texte << std::endl ; }
392   Fic.close() ;
393 //
394 }
395 //===============================================================================
396 // REMARQUE : on devrait utiliser le GetStringInTexte de HOMARD_Gen_i mais je ne sais pas
397 //            comment l'appeler. ALors je clone.
398 // Recuperation de la chaine de caracteres par rapport l'apparition d'un texte
399 // ligne : la ligne a manipuler
400 // texte : le texte a reperer
401 // option : 0 : la chaine avant le texte
402 //          1 : la chaine apres le texte
403 // Si le texte est absent, on retourne la chaine totale
404 //===============================================================================
405 std::string YACSDriver::GetStringInTexte( const std::string ligne, const std::string texte, int option )
406 {
407 //   MESSAGE("GetStringInTexte, recherche de '"<<texte<<"' dans '"<<ligne<<"'"<<", option = "<<option);
408 //
409   std::string chaine = ligne ;
410   int position = ligne.find_first_of( texte ) ;
411   if ( position > 0 )
412   {
413     if ( option == 0 ) { chaine = ligne.substr( 0, position ) ; }
414     else               { chaine = ligne.substr( position+1 ) ; }
415   }
416 // Conversion de type
417   return chaine ;
418 //
419 }