Salome HOME
Merge from V6_main 01/04/2013
[modules/homard.git] / src / HOMARD / HOMARD_DriverTools.cxx
1 // Copyright (C) 2011-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 //  File   : HOMARD_DriverTools.cxx
20 //  Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
21 //
22 // ----------------------------------------------------------------------------
23
24 #include "HOMARD_DriverTools.hxx"
25 #include "HOMARD_Boundary.hxx"
26 #include "HOMARD_Cas.hxx"
27 #include "HOMARD_Hypothesis.hxx"
28 #include "HOMARD_Iteration.hxx"
29 #include "HOMARD_Zone.hxx"
30 #include <sstream>
31 #include <cstdlib>
32 #include "utilities.h"
33
34 namespace HOMARD
35 {
36
37   const char* const SEPARATOR = "|";
38
39   /*!
40     \brief Read next chunk of data from the string
41     \internal
42
43     The function tries to read next chunk of the data from the input string \a str.
44     The parameter \a start specifies the start position of next chunk. If the operation
45     read the chunk successfully, after its completion this parameter will refer to the
46     start position of the next chunk. The function returns resulting chunk as a string.
47     The status of the operation is returned via \a ok parameter.
48
49     \param str source data stream string
50     \param start start position to get next chunk
51     \param ok in this variable the status of the chunk reading operation is returned
52     \return next chunk read from the string
53   */
54   static std::string getNextChunk( const std::string& str, std::string::size_type& start, bool& ok )
55   {
56     std::string chunk = "";
57     ok = false;
58     if ( start <= str.size() ) {
59       std::string::size_type end = str.find( separator(), start );
60       chunk = str.substr( start, end == std::string::npos ? std::string::npos : end-start );
61       start = end == std::string::npos ? str.size()+1 : end + separator().size();
62       ok = true;
63     }
64     return chunk;
65   }
66
67   /*!
68     \brief Get persistence signature
69     \param type persistence entity type
70     \return persistence signature
71   */
72   std::string GetSignature( SignatureType type )
73   {
74     std::string signature = "";
75     switch ( type ) {
76     case Case:       signature = "CASE"; break;
77     case Zone:       signature = "ZONE"; break;
78     case Hypothesis: signature = "HYPO"; break;
79     case Iteration:  signature = "ITER"; break;
80     case Boundary:   signature = "BOUNDARY"; break;
81     default: break;
82     }
83     signature += separator();
84     return signature;
85   }
86
87   /*!
88     \brief Get data separator
89     \return string that is used to separate data entities in the stream
90   */
91   std::string separator()
92   {
93     return std::string( SEPARATOR );
94   }
95
96 // =======================
97 // Case
98 // =======================
99   /*!
100     \brief Dump case to the string
101     \param cas case being dumped
102     \return string representation of the case
103   */
104   std::string Dump( const HOMARD_Cas& cas )
105   {
106     std::stringstream os;
107     std::string saux ;
108     // ...
109     MESSAGE( ". Sauvegarde du cas "<<cas.GetName());
110     os << cas.GetName();
111     os << separator() << cas.GetDirName();
112     os << separator() << cas.GetConfType();
113
114     std::vector<double> coor = cas.GetBoundingBox();
115     os << separator() << coor.size();
116     for ( int i = 0; i < coor.size(); i++ )
117           os << separator() << coor[i];
118
119     std::list<std::string> ListString = cas.GetIterations();
120     os << separator() << ListString.size();
121     std::list<std::string>::const_iterator it;
122     for ( it = ListString.begin(); it != ListString.end(); ++it )
123           os << separator() << *it;
124
125     ListString = cas.GetGroups();
126     os << separator() << ListString.size();
127     for ( it = ListString.begin(); it != ListString.end(); ++it )
128          os << separator() << *it;
129     ListString = cas.GetBoundaryGroup();
130     os << separator() << ListString.size();
131     for ( it = ListString.begin(); it != ListString.end(); ++it )
132          os << separator() << *it;
133
134     os << separator() << cas.GetPyram();
135
136     saux = os.str();
137 //     MESSAGE( ". Fin avec "<<saux);
138     return saux ;
139   }
140 //
141 // Iteration
142 // ==========
143 //
144   /*!
145     \brief Dump iteration to the string
146     \param iteration iteration being dumped
147     \return string representation of the iteration
148   */
149   std::string Dump( const HOMARD_Iteration& iteration )
150   {
151     std::stringstream os;
152     std::string saux ;
153     // ...
154     MESSAGE( ". Sauvegarde de l'iteration "<<iteration.GetName());
155     os << iteration.GetName();
156     os << separator() << iteration.GetEtat();
157     os << separator() << iteration.GetNumber();
158     os << separator() << iteration.GetMeshFile();
159     os << separator() << iteration.GetLogFile();
160     os << separator() << iteration.GetMeshName();
161     os << separator() << iteration.GetFieldFile();
162     os << separator() << iteration.GetTimeStep();
163     os << separator() << iteration.GetRank();
164     os << separator() << iteration.GetIterParentName();
165     //
166     std::list<std::string> ListString = iteration.GetIterations();
167     os << separator() << ListString.size();
168     std::list<std::string>::const_iterator it;
169     for ( it = ListString.begin(); it != ListString.end(); ++it )
170       os << separator() << *it;
171
172     os << separator() << iteration.GetHypoName();
173     os << separator() << iteration.GetCaseName();
174     os << separator() << iteration.GetDirName();
175
176     saux = os.str();
177 //     MESSAGE( ". Fin avec "<<saux);
178     return saux ;
179   }
180 //
181 // hypothese
182 // ==============================
183   /*!
184     \brief Dump hypothesis to the string
185     \param hypothesis hypothesis being dumped
186     \return string representation of the hypothesis
187   */
188   std::string Dump( const HOMARD_Hypothesis& hypothesis )
189   {
190     std::stringstream os;
191     std::string saux ;
192     // ...
193     MESSAGE( ". Sauvegarde de l'hypothese "<<hypothesis.GetName());
194     os << hypothesis.GetName();
195     os << separator() << hypothesis.GetCaseCreation();
196     os << separator() << hypothesis.GetAdapType();
197     os << separator() << hypothesis.GetRefinType();
198     os << separator() << hypothesis.GetUnRefType();
199     os << separator() << hypothesis.GetFieldName();
200     os << separator() << hypothesis.GetRefinThrType();
201     os << separator() << hypothesis.GetThreshR();
202     os << separator() << hypothesis.GetUnRefThrType();
203     os << separator() << hypothesis.GetThreshC();
204     os << separator() << hypothesis.GetUseField();
205     os << separator() << hypothesis.GetUseComp();
206     os << separator() << hypothesis.GetTypeFieldInterp();
207
208     std::list<std::string> ListString = hypothesis.GetIterations();
209     std::list<std::string>::const_iterator it;
210     os << separator() << ListString.size();
211     for ( it = ListString.begin(); it != ListString.end(); ++it )
212          os << separator() << *it;
213
214     ListString = hypothesis.GetZones();
215     os << separator() << ListString.size();
216     for ( it = ListString.begin(); it != ListString.end(); ++it )
217           os << separator() << *it;
218
219     ListString = hypothesis.GetListComp();
220     os << separator() << ListString.size();
221     for ( it = ListString.begin(); it != ListString.end(); ++it )
222          os << separator() << *it;
223
224     ListString = hypothesis.GetGroups();
225     os << separator() << ListString.size();
226     for ( it = ListString.begin(); it != ListString.end(); ++it )
227           os << separator() << *it;
228
229     ListString = hypothesis.GetListFieldInterp();
230     os << separator() << ListString.size();
231     for ( it = ListString.begin(); it != ListString.end(); ++it )
232           os << separator() << *it;
233
234     os << separator() << hypothesis.GetNivMax();
235     os << separator() << hypothesis.GetDiamMin();
236     os << separator() << hypothesis.GetAdapInit();
237     os << separator() << hypothesis.GetLevelOutput();
238
239     saux = os.str();
240 //     MESSAGE( ". Fin avec "<<saux);
241     return saux ;
242   }
243 //
244 // Zone
245 // =========================
246
247   /*!
248     \brief Dump zone to the string
249     \param zone zone being dumped
250     \return string representation of the zone
251   */
252   std::string Dump( const HOMARD_Zone& zone )
253   {
254     std::stringstream os;
255     std::string saux ;
256     MESSAGE( ". Sauvegarde de la zone "<<zone.GetName());
257     os << zone.GetName();
258     os << separator() << zone.GetType();
259
260     std::vector<double> coords = zone.GetCoords();
261     for ( int i = 0; i < coords.size(); i++ )
262       os << separator() << ( i < coords.size() ? coords[i] : 0. );
263
264     std::vector<double> limit = zone.GetLimit();
265     for ( int i = 0; i < 3; i++ )
266       os << separator() << ( i < limit.size() ? limit[i] : 0. );
267
268     std::list<std::string> hypos = zone.GetHypo();
269     os << separator() << hypos.size();
270     std::list<std::string>::const_iterator it;
271     for ( it = hypos.begin(); it != hypos.end(); ++it )
272       os << separator() << *it;
273
274     saux = os.str();
275 //     MESSAGE( ". Fin avec "<<saux);
276     return saux ;
277   }
278 //
279 // 1.5. Archivage d'une frontiere
280 // ==============================
281
282   /*!
283     \brief Dump boundary to the string
284     \param boundary boundary being dumped
285     \return string representation of the boundary
286   */
287   std::string Dump( const HOMARD_Boundary& boundary )
288   {
289     std::stringstream os;
290     std::string saux ;
291     MESSAGE( ". Sauvegarde de la frontiere "<<boundary.GetName());
292
293     int BoundaryType = boundary.GetType() ;
294
295     os << boundary.GetName() ;
296     os << separator() << BoundaryType ;
297     os << separator() << boundary.GetCaseCreation() ;
298
299     if ( BoundaryType == 0 )
300     {
301       os << separator() << boundary.GetMeshName();
302       os << separator() << boundary.GetMeshFile();
303     }
304     else {
305       std::vector<double> coor = boundary.GetCoords() ;
306       for ( int i = 0; i < coor.size(); i++ )
307             os << separator() << coor[i];
308       std::vector<double> limit = boundary.GetLimit();
309       for ( int i = 0; i < limit.size(); i++ )
310             os << separator() << limit[i];
311     }
312
313     std::list<std::string> ListString = boundary.GetGroups();
314     std::list<std::string>::const_iterator it;
315     os << separator() << ListString.size();
316     for ( it = ListString.begin(); it != ListString.end(); ++it )
317           os << separator() << *it;
318
319     saux = os.str();
320 //     MESSAGE( ". Fin avec "<<saux);
321     return saux ;
322   }
323
324 //
325 // Restauration des objets
326 // ==========================
327 // Case
328 // ==========================
329 //
330   /*!
331     \brief Restore case from the string
332     \param cas case being restored
333     \param stream string representation of the case
334     \return \c true if case is correctly restored or \c false otherwise
335   */
336   bool Restore( HOMARD_Cas& cas, const std::string& stream )
337   {
338     MESSAGE( ". Restoration du cas ");
339     std::string::size_type start = 0;
340     std::string chunk, chunkNext;
341     bool ok;
342     // ...
343     chunk = getNextChunk( stream, start, ok );
344     if ( !ok ) return false;
345     cas.SetName( chunk.c_str() );
346
347     chunk = getNextChunk( stream, start, ok );
348     if ( !ok ) return false;
349     cas.SetDirName( chunk.c_str() );
350
351     chunk = getNextChunk( stream, start, ok );
352     if ( !ok ) return false;
353     cas.SetConfType( atoi( chunk.c_str() ) );
354
355     chunk = getNextChunk( stream, start, ok );
356     if ( !ok ) return false;
357
358     int size = atoi( chunk.c_str() );
359     std::vector<double> boite;
360     boite.resize( size );
361     for ( int i = 0; i < size; i++ ) {
362       chunk = getNextChunk( stream, start, ok );
363       if ( !ok ) return false;
364       boite[i] = strtod( chunk.c_str(), 0 );
365     }
366     cas.SetBoundingBox( boite );
367
368     chunk = getNextChunk( stream, start, ok );
369     if ( !ok ) return false;
370
371     size = atoi( chunk.c_str() );
372     for ( int i = 0; i < size; i++ ) {
373       chunk = getNextChunk( stream, start, ok );
374       if ( !ok ) return false;
375       cas.AddIteration( chunk.c_str() );
376     }
377
378     chunk = getNextChunk( stream, start, ok );
379     if ( !ok ) return false;
380     size = atoi( chunk.c_str() );
381     for ( int i = 0; i < size; i++ )
382     {
383       chunk = getNextChunk( stream, start, ok );
384       if ( !ok ) return false;
385       cas.AddGroup( chunk.c_str() );
386     }
387
388     chunk = getNextChunk( stream, start, ok );
389     if ( !ok ) return false;
390     size = atoi( chunk.c_str() );
391     for ( int i = 0; i < size; i++ ) {
392       chunk = getNextChunk( stream, start, ok );
393       if ( !ok ) return false;
394       i++;
395       chunkNext = getNextChunk( stream, start, ok );
396       if ( !ok ) return false;
397       cas.AddBoundaryGroup( chunk.c_str(), chunkNext.c_str() );
398     }
399
400     chunk = getNextChunk( stream, start, ok );
401     if ( !ok ) return false;
402     cas.SetPyram( atoi( chunk.c_str() ) );
403
404     return true;
405   }
406 //
407 //  Iteration
408 // =================================
409   /*!
410     \brief Restore iteration from the string
411     \param iteration iteration being restored
412     \param stream string representation of the iteration
413     \return \c true if iteration is correctly restored or \c false otherwise
414   */
415   bool Restore( HOMARD_Iteration& iteration, const std::string& stream )
416   {
417     std::string::size_type start = 0;
418     std::string chunk;
419     bool ok;
420     chunk = getNextChunk( stream, start, ok );
421     if ( !ok ) return false;
422
423     iteration.SetName( chunk.c_str() );
424     chunk = getNextChunk( stream, start, ok );
425     if ( !ok ) return false;
426     iteration.SetEtat( (bool)atoi( chunk.c_str() ) );
427     chunk = getNextChunk( stream, start, ok );
428     if ( !ok ) return false;
429     iteration.SetNumber( atoi( chunk.c_str() ) );
430     chunk = getNextChunk( stream, start, ok );
431     if ( !ok ) return false;
432     iteration.SetMeshFile( chunk.c_str() );
433     chunk = getNextChunk( stream, start, ok );
434     if ( !ok ) return false;
435     iteration.SetLogFile( chunk.c_str() );
436     chunk = getNextChunk( stream, start, ok );
437     if ( !ok ) return false;
438     iteration.SetMeshName( chunk.c_str() );
439     chunk = getNextChunk( stream, start, ok );
440     if ( !ok ) return false;
441     iteration.SetFieldFile( chunk.c_str() );
442     // .
443     int timestep, rank;
444     chunk = getNextChunk( stream, start, ok );
445     if ( !ok ) return false;
446     timestep = atoi( chunk.c_str() );
447     chunk = getNextChunk( stream, start, ok );
448     if ( !ok ) return false;
449     rank = atoi( chunk.c_str() );
450     iteration.SetTimeStepRank( timestep, rank );
451     chunk = getNextChunk( stream, start, ok );
452     if ( !ok ) return false;
453     iteration.SetIterParentName( chunk.c_str() );
454     //
455     chunk = getNextChunk( stream, start, ok );
456     if ( !ok ) return false;
457     int size = atoi( chunk.c_str() );
458     for ( int i = 0; i < size; i++ ) {
459       chunk = getNextChunk( stream, start, ok );
460       if ( !ok ) return false;
461       iteration.LinkNextIteration( chunk.c_str() );
462     }
463     //
464     chunk = getNextChunk( stream, start, ok );
465     if ( !ok ) return false;
466     iteration.SetHypoName( chunk.c_str() );
467     chunk = getNextChunk( stream, start, ok );
468     if ( !ok ) return false;
469     iteration.SetCaseName( chunk.c_str() );
470     chunk = getNextChunk( stream, start, ok );
471     if ( !ok ) return false;
472     iteration.SetDirName( chunk.c_str() );
473     return true;
474   }
475
476 //
477 // hypothese
478 // =================================
479   /*!
480     \brief Restore hypothesis from the string
481     \param hypothesis hypothesis being restored
482     \param stream string representation of the hypothesis
483     \return \c true if hypothesis is correctly restored or \c false otherwise
484   */
485   bool Restore( HOMARD_Hypothesis& hypothesis, const std::string& stream )
486   {
487     std::string::size_type start = 0;
488     std::string chunk, chunkNext;
489     bool ok;
490
491     chunk = getNextChunk( stream, start, ok );
492     if ( !ok ) return false;
493     hypothesis.SetName( chunk.c_str() );
494
495     chunk = getNextChunk( stream, start, ok );
496     if ( !ok ) return false;
497     hypothesis.SetCaseCreation( chunk.c_str() );
498
499     chunk = getNextChunk( stream, start, ok );
500     if ( !ok ) return false;
501     hypothesis.SetAdapType( atoi( chunk.c_str() ) );
502
503     chunk = getNextChunk( stream, start, ok );
504     if ( !ok ) return false;
505     int typeraff = atoi( chunk.c_str() );
506     chunk = getNextChunk( stream, start, ok );
507     if ( !ok ) return false;
508     int typedera = atoi( chunk.c_str() );
509     hypothesis.SetRefinTypeDera( typeraff, typedera );
510
511     chunk = getNextChunk( stream, start, ok );
512     if ( !ok ) return false;
513     hypothesis.SetField( chunk.c_str() );
514
515     chunk = getNextChunk( stream, start, ok );
516     if ( !ok ) return false;
517     int typethr = atoi( chunk.c_str() );
518     chunk = getNextChunk( stream, start, ok );
519     if ( !ok ) return false;
520     double threshr = strtod( chunk.c_str(), 0 );
521     hypothesis.SetRefinThr( typethr, threshr );
522
523     chunk = getNextChunk( stream, start, ok );
524     if ( !ok ) return false;
525     int typethc = atoi( chunk.c_str() );
526     chunk = getNextChunk( stream, start, ok );
527     if ( !ok ) return false;
528     double threshc = strtod( chunk.c_str(), 0 );
529     hypothesis.SetUnRefThr( typethc, threshc );
530
531     chunk = getNextChunk( stream, start, ok );
532     if ( !ok ) return false;
533     hypothesis.SetUseField(atoi(chunk.c_str()));
534
535     chunk = getNextChunk( stream, start, ok );
536     if ( !ok ) return false;
537     hypothesis.SetUseComp(atoi(chunk.c_str()));
538
539     chunk = getNextChunk( stream, start, ok );
540     if ( !ok ) return false;
541     hypothesis.SetTypeFieldInterp(atoi(chunk.c_str()));
542
543     chunk = getNextChunk( stream, start, ok );
544     if ( !ok ) return false;
545     int size = atoi( chunk.c_str() );
546     for ( int i = 0; i < size; i++ ) {
547       chunk = getNextChunk( stream, start, ok );
548       if ( !ok ) return false;
549       hypothesis.LinkIteration( chunk.c_str() );
550     }
551
552     chunk = getNextChunk( stream, start, ok );
553     if ( !ok ) return false;
554     size = atoi( chunk.c_str() );
555     for ( int i = 0; i < size; i++ ) {
556       chunk = getNextChunk( stream, start, ok );
557       if ( !ok ) return false;
558       i++;
559       chunkNext = getNextChunk( stream, start, ok );
560       int typeuse = atoi( chunkNext.c_str() );
561       if ( !ok ) return false;
562       hypothesis.AddZone( chunk.c_str(), typeuse );
563     }
564
565     chunk = getNextChunk( stream, start, ok );
566     if ( !ok ) return false;
567     size = atoi( chunk.c_str() );
568     for ( int i = 0; i < size; i++ ) {
569       chunk = getNextChunk( stream, start, ok );
570       if ( !ok ) return false;
571       hypothesis.AddComp( chunk.c_str() );
572     }
573
574     chunk = getNextChunk( stream, start, ok );
575     if ( !ok ) return false;
576     size = atoi( chunk.c_str() );
577     for ( int i = 0; i < size; i++ ) {
578       chunk = getNextChunk( stream, start, ok );
579       if ( !ok ) return false;
580       hypothesis.AddGroup( chunk.c_str() );
581     }
582
583     chunk = getNextChunk( stream, start, ok );
584     if ( !ok ) return false;
585     size = atoi( chunk.c_str() );
586     for ( int i = 0; i < size; i++ ) {
587       chunk = getNextChunk( stream, start, ok );
588       if ( !ok ) return false;
589       hypothesis.AddFieldInterp( chunk.c_str() );
590     }
591
592     chunk = getNextChunk( stream, start, ok );
593     if ( !ok ) return false;
594     hypothesis.SetNivMax( atoi( chunk.c_str() ) );
595
596     chunk = getNextChunk( stream, start, ok );
597     if ( !ok ) return false;
598     hypothesis.SetDiamMin( strtod( chunk.c_str(), 0 ) );
599
600     chunk = getNextChunk( stream, start, ok );
601     if ( !ok ) return false;
602     hypothesis.SetAdapInit( strtod( chunk.c_str(), 0 ) );
603
604     chunk = getNextChunk( stream, start, ok );
605     if ( !ok ) return false;
606     hypothesis.SetLevelOutput( strtod( chunk.c_str(), 0 ) );
607
608     return true;
609   }
610
611 //
612 // Zone
613 // ============================
614   /*!
615     \brief Restore zone from the string
616     \param zone zone being restored
617     \param stream string representation of the zone
618     \return \c true if zone is correctly restored or \c false otherwise
619   */
620   bool Restore( HOMARD_Zone& zone, const std::string& stream )
621   {
622     std::string::size_type start = 0;
623     std::string chunk;
624     bool ok;
625     //
626     chunk = getNextChunk( stream, start, ok );
627     if ( !ok ) return false;
628     zone.SetName( chunk.c_str() );
629     //
630     chunk = getNextChunk( stream, start, ok );
631     if ( !ok ) return false;
632     int ZoneType = atoi( chunk.c_str() ) ;
633     zone.SetType( ZoneType );
634     // Les coordonnees des zones : le nombre depend du type
635     std::vector<double> coords;
636     int lgcoords ;
637     if ( ZoneType == 2 or ( ZoneType >= 11 and ZoneType <= 13 ) ) { lgcoords = 6 ; }
638     else if ( ZoneType == 4 ) { lgcoords = 4 ; }
639     else if ( ZoneType == 5 or ( ZoneType >= 31 and ZoneType <= 33 ) ) { lgcoords = 8 ; }
640     else if ( ZoneType == 7 or ( ZoneType >= 61 and ZoneType <= 63 ) ) { lgcoords = 9 ; }
641     else return false;
642     coords.resize( lgcoords );
643     for ( int i = 0; i < lgcoords; i++ ) {
644       chunk = getNextChunk( stream, start, ok );
645       if ( !ok ) return false;
646       coords[i] = strtod( chunk.c_str(), 0 );
647     }
648     if ( ZoneType == 2 or ( ZoneType >= 11 and ZoneType <= 13 ) )
649     { zone.SetBox( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5] ); }
650     else if ( ZoneType == 4 )
651     { zone.SetSphere( coords[0], coords[1], coords[2], coords[3] ); }
652     else if ( ZoneType == 5 or ( ZoneType >= 31 and ZoneType <= 33 ) )
653     { zone.SetCylinder( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], coords[6], coords[7] ); }
654     else if ( ZoneType == 7 or ( ZoneType >= 61 and ZoneType <= 63 ) )
655     { zone.SetPipe( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], coords[6], coords[7], coords[8] ); }
656     // Remarque : la taille de coords est suffisante pour les limites
657     for ( int i = 0; i < 3; i++ ) {
658       chunk = getNextChunk( stream, start, ok );
659       if ( !ok ) return false;
660       coords[i] = strtod( chunk.c_str(), 0 );
661     }
662     zone.SetLimit( coords[0], coords[1], coords[2]);
663
664     chunk = getNextChunk( stream, start, ok );
665     if ( !ok ) return false;
666     int size = atoi( chunk.c_str() );
667     for ( int i = 0; i < size; i++ ) {
668       chunk = getNextChunk( stream, start, ok );
669       if ( !ok ) return false;
670       zone.AddHypo( chunk.c_str() );
671     }
672     return true;
673   }
674
675 //
676 // 2.5. Restauration d'une frontiere
677 // =================================
678
679   /*!
680     \brief Restore boundary from the string
681     \param boundary boundary being restored
682     \param stream string representation of the boundary
683     \return \c true if zone is correctly restored or \c false otherwise
684   */
685   bool Restore( HOMARD_Boundary& boundary, const std::string& stream )
686   {
687     std::string::size_type start = 0;
688     std::string chunk;
689     bool ok;
690
691     chunk = getNextChunk( stream, start, ok );
692     if ( !ok ) return false;
693     boundary.SetName( chunk.c_str() );
694
695     chunk = getNextChunk( stream, start, ok );
696     if ( !ok ) return false;
697     int BoundaryType = atoi( chunk.c_str() ) ;
698     boundary.SetType( BoundaryType );
699
700     chunk = getNextChunk( stream, start, ok );
701     if ( !ok ) return false;
702     boundary.SetCaseCreation( chunk.c_str() );
703
704     // Si analytique, les coordonnees des frontieres : le nombre depend du type
705     // Si discret, le maillage
706     int lgcoords ;
707     if ( BoundaryType == 1 ) { lgcoords = 7 ; }
708     else if ( BoundaryType == 2 ) { lgcoords = 4 ; }
709     else { lgcoords = 0 ; }
710 //
711     if ( lgcoords == 0 )
712     {
713       chunk = getNextChunk( stream, start, ok );
714       if ( !ok ) return false;
715       boundary.SetMeshName( chunk.c_str() );
716
717       chunk = getNextChunk( stream, start, ok );
718       if ( !ok ) return false;
719       boundary.SetMeshFile( chunk.c_str() );
720     }
721     else
722     { std::vector<double> coords;
723       coords.resize( lgcoords );
724       for ( int i = 0; i < lgcoords; i++ ) {
725         chunk = getNextChunk( stream, start, ok );
726         if ( !ok ) return false;
727         coords[i] = strtod( chunk.c_str(), 0 );
728       }
729       if ( BoundaryType == 1 )
730       { boundary.SetCylinder(coords[0],coords[1],coords[2],coords[3],coords[4],coords[5],coords[6]); }
731       else if ( BoundaryType == 2 )
732       { boundary.SetSphere( coords[0], coords[1], coords[2], coords[3]); }
733       else if ( BoundaryType == 3 )
734       { boundary.SetConeA( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], coords[6]); }
735       else if ( BoundaryType == 4 )
736       { boundary.SetConeR( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], coords[6], coords[7]); }
737       // Remarque : la taille de coords est suffisante pour les limites
738       for ( int i = 0; i < 3; i++ ) {
739         chunk = getNextChunk( stream, start, ok );
740         if ( !ok ) return false;
741         coords[i] = strtod( chunk.c_str(), 0 );
742       }
743       boundary.SetLimit( coords[0], coords[1], coords[2]);
744     }
745     // Les groupes
746     chunk = getNextChunk( stream, start, ok );
747     if ( !ok ) return false;
748     int size = atoi( chunk.c_str() );
749     for ( int i = 0; i < size; i++ ) {
750       chunk = getNextChunk( stream, start, ok );
751       if ( !ok ) return false;
752       boundary.AddGroup( chunk.c_str() );
753     }
754
755     return true;
756   }
757
758 } // namespace HOMARD /end/