1 // Copyright (C) 2011 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File : HOMARD_DriverTools.cxx
20 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22 // ----------------------------------------------------------------------------
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"
32 #include "utilities.h"
37 const char* const SEPARATOR = "|";
40 \brief Read next chunk of data from the string
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.
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
54 static std::string getNextChunk( const std::string& str, std::string::size_type& start, bool& ok )
56 std::string chunk = "";
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();
68 \brief Get persistence signature
69 \param type persistence entity type
70 \return persistence signature
72 std::string GetSignature( SignatureType type )
74 std::string signature = "";
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;
83 signature += separator();
88 \brief Get data separator
89 \return string that is used to separate data entities in the stream
91 std::string separator()
93 return std::string( SEPARATOR );
96 // =======================
98 // =======================
100 \brief Dump case to the string
101 \param cas case being dumped
102 \return string representation of the case
104 std::string Dump( const HOMARD_Cas& cas )
106 std::stringstream os;
108 MESSAGE( ". Dump du cas "<<cas.GetName());
110 os << separator() << cas.GetDirName();
111 os << separator() << cas.GetConfType();
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];
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;
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;
133 os << separator() << cas.GetPyram();
135 // MESSAGE( ". Fin avec "<<os.str());
143 \brief Dump iteration to the string
144 \param iteration iteration being dumped
145 \return string representation of the iteration
147 std::string Dump( const HOMARD_Iteration& iteration )
149 std::stringstream os;
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();
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;
169 os << separator() << iteration.GetHypoName();
170 os << separator() << iteration.GetCaseName();
171 os << separator() << iteration.GetDirName();
173 // MESSAGE( ". Fin avec "<<os.str());
178 // ==============================
180 \brief Dump hypothesis to the string
181 \param hypothesis hypothesis being dumped
182 \return string representation of the hypothesis
184 std::string Dump( const HOMARD_Hypothesis& hypothesis )
186 std::stringstream os;
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();
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;
209 ListString = hypothesis.GetZones();
210 os << separator() << ListString.size();
211 for ( it = ListString.begin(); it != ListString.end(); ++it )
212 os << separator() << *it;
214 ListString = hypothesis.GetListComp();
215 os << separator() << ListString.size();
216 for ( it = ListString.begin(); it != ListString.end(); ++it )
217 os << separator() << *it;
219 ListString = hypothesis.GetGroups();
220 os << separator() << ListString.size();
221 for ( it = ListString.begin(); it != ListString.end(); ++it )
222 os << separator() << *it;
224 ListString = hypothesis.GetListFieldInterp();
225 os << separator() << ListString.size();
226 for ( it = ListString.begin(); it != ListString.end(); ++it )
227 os << separator() << *it;
229 os << separator() << hypothesis.GetNivMax();
230 os << separator() << hypothesis.GetDiamMin();
232 // MESSAGE( ". Fin avec "<<os.str());
237 // =========================
240 \brief Dump zone to the string
241 \param zone zone being dumped
242 \return string representation of the zone
244 std::string Dump( const HOMARD_Zone& zone )
246 std::stringstream os;
247 MESSAGE( ". Dump de la zone "<<zone.GetName());
248 os << zone.GetName();
249 os << separator() << zone.GetZoneType();
251 std::vector<double> coords = zone.GetCoords();
252 for ( int i = 0; i < coords.size(); i++ )
253 os << separator() << ( i < coords.size() ? coords[i] : 0. );
255 std::vector<double> limit = zone.GetLimit();
256 for ( int i = 0; i < 3; i++ )
257 os << separator() << ( i < limit.size() ? limit[i] : 0. );
259 std::list<std::string> hypos = zone.GetHypo();
260 os << separator() << hypos.size();
261 std::list<std::string>::const_iterator it;
262 for ( it = hypos.begin(); it != hypos.end(); ++it )
263 os << separator() << *it;
265 // MESSAGE( ". Fin avec "<<os.str());
269 // 1.5. Archivage d'une frontiere
270 // ==============================
273 \brief Dump boundary to the string
274 \param boundary boundary being dumped
275 \return string representation of the boundary
277 std::string Dump( const HOMARD_Boundary& boundary )
279 std::stringstream os;
280 MESSAGE( ". Dump de la frontiere "<<boundary.GetName());
282 int BoundaryType = boundary.GetBoundaryType() ;
284 os << boundary.GetName() ;
285 os << separator() << BoundaryType ;
286 os << separator() << boundary.GetCaseCreation() ;
288 if ( BoundaryType == 0 )
290 os << separator() << boundary.GetMeshName();
291 os << separator() << boundary.GetMeshFile();
294 std::vector<double> coor = boundary.GetCoords() ;
295 for ( int i = 0; i < coor.size(); i++ )
296 os << separator() << coor[i];
297 std::vector<double> limit = boundary.GetLimit();
298 for ( int i = 0; i < limit.size(); i++ )
299 os << separator() << limit[i];
302 std::list<std::string> ListString = boundary.GetGroups();
303 std::list<std::string>::const_iterator it;
304 os << separator() << ListString.size();
305 for ( it = ListString.begin(); it != ListString.end(); ++it )
306 os << separator() << *it;
308 // MESSAGE( ". Fin avec "<<os.str());
313 // Restauration des objets
314 // ==========================
316 // ==========================
319 \brief Restore case from the string
320 \param cas case being restored
321 \param stream string representation of the case
322 \return \c true if case is correctly restored or \c false otherwise
324 bool Restore( HOMARD_Cas& cas, const std::string& stream )
326 MESSAGE( ". Restoration du cas ");
327 std::string::size_type start = 0;
328 std::string chunk, chunkNext;
331 chunk = getNextChunk( stream, start, ok );
332 if ( !ok ) return false;
333 cas.SetName( chunk.c_str() );
335 chunk = getNextChunk( stream, start, ok );
336 if ( !ok ) return false;
337 cas.SetDirName( chunk.c_str() );
339 chunk = getNextChunk( stream, start, ok );
340 if ( !ok ) return false;
341 cas.SetConfType( atoi( chunk.c_str() ) );
343 chunk = getNextChunk( stream, start, ok );
344 if ( !ok ) return false;
346 int size = atoi( chunk.c_str() );
347 std::vector<double> boite;
348 boite.resize( size );
349 for ( int i = 0; i < size; i++ ) {
350 chunk = getNextChunk( stream, start, ok );
351 if ( !ok ) return false;
352 boite[i] = strtod( chunk.c_str(), 0 );
354 cas.SetBoundingBox( boite );
356 chunk = getNextChunk( stream, start, ok );
357 if ( !ok ) return false;
359 size = atoi( chunk.c_str() );
360 for ( int i = 0; i < size; i++ ) {
361 chunk = getNextChunk( stream, start, ok );
362 if ( !ok ) return false;
363 cas.AddIteration( chunk.c_str() );
366 chunk = getNextChunk( stream, start, ok );
367 if ( !ok ) return false;
368 size = atoi( chunk.c_str() );
369 for ( int i = 0; i < size; i++ )
371 chunk = getNextChunk( stream, start, ok );
372 if ( !ok ) return false;
373 cas.AddGroup( chunk.c_str() );
376 chunk = getNextChunk( stream, start, ok );
377 if ( !ok ) return false;
378 size = atoi( chunk.c_str() );
379 for ( int i = 0; i < size; i++ ) {
380 chunk = getNextChunk( stream, start, ok );
381 if ( !ok ) return false;
383 chunkNext = getNextChunk( stream, start, ok );
384 if ( !ok ) return false;
385 cas.AddBoundaryGroup( chunk.c_str(), chunkNext.c_str() );
388 chunk = getNextChunk( stream, start, ok );
389 if ( !ok ) return false;
390 cas.SetPyram( atoi( chunk.c_str() ) );
396 // =================================
398 \brief Restore iteration from the string
399 \param iteration iteration being restored
400 \param stream string representation of the iteration
401 \return \c true if iteration is correctly restored or \c false otherwise
403 bool Restore( HOMARD_Iteration& iteration, const std::string& stream )
405 std::string::size_type start = 0;
408 chunk = getNextChunk( stream, start, ok );
409 if ( !ok ) return false;
411 iteration.SetName( chunk.c_str() );
412 chunk = getNextChunk( stream, start, ok );
413 if ( !ok ) return false;
414 iteration.SetEtat( (bool)atoi( chunk.c_str() ) );
415 chunk = getNextChunk( stream, start, ok );
416 if ( !ok ) return false;
417 iteration.SetNumber( atoi( chunk.c_str() ) );
418 chunk = getNextChunk( stream, start, ok );
419 if ( !ok ) return false;
420 iteration.SetMeshFile( chunk.c_str() );
421 chunk = getNextChunk( stream, start, ok );
422 if ( !ok ) return false;
423 iteration.SetMessFile( chunk.c_str() );
424 chunk = getNextChunk( stream, start, ok );
425 if ( !ok ) return false;
426 iteration.SetMeshName( chunk.c_str() );
427 chunk = getNextChunk( stream, start, ok );
428 if ( !ok ) return false;
429 iteration.SetFieldFile( chunk.c_str() );
432 chunk = getNextChunk( stream, start, ok );
433 if ( !ok ) return false;
434 timestep = atoi( chunk.c_str() );
435 chunk = getNextChunk( stream, start, ok );
436 if ( !ok ) return false;
437 rank = atoi( chunk.c_str() );
438 iteration.SetTimeStepRank( timestep, rank );
439 chunk = getNextChunk( stream, start, ok );
440 if ( !ok ) return false;
441 iteration.SetIterParent( chunk.c_str() );
443 chunk = getNextChunk( stream, start, ok );
444 if ( !ok ) return false;
445 int size = atoi( chunk.c_str() );
446 for ( int i = 0; i < size; i++ ) {
447 chunk = getNextChunk( stream, start, ok );
448 if ( !ok ) return false;
449 iteration.AddIteration( chunk.c_str() );
452 chunk = getNextChunk( stream, start, ok );
453 if ( !ok ) return false;
454 iteration.SetHypoName( chunk.c_str() );
455 chunk = getNextChunk( stream, start, ok );
456 if ( !ok ) return false;
457 iteration.SetCaseName( chunk.c_str() );
458 chunk = getNextChunk( stream, start, ok );
459 if ( !ok ) return false;
460 iteration.SetDirName( chunk.c_str() );
466 // =================================
468 \brief Restore hypothesis from the string
469 \param hypothesis hypothesis being restored
470 \param stream string representation of the hypothesis
471 \return \c true if hypothesis is correctly restored or \c false otherwise
473 bool Restore( HOMARD_Hypothesis& hypothesis, const std::string& stream )
475 std::string::size_type start = 0;
479 chunk = getNextChunk( stream, start, ok );
480 if ( !ok ) return false;
481 hypothesis.SetName( chunk.c_str() );
483 chunk = getNextChunk( stream, start, ok );
484 if ( !ok ) return false;
485 hypothesis.SetCaseCreation( chunk.c_str() );
487 chunk = getNextChunk( stream, start, ok );
488 if ( !ok ) return false;
489 hypothesis.SetAdapType( atoi( chunk.c_str() ) );
491 chunk = getNextChunk( stream, start, ok );
492 if ( !ok ) return false;
493 int typeraff = atoi( chunk.c_str() );
494 chunk = getNextChunk( stream, start, ok );
495 if ( !ok ) return false;
496 int typedera = atoi( chunk.c_str() );
497 hypothesis.SetRefinTypeDera( typeraff, typedera );
499 chunk = getNextChunk( stream, start, ok );
500 if ( !ok ) return false;
501 hypothesis.SetField( chunk.c_str() );
503 chunk = getNextChunk( stream, start, ok );
504 if ( !ok ) return false;
505 int typethr = atoi( chunk.c_str() );
506 chunk = getNextChunk( stream, start, ok );
507 if ( !ok ) return false;
508 double threshr = strtod( chunk.c_str(), 0 );
509 hypothesis.SetRefinThr( typethr, threshr );
511 chunk = getNextChunk( stream, start, ok );
512 if ( !ok ) return false;
513 int typethc = atoi( chunk.c_str() );
514 chunk = getNextChunk( stream, start, ok );
515 if ( !ok ) return false;
516 double threshc = strtod( chunk.c_str(), 0 );
517 hypothesis.SetUnRefThr( typethc, threshc );
519 chunk = getNextChunk( stream, start, ok );
520 if ( !ok ) return false;
521 hypothesis.SetUseField(atoi(chunk.c_str()));
523 chunk = getNextChunk( stream, start, ok );
524 if ( !ok ) return false;
525 hypothesis.SetUseComp(atoi(chunk.c_str()));
527 chunk = getNextChunk( stream, start, ok );
528 if ( !ok ) return false;
529 hypothesis.SetTypeFieldInterp(atoi(chunk.c_str()));
531 chunk = getNextChunk( stream, start, ok );
532 if ( !ok ) return false;
533 int size = atoi( chunk.c_str() );
534 for ( int i = 0; i < size; i++ ) {
535 chunk = getNextChunk( stream, start, ok );
536 if ( !ok ) return false;
537 hypothesis.AddIteration( chunk.c_str() );
540 chunk = getNextChunk( stream, start, ok );
541 if ( !ok ) return false;
542 size = atoi( chunk.c_str() );
543 for ( int i = 0; i < size; i++ ) {
544 chunk = getNextChunk( stream, start, ok );
545 if ( !ok ) return false;
546 hypothesis.AddZone( chunk.c_str() );
549 chunk = getNextChunk( stream, start, ok );
550 if ( !ok ) return false;
551 size = atoi( chunk.c_str() );
552 for ( int i = 0; i < size; i++ ) {
553 chunk = getNextChunk( stream, start, ok );
554 if ( !ok ) return false;
555 hypothesis.AddComp( chunk.c_str() );
558 chunk = getNextChunk( stream, start, ok );
559 if ( !ok ) return false;
560 size = atoi( chunk.c_str() );
561 for ( int i = 0; i < size; i++ ) {
562 chunk = getNextChunk( stream, start, ok );
563 if ( !ok ) return false;
564 hypothesis.AddGroup( chunk.c_str() );
567 chunk = getNextChunk( stream, start, ok );
568 if ( !ok ) return false;
569 size = atoi( chunk.c_str() );
570 for ( int i = 0; i < size; i++ ) {
571 chunk = getNextChunk( stream, start, ok );
572 if ( !ok ) return false;
573 hypothesis.AddFieldInterp( chunk.c_str() );
576 chunk = getNextChunk( stream, start, ok );
577 if ( !ok ) return false;
578 hypothesis.SetNivMax( atoi( chunk.c_str() ) );
580 chunk = getNextChunk( stream, start, ok );
581 if ( !ok ) return false;
582 hypothesis.SetDiamMin( strtod( chunk.c_str(), 0 ) );
589 // ============================
591 \brief Restore zone from the string
592 \param zone zone being restored
593 \param stream string representation of the zone
594 \return \c true if zone is correctly restored or \c false otherwise
596 bool Restore( HOMARD_Zone& zone, const std::string& stream )
598 std::string::size_type start = 0;
602 chunk = getNextChunk( stream, start, ok );
603 if ( !ok ) return false;
604 zone.SetName( chunk.c_str() );
606 chunk = getNextChunk( stream, start, ok );
607 if ( !ok ) return false;
608 int ZoneType = atoi( chunk.c_str() ) ;
609 zone.SetZoneType( ZoneType );
610 // Les coordonnees des zones : le nombre depend du type
611 std::vector<double> coords;
613 if ( ZoneType == 2 or ( ZoneType >= 11 and ZoneType <= 13 ) ) { lgcoords = 6 ; }
614 else if ( ZoneType == 4 ) { lgcoords = 4 ; }
615 else if ( ZoneType == 5 or ( ZoneType >= 31 and ZoneType <= 33 ) ) { lgcoords = 8 ; }
616 else if ( ZoneType == 7 or ( ZoneType >= 61 and ZoneType <= 63 ) ) { lgcoords = 9 ; }
618 coords.resize( lgcoords );
619 for ( int i = 0; i < lgcoords; i++ ) {
620 chunk = getNextChunk( stream, start, ok );
621 if ( !ok ) return false;
622 coords[i] = strtod( chunk.c_str(), 0 );
624 if ( ZoneType == 2 or ( ZoneType >= 11 and ZoneType <= 13 ) )
625 { zone.SetBox( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5] ); }
626 else if ( ZoneType == 4 )
627 { zone.SetSphere( coords[0], coords[1], coords[2], coords[3] ); }
628 else if ( ZoneType == 5 or ( ZoneType >= 31 and ZoneType <= 33 ) )
629 { zone.SetCylinder( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], coords[6], coords[7] ); }
630 else if ( ZoneType == 7 or ( ZoneType >= 61 and ZoneType <= 63 ) )
631 { zone.SetPipe( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], coords[6], coords[7], coords[8] ); }
632 // Remarque : la taille de coords est suffisante pour les limites
633 for ( int i = 0; i < 3; i++ ) {
634 chunk = getNextChunk( stream, start, ok );
635 if ( !ok ) return false;
636 coords[i] = strtod( chunk.c_str(), 0 );
638 zone.SetLimit( coords[0], coords[1], coords[2]);
640 chunk = getNextChunk( stream, start, ok );
641 if ( !ok ) return false;
642 int size = atoi( chunk.c_str() );
643 for ( int i = 0; i < size; i++ ) {
644 chunk = getNextChunk( stream, start, ok );
645 if ( !ok ) return false;
646 zone.AddHypo( chunk.c_str() );
652 // 2.5. Restauration d'une frontiere
653 // =================================
656 \brief Restore boundary from the string
657 \param boundary boundary being restored
658 \param stream string representation of the boundary
659 \return \c true if zone is correctly restored or \c false otherwise
661 bool Restore( HOMARD_Boundary& boundary, const std::string& stream )
663 std::string::size_type start = 0;
667 chunk = getNextChunk( stream, start, ok );
668 if ( !ok ) return false;
669 boundary.SetName( chunk.c_str() );
671 chunk = getNextChunk( stream, start, ok );
672 if ( !ok ) return false;
673 int BoundaryType = atoi( chunk.c_str() ) ;
674 boundary.SetBoundaryType( BoundaryType );
676 chunk = getNextChunk( stream, start, ok );
677 if ( !ok ) return false;
678 boundary.SetCaseCreation( chunk.c_str() );
680 // Si analytique, les coordonnees des frontieres : le nombre depend du type
681 // Si discret, le maillage
683 if ( BoundaryType == 1 ) { lgcoords = 7 ; }
684 else if ( BoundaryType == 2 ) { lgcoords = 4 ; }
685 else { lgcoords = 0 ; }
689 chunk = getNextChunk( stream, start, ok );
690 if ( !ok ) return false;
691 boundary.SetMeshName( chunk.c_str() );
693 chunk = getNextChunk( stream, start, ok );
694 if ( !ok ) return false;
695 boundary.SetMeshFile( chunk.c_str() );
698 { std::vector<double> coords;
699 coords.resize( lgcoords );
700 for ( int i = 0; i < lgcoords; i++ ) {
701 chunk = getNextChunk( stream, start, ok );
702 if ( !ok ) return false;
703 coords[i] = strtod( chunk.c_str(), 0 );
705 if ( BoundaryType == 1 )
706 { boundary.SetCylinder(coords[0],coords[1],coords[2],coords[3],coords[4],coords[5],coords[6]); }
707 else if ( BoundaryType == 2 )
708 { boundary.SetSphere( coords[0], coords[1], coords[2], coords[3]); }
709 // Remarque : la taille de coords est suffisante pour les limites
710 for ( int i = 0; i < 3; i++ ) {
711 chunk = getNextChunk( stream, start, ok );
712 if ( !ok ) return false;
713 coords[i] = strtod( chunk.c_str(), 0 );
715 boundary.SetLimit( coords[0], coords[1], coords[2]);
718 chunk = getNextChunk( stream, start, ok );
719 if ( !ok ) return false;
720 int size = atoi( chunk.c_str() );
721 for ( int i = 0; i < size; i++ ) {
722 chunk = getNextChunk( stream, start, ok );
723 if ( !ok ) return false;
724 boundary.AddGroup( chunk.c_str() );
730 } // namespace HOMARD /end/