Salome HOME
Merge from V6_main 13/12/2012
[modules/homard.git] / src / HOMARD / HOMARD_DriverTools.cxx
1 // Copyright (C) 2011-2012  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     // ...
108     MESSAGE( ". Dump du cas "<<cas.GetName());
109     os << cas.GetName();
110     os << separator() << cas.GetDirName();
111     os << separator() << cas.GetConfType();
112
113     std::vector<double> coor = cas.GetBoundingBox();
114     os << separator() << coor.size();
115     for ( int i = 0; i < coor.size(); i++ )
116           os << separator() << coor[i];
117
118     std::list<std::string> ListString = cas.GetIterations();
119     os << separator() << ListString.size();
120     std::list<std::string>::const_iterator it;
121     for ( it = ListString.begin(); it != ListString.end(); ++it )
122           os << separator() << *it;
123
124     ListString = cas.GetGroups();
125     os << separator() << ListString.size();
126     for ( it = ListString.begin(); it != ListString.end(); ++it )
127          os << separator() << *it;
128     ListString = cas.GetBoundaryGroup();
129     os << separator() << ListString.size();
130     for ( it = ListString.begin(); it != ListString.end(); ++it )
131          os << separator() << *it;
132
133     os << separator() << cas.GetPyram();
134
135 //    MESSAGE( ". Fin avec "<<os.str());
136     return os.str();
137   }
138 //
139 // Iteration
140 // ==========
141 //
142   /*!
143     \brief Dump iteration to the string
144     \param iteration iteration being dumped
145     \return string representation of the iteration
146   */
147   std::string Dump( const HOMARD_Iteration& iteration )
148   {
149     std::stringstream os;
150     // ...
151     MESSAGE( ". Dump de l'iteration "<<iteration.GetName());
152     os << iteration.GetName();
153     os << separator() << iteration.GetEtat();
154     os << separator() << iteration.GetNumber();
155     os << separator() << iteration.GetMeshFile();
156     os << separator() << iteration.GetMessFile();
157     os << separator() << iteration.GetMeshName();
158     os << separator() << iteration.GetFieldFile();
159     os << separator() << iteration.GetTimeStep();
160     os << separator() << iteration.GetRank();
161     os << separator() << iteration.GetIterParent();
162     //
163     std::list<std::string> ListString = iteration.GetIterations();
164     os << separator() << ListString.size();
165     std::list<std::string>::const_iterator it;
166     for ( it = ListString.begin(); it != ListString.end(); ++it )
167       os << separator() << *it;
168
169     os << separator() << iteration.GetHypoName();
170     os << separator() << iteration.GetCaseName();
171     os << separator() << iteration.GetDirName();
172
173 //    MESSAGE( ". Fin avec "<<os.str());
174     return os.str();
175   }
176 //
177 // hypothese
178 // ==============================
179   /*!
180     \brief Dump hypothesis to the string
181     \param hypothesis hypothesis being dumped
182     \return string representation of the hypothesis
183   */
184   std::string Dump( const HOMARD_Hypothesis& hypothesis )
185   {
186     std::stringstream os;
187     // ...
188     MESSAGE( ". Dump de l'hypothese "<<hypothesis.GetName());
189     os << hypothesis.GetName();
190     os << separator() << hypothesis.GetCaseCreation();
191     os << separator() << hypothesis.GetAdapType();
192     os << separator() << hypothesis.GetRefinType();
193     os << separator() << hypothesis.GetUnRefType();
194     os << separator() << hypothesis.GetFieldName();
195     os << separator() << hypothesis.GetRefinThrType();
196     os << separator() << hypothesis.GetThreshR();
197     os << separator() << hypothesis.GetUnRefThrType();
198     os << separator() << hypothesis.GetThreshC();
199     os << separator() << hypothesis.GetUseField();
200     os << separator() << hypothesis.GetUseCompI();
201     os << separator() << hypothesis.GetTypeFieldInterp();
202
203     std::list<std::string> ListString = hypothesis.GetIterations();
204     std::list<std::string>::const_iterator it;
205     os << separator() << ListString.size();
206     for ( it = ListString.begin(); it != ListString.end(); ++it )
207          os << separator() << *it;
208
209     ListString = hypothesis.GetZones();
210     os << separator() << ListString.size();
211     for ( it = ListString.begin(); it != ListString.end(); ++it )
212           os << separator() << *it;
213
214     ListString = hypothesis.GetListComp();
215     os << separator() << ListString.size();
216     for ( it = ListString.begin(); it != ListString.end(); ++it )
217          os << separator() << *it;
218
219     ListString = hypothesis.GetGroups();
220     os << separator() << ListString.size();
221     for ( it = ListString.begin(); it != ListString.end(); ++it )
222           os << separator() << *it;
223
224     ListString = hypothesis.GetListFieldInterp();
225     os << separator() << ListString.size();
226     for ( it = ListString.begin(); it != ListString.end(); ++it )
227           os << separator() << *it;
228
229     os << separator() << hypothesis.GetNivMax();
230     os << separator() << hypothesis.GetDiamMin();
231     os << separator() << hypothesis.GetAdapInit();
232     os << separator() << hypothesis.GetLevelOutput();
233
234 //    MESSAGE( ". Fin avec "<<os.str());
235     return os.str();
236   }
237 //
238 // Zone
239 // =========================
240
241   /*!
242     \brief Dump zone to the string
243     \param zone zone being dumped
244     \return string representation of the zone
245   */
246   std::string Dump( const HOMARD_Zone& zone )
247   {
248     std::stringstream os;
249     MESSAGE( ". Dump de la zone "<<zone.GetName());
250     os << zone.GetName();
251     os << separator() << zone.GetZoneType();
252
253     std::vector<double> coords = zone.GetCoords();
254     for ( int i = 0; i < coords.size(); i++ )
255       os << separator() << ( i < coords.size() ? coords[i] : 0. );
256
257     std::vector<double> limit = zone.GetLimit();
258     for ( int i = 0; i < 3; i++ )
259       os << separator() << ( i < limit.size() ? limit[i] : 0. );
260
261     std::list<std::string> hypos = zone.GetHypo();
262     os << separator() << hypos.size();
263     std::list<std::string>::const_iterator it;
264     for ( it = hypos.begin(); it != hypos.end(); ++it )
265       os << separator() << *it;
266
267 //    MESSAGE( ". Fin avec "<<os.str());
268     return os.str();
269   }
270 //
271 // 1.5. Archivage d'une frontiere
272 // ==============================
273
274   /*!
275     \brief Dump boundary to the string
276     \param boundary boundary being dumped
277     \return string representation of the boundary
278   */
279   std::string Dump( const HOMARD_Boundary& boundary )
280   {
281     std::stringstream os;
282     MESSAGE( ". Dump de la frontiere "<<boundary.GetName());
283
284     int BoundaryType = boundary.GetBoundaryType() ;
285
286     os << boundary.GetName() ;
287     os << separator() << BoundaryType ;
288     os << separator() << boundary.GetCaseCreation() ;
289
290     if ( BoundaryType == 0 )
291     {
292       os << separator() << boundary.GetMeshName();
293       os << separator() << boundary.GetMeshFile();
294     }
295     else {
296       std::vector<double> coor = boundary.GetCoords() ;
297       for ( int i = 0; i < coor.size(); i++ )
298             os << separator() << coor[i];
299       std::vector<double> limit = boundary.GetLimit();
300       for ( int i = 0; i < limit.size(); i++ )
301             os << separator() << limit[i];
302     }
303
304     std::list<std::string> ListString = boundary.GetGroups();
305     std::list<std::string>::const_iterator it;
306     os << separator() << ListString.size();
307     for ( it = ListString.begin(); it != ListString.end(); ++it )
308           os << separator() << *it;
309
310 //    MESSAGE( ". Fin avec "<<os.str());
311     return os.str();
312   }
313
314 //
315 // Restauration des objets
316 // ==========================
317 // Case
318 // ==========================
319 //
320   /*!
321     \brief Restore case from the string
322     \param cas case being restored
323     \param stream string representation of the case
324     \return \c true if case is correctly restored or \c false otherwise
325   */
326   bool Restore( HOMARD_Cas& cas, const std::string& stream )
327   {
328     MESSAGE( ". Restoration du cas ");
329     std::string::size_type start = 0;
330     std::string chunk, chunkNext;
331     bool ok;
332     // ...
333     chunk = getNextChunk( stream, start, ok );
334     if ( !ok ) return false;
335     cas.SetName( chunk.c_str() );
336
337     chunk = getNextChunk( stream, start, ok );
338     if ( !ok ) return false;
339     cas.SetDirName( chunk.c_str() );
340
341     chunk = getNextChunk( stream, start, ok );
342     if ( !ok ) return false;
343     cas.SetConfType( atoi( chunk.c_str() ) );
344
345     chunk = getNextChunk( stream, start, ok );
346     if ( !ok ) return false;
347
348     int size = atoi( chunk.c_str() );
349     std::vector<double> boite;
350     boite.resize( size );
351     for ( int i = 0; i < size; i++ ) {
352       chunk = getNextChunk( stream, start, ok );
353       if ( !ok ) return false;
354       boite[i] = strtod( chunk.c_str(), 0 );
355     }
356     cas.SetBoundingBox( boite );
357
358     chunk = getNextChunk( stream, start, ok );
359     if ( !ok ) return false;
360
361     size = atoi( chunk.c_str() );
362     for ( int i = 0; i < size; i++ ) {
363       chunk = getNextChunk( stream, start, ok );
364       if ( !ok ) return false;
365       cas.AddIteration( chunk.c_str() );
366     }
367
368     chunk = getNextChunk( stream, start, ok );
369     if ( !ok ) return false;
370     size = atoi( chunk.c_str() );
371     for ( int i = 0; i < size; i++ )
372     {
373       chunk = getNextChunk( stream, start, ok );
374       if ( !ok ) return false;
375       cas.AddGroup( 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       chunk = getNextChunk( stream, start, ok );
383       if ( !ok ) return false;
384       i++;
385       chunkNext = getNextChunk( stream, start, ok );
386       if ( !ok ) return false;
387       cas.AddBoundaryGroup( chunk.c_str(), chunkNext.c_str() );
388     }
389
390     chunk = getNextChunk( stream, start, ok );
391     if ( !ok ) return false;
392     cas.SetPyram( atoi( chunk.c_str() ) );
393
394     return true;
395   }
396 //
397 //  Iteration
398 // =================================
399   /*!
400     \brief Restore iteration from the string
401     \param iteration iteration being restored
402     \param stream string representation of the iteration
403     \return \c true if iteration is correctly restored or \c false otherwise
404   */
405   bool Restore( HOMARD_Iteration& iteration, const std::string& stream )
406   {
407     std::string::size_type start = 0;
408     std::string chunk;
409     bool ok;
410     chunk = getNextChunk( stream, start, ok );
411     if ( !ok ) return false;
412
413     iteration.SetName( chunk.c_str() );
414     chunk = getNextChunk( stream, start, ok );
415     if ( !ok ) return false;
416     iteration.SetEtat( (bool)atoi( chunk.c_str() ) );
417     chunk = getNextChunk( stream, start, ok );
418     if ( !ok ) return false;
419     iteration.SetNumber( atoi( chunk.c_str() ) );
420     chunk = getNextChunk( stream, start, ok );
421     if ( !ok ) return false;
422     iteration.SetMeshFile( chunk.c_str() );
423     chunk = getNextChunk( stream, start, ok );
424     if ( !ok ) return false;
425     iteration.SetMessFile( chunk.c_str() );
426     chunk = getNextChunk( stream, start, ok );
427     if ( !ok ) return false;
428     iteration.SetMeshName( chunk.c_str() );
429     chunk = getNextChunk( stream, start, ok );
430     if ( !ok ) return false;
431     iteration.SetFieldFile( chunk.c_str() );
432     // .
433     int timestep, rank;
434     chunk = getNextChunk( stream, start, ok );
435     if ( !ok ) return false;
436     timestep = atoi( chunk.c_str() );
437     chunk = getNextChunk( stream, start, ok );
438     if ( !ok ) return false;
439     rank = atoi( chunk.c_str() );
440     iteration.SetTimeStepRank( timestep, rank );
441     chunk = getNextChunk( stream, start, ok );
442     if ( !ok ) return false;
443     iteration.SetIterParent( chunk.c_str() );
444     //
445     chunk = getNextChunk( stream, start, ok );
446     if ( !ok ) return false;
447     int size = atoi( chunk.c_str() );
448     for ( int i = 0; i < size; i++ ) {
449       chunk = getNextChunk( stream, start, ok );
450       if ( !ok ) return false;
451       iteration.AddIteration( chunk.c_str() );
452     }
453     //
454     chunk = getNextChunk( stream, start, ok );
455     if ( !ok ) return false;
456     iteration.SetHypoName( chunk.c_str() );
457     chunk = getNextChunk( stream, start, ok );
458     if ( !ok ) return false;
459     iteration.SetCaseName( chunk.c_str() );
460     chunk = getNextChunk( stream, start, ok );
461     if ( !ok ) return false;
462     iteration.SetDirName( chunk.c_str() );
463     return true;
464   }
465
466 //
467 // hypothese
468 // =================================
469   /*!
470     \brief Restore hypothesis from the string
471     \param hypothesis hypothesis being restored
472     \param stream string representation of the hypothesis
473     \return \c true if hypothesis is correctly restored or \c false otherwise
474   */
475   bool Restore( HOMARD_Hypothesis& hypothesis, const std::string& stream )
476   {
477     std::string::size_type start = 0;
478     std::string chunk, chunkNext;
479     bool ok;
480
481     chunk = getNextChunk( stream, start, ok );
482     if ( !ok ) return false;
483     hypothesis.SetName( chunk.c_str() );
484
485     chunk = getNextChunk( stream, start, ok );
486     if ( !ok ) return false;
487     hypothesis.SetCaseCreation( chunk.c_str() );
488
489     chunk = getNextChunk( stream, start, ok );
490     if ( !ok ) return false;
491     hypothesis.SetAdapType( atoi( chunk.c_str() ) );
492
493     chunk = getNextChunk( stream, start, ok );
494     if ( !ok ) return false;
495     int typeraff = atoi( chunk.c_str() );
496     chunk = getNextChunk( stream, start, ok );
497     if ( !ok ) return false;
498     int typedera = atoi( chunk.c_str() );
499     hypothesis.SetRefinTypeDera( typeraff, typedera );
500
501     chunk = getNextChunk( stream, start, ok );
502     if ( !ok ) return false;
503     hypothesis.SetField( chunk.c_str() );
504
505     chunk = getNextChunk( stream, start, ok );
506     if ( !ok ) return false;
507     int typethr = atoi( chunk.c_str() );
508     chunk = getNextChunk( stream, start, ok );
509     if ( !ok ) return false;
510     double threshr = strtod( chunk.c_str(), 0 );
511     hypothesis.SetRefinThr( typethr, threshr );
512
513     chunk = getNextChunk( stream, start, ok );
514     if ( !ok ) return false;
515     int typethc = atoi( chunk.c_str() );
516     chunk = getNextChunk( stream, start, ok );
517     if ( !ok ) return false;
518     double threshc = strtod( chunk.c_str(), 0 );
519     hypothesis.SetUnRefThr( typethc, threshc );
520
521     chunk = getNextChunk( stream, start, ok );
522     if ( !ok ) return false;
523     hypothesis.SetUseField(atoi(chunk.c_str()));
524
525     chunk = getNextChunk( stream, start, ok );
526     if ( !ok ) return false;
527     hypothesis.SetUseComp(atoi(chunk.c_str()));
528
529     chunk = getNextChunk( stream, start, ok );
530     if ( !ok ) return false;
531     hypothesis.SetTypeFieldInterp(atoi(chunk.c_str()));
532
533     chunk = getNextChunk( stream, start, ok );
534     if ( !ok ) return false;
535     int size = atoi( chunk.c_str() );
536     for ( int i = 0; i < size; i++ ) {
537       chunk = getNextChunk( stream, start, ok );
538       if ( !ok ) return false;
539       hypothesis.AddIteration( chunk.c_str() );
540     }
541
542     chunk = getNextChunk( stream, start, ok );
543     if ( !ok ) return false;
544     size = atoi( chunk.c_str() );
545     for ( int i = 0; i < size; i++ ) {
546       chunk = getNextChunk( stream, start, ok );
547       if ( !ok ) return false;
548       i++;
549       chunkNext = getNextChunk( stream, start, ok );
550       int typeuse = atoi( chunkNext.c_str() );
551       if ( !ok ) return false;
552       hypothesis.AddZone( chunk.c_str(), typeuse );
553     }
554
555     chunk = getNextChunk( stream, start, ok );
556     if ( !ok ) return false;
557     size = atoi( chunk.c_str() );
558     for ( int i = 0; i < size; i++ ) {
559       chunk = getNextChunk( stream, start, ok );
560       if ( !ok ) return false;
561       hypothesis.AddComp( chunk.c_str() );
562     }
563
564     chunk = getNextChunk( stream, start, ok );
565     if ( !ok ) return false;
566     size = atoi( chunk.c_str() );
567     for ( int i = 0; i < size; i++ ) {
568       chunk = getNextChunk( stream, start, ok );
569       if ( !ok ) return false;
570       hypothesis.AddGroup( chunk.c_str() );
571     }
572
573     chunk = getNextChunk( stream, start, ok );
574     if ( !ok ) return false;
575     size = atoi( chunk.c_str() );
576     for ( int i = 0; i < size; i++ ) {
577       chunk = getNextChunk( stream, start, ok );
578       if ( !ok ) return false;
579       hypothesis.AddFieldInterp( chunk.c_str() );
580     }
581
582     chunk = getNextChunk( stream, start, ok );
583     if ( !ok ) return false;
584     hypothesis.SetNivMax( atoi( chunk.c_str() ) );
585
586     chunk = getNextChunk( stream, start, ok );
587     if ( !ok ) return false;
588     hypothesis.SetDiamMin( strtod( chunk.c_str(), 0 ) );
589
590     chunk = getNextChunk( stream, start, ok );
591     if ( !ok ) return false;
592     hypothesis.SetAdapInit( strtod( chunk.c_str(), 0 ) );
593
594     chunk = getNextChunk( stream, start, ok );
595     if ( !ok ) return false;
596     hypothesis.SetLevelOutput( strtod( chunk.c_str(), 0 ) );
597
598     return true;
599   }
600
601 //
602 // Zone
603 // ============================
604   /*!
605     \brief Restore zone from the string
606     \param zone zone being restored
607     \param stream string representation of the zone
608     \return \c true if zone is correctly restored or \c false otherwise
609   */
610   bool Restore( HOMARD_Zone& zone, const std::string& stream )
611   {
612     std::string::size_type start = 0;
613     std::string chunk;
614     bool ok;
615     //
616     chunk = getNextChunk( stream, start, ok );
617     if ( !ok ) return false;
618     zone.SetName( chunk.c_str() );
619     //
620     chunk = getNextChunk( stream, start, ok );
621     if ( !ok ) return false;
622     int ZoneType = atoi( chunk.c_str() ) ;
623     zone.SetZoneType( ZoneType );
624     // Les coordonnees des zones : le nombre depend du type
625     std::vector<double> coords;
626     int lgcoords ;
627     if ( ZoneType == 2 or ( ZoneType >= 11 and ZoneType <= 13 ) ) { lgcoords = 6 ; }
628     else if ( ZoneType == 4 ) { lgcoords = 4 ; }
629     else if ( ZoneType == 5 or ( ZoneType >= 31 and ZoneType <= 33 ) ) { lgcoords = 8 ; }
630     else if ( ZoneType == 7 or ( ZoneType >= 61 and ZoneType <= 63 ) ) { lgcoords = 9 ; }
631     else return false;
632     coords.resize( lgcoords );
633     for ( int i = 0; i < lgcoords; i++ ) {
634       chunk = getNextChunk( stream, start, ok );
635       if ( !ok ) return false;
636       coords[i] = strtod( chunk.c_str(), 0 );
637     }
638     if ( ZoneType == 2 or ( ZoneType >= 11 and ZoneType <= 13 ) )
639     { zone.SetBox( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5] ); }
640     else if ( ZoneType == 4 )
641     { zone.SetSphere( coords[0], coords[1], coords[2], coords[3] ); }
642     else if ( ZoneType == 5 or ( ZoneType >= 31 and ZoneType <= 33 ) )
643     { zone.SetCylinder( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], coords[6], coords[7] ); }
644     else if ( ZoneType == 7 or ( ZoneType >= 61 and ZoneType <= 63 ) )
645     { zone.SetPipe( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], coords[6], coords[7], coords[8] ); }
646     // Remarque : la taille de coords est suffisante pour les limites
647     for ( int i = 0; i < 3; i++ ) {
648       chunk = getNextChunk( stream, start, ok );
649       if ( !ok ) return false;
650       coords[i] = strtod( chunk.c_str(), 0 );
651     }
652     zone.SetLimit( coords[0], coords[1], coords[2]);
653
654     chunk = getNextChunk( stream, start, ok );
655     if ( !ok ) return false;
656     int size = atoi( chunk.c_str() );
657     for ( int i = 0; i < size; i++ ) {
658       chunk = getNextChunk( stream, start, ok );
659       if ( !ok ) return false;
660       zone.AddHypo( chunk.c_str() );
661     }
662     return true;
663   }
664
665 //
666 // 2.5. Restauration d'une frontiere
667 // =================================
668
669   /*!
670     \brief Restore boundary from the string
671     \param boundary boundary being restored
672     \param stream string representation of the boundary
673     \return \c true if zone is correctly restored or \c false otherwise
674   */
675   bool Restore( HOMARD_Boundary& boundary, const std::string& stream )
676   {
677     std::string::size_type start = 0;
678     std::string chunk;
679     bool ok;
680
681     chunk = getNextChunk( stream, start, ok );
682     if ( !ok ) return false;
683     boundary.SetName( chunk.c_str() );
684
685     chunk = getNextChunk( stream, start, ok );
686     if ( !ok ) return false;
687     int BoundaryType = atoi( chunk.c_str() ) ;
688     boundary.SetBoundaryType( BoundaryType );
689
690     chunk = getNextChunk( stream, start, ok );
691     if ( !ok ) return false;
692     boundary.SetCaseCreation( chunk.c_str() );
693
694     // Si analytique, les coordonnees des frontieres : le nombre depend du type
695     // Si discret, le maillage
696     int lgcoords ;
697     if ( BoundaryType == 1 ) { lgcoords = 7 ; }
698     else if ( BoundaryType == 2 ) { lgcoords = 4 ; }
699     else { lgcoords = 0 ; }
700 //
701     if ( lgcoords == 0 )
702     {
703       chunk = getNextChunk( stream, start, ok );
704       if ( !ok ) return false;
705       boundary.SetMeshName( chunk.c_str() );
706
707       chunk = getNextChunk( stream, start, ok );
708       if ( !ok ) return false;
709       boundary.SetMeshFile( chunk.c_str() );
710     }
711     else
712     { std::vector<double> coords;
713       coords.resize( lgcoords );
714       for ( int i = 0; i < lgcoords; i++ ) {
715         chunk = getNextChunk( stream, start, ok );
716         if ( !ok ) return false;
717         coords[i] = strtod( chunk.c_str(), 0 );
718       }
719       if ( BoundaryType == 1 )
720       { boundary.SetCylinder(coords[0],coords[1],coords[2],coords[3],coords[4],coords[5],coords[6]); }
721       else if ( BoundaryType == 2 )
722       { boundary.SetSphere( coords[0], coords[1], coords[2], coords[3]); }
723       // Remarque : la taille de coords est suffisante pour les limites
724       for ( int i = 0; i < 3; i++ ) {
725         chunk = getNextChunk( stream, start, ok );
726         if ( !ok ) return false;
727         coords[i] = strtod( chunk.c_str(), 0 );
728       }
729       boundary.SetLimit( coords[0], coords[1], coords[2]);
730     }
731     // Les groupes
732     chunk = getNextChunk( stream, start, ok );
733     if ( !ok ) return false;
734     int size = atoi( chunk.c_str() );
735     for ( int i = 0; i < size; i++ ) {
736       chunk = getNextChunk( stream, start, ok );
737       if ( !ok ) return false;
738       boundary.AddGroup( chunk.c_str() );
739     }
740
741     return true;
742   }
743
744 } // namespace HOMARD /end/