1 // Copyright (C) 2007-2013 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 : SauvReader.cxx
20 // Created : Tue Aug 16 13:57:42 2011
21 // Author : Edward AGAPOV (eap)
24 #include "SauvReader.hxx"
26 #include "SauvMedConvertor.hxx"
27 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
28 #include "NormalizedUnstructuredMesh.hxx"
29 #include "MEDCouplingRefCountObject.hxx"
35 using namespace ParaMEDMEM;
36 using namespace SauvUtilities;
39 #define GIBI_EQUAL(var_str, stat_str) (strncmp (var_str, stat_str, strlen(stat_str)) == 0)
41 //================================================================================
43 * \brief Creates a reader of a given sauve file
45 //================================================================================
47 SauvReader* SauvReader::New(const char *fileName) throw(INTERP_KERNEL::Exception)
49 if ( !fileName || strlen(fileName) < 1 ) THROW_IK_EXCEPTION("Invalid file name");
51 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr< SauvUtilities::FileReader> parser;
54 parser = new XDRReader( fileName );
57 SauvReader* reader = new SauvReader;
58 reader->_fileReader = parser.retn();
62 // try to open as ASCII
63 parser = new ASCIIReader( fileName );
66 SauvReader* reader = new SauvReader;
67 reader->_fileReader = parser.retn();
71 THROW_IK_EXCEPTION("Unable to open file |"<< fileName << "|");
73 //================================================================================
77 //================================================================================
79 SauvReader::~SauvReader()
81 _fileReader->decrRef();
84 //================================================================================
86 * \brief Return current line of ASCII file to report an error
88 //================================================================================
90 std::string SauvReader::lineNb() const
93 return string(" (line #") + SauvUtilities::toString
94 ( static_cast<SauvUtilities::ASCIIReader*>( _fileReader )->lineNb() ) + ")";
99 //================================================================================
101 * \brief Reads contents of the sauve file and convert it to MEDFileData
103 //================================================================================
105 ParaMEDMEM::MEDFileData * SauvReader::loadInMEDFileDS() throw(INTERP_KERNEL::Exception)
107 SauvUtilities::IntermediateMED iMed; // intermadiate DS
110 char* line; // a current line
111 const char* enregistrement_type=" ENREGISTREMENT DE TYPE";
113 while ( getNextLine(line, /*raiseOEF=*/false)) // external loop looking for "ENREGISTREMENT DE TYPE"
115 if ( isASCII() && !GIBI_EQUAL( line, enregistrement_type ))
116 continue; // "ENREGISTREMENT DE TYPE" not found -> read the next line
118 // read the number of a record
121 recordNumber = atoi( line + strlen(enregistrement_type) + 1 );
123 recordNumber = getInt();
126 if ( recordNumber == 2 )
128 else if (recordNumber == 4 )
130 else if (recordNumber == 7 )
132 else if (recordNumber == 5 )
133 break; // stop reading
136 THROW_IK_EXCEPTION("XDR : ENREGISTREMENT DE TYPE " << recordNumber << " not implemented!!!");
139 ParaMEDMEM::MEDFileData* medFileData = iMed.convertInMEDFileDS();
144 //================================================================================
146 * \brief Reads "ENREGISTREMENT DE TYPE 4"
148 //================================================================================
150 void SauvReader::readRecord4()
154 getInt(); // skip NIVEAU
155 getInt(); // skip ERREUR
156 _iMed->_spaceDim = getInt();
157 getFloat(); // skip DENSITE
163 const char* s = " NIVEAU 15 NIVEAU ERREUR 0 DIMENSION";
164 _iMed->_spaceDim = atoi( line + strlen( s ) + 1 );
165 if ( !GIBI_EQUAL( line, " NIVEAU" ))
166 THROW_IK_EXCEPTION( "Could not read space dimension" << lineNb() );
168 if ( _iMed->_spaceDim < 1 )
169 THROW_IK_EXCEPTION( "Invalid space dimension:" << _iMed->_spaceDim );
172 //================================================================================
174 * \brief Reads "ENREGISTREMENT DE TYPE 7"
176 //================================================================================
178 void SauvReader::readRecord7()
182 getInt(); // skip NOMBRE INFO CASTEM2000
183 getInt(); // skip IFOUR
184 getInt(); // skip NIFOUR
185 getInt(); // skip IFOMOD
186 getInt(); // skip IECHO
187 getInt(); // skip IIMPI
188 getInt(); // skip IOSPI
189 getInt(); // skip ISOTYP
190 getInt(); // skip NSDPGE
195 // NOMBRE INFO CASTEM2000 8
196 // IFOUR 2 NIFOUR 0 IFOMOD 2 IECHO 1 IIMPI 0 IOSPI 0 ISOTYP 1
205 //================================================================================
207 * \brief Reads the pile number, nb of objects and nb named of objects
209 //================================================================================
211 int SauvReader::readPileNumber(int& nbNamedObjects, int& nbObjects)
213 // FORMAT(' PILE NUMERO',I4,'NBRE ObjectS NOMMES',I8,'NBRE ObjectS',I8)
218 pileNumber = getInt(); next();
219 nbNamedObjects = getInt(); next();
220 nbObjects = getInt(); next();
226 const char *s1 = " PILE NUMERO", *s2 = "NBRE ObjectS NOMMES", *s3 = "NBRE ObjectS";
227 if ( ! GIBI_EQUAL( line, s1 ) )
228 THROW_IK_EXCEPTION("Could not read the pile number " << lineNb() );
229 line = line + strlen(s1);
230 pileNumber = atoi( line );
231 line = line + 4 + strlen(s2);
232 nbNamedObjects = atoi( line );
233 line = line + 8 + strlen(s3);
234 nbObjects = atoi( line );
236 if ( nbNamedObjects<0 )
237 THROW_IK_EXCEPTION("Invalid nb of named objects: " << nbNamedObjects << lineNb() );
239 THROW_IK_EXCEPTION("Invalid nb of objects: " << nbObjects << lineNb() );
240 // It appears to be a valid case
241 // if ( nbObjects<nbNamedObjects)
242 // THROW_IK_EXCEPTION("In PILE " << pileNumber <<
243 // " nb of objects is less than nb of named objects" << lineNb() );
247 //================================================================================
249 * \brief Reads "ENREGISTREMENT DE TYPE 2"
251 //================================================================================
253 void SauvReader::readRecord2()
255 if ( _iMed->_spaceDim == 0 )
256 THROW_IK_EXCEPTION("Missing ENREGISTREMENT DE TYPE 4");
258 // read a pile number
259 int pileNumber, nbNamedObjects, nbObjects;
260 pileNumber = readPileNumber(nbNamedObjects, nbObjects);
262 if ( !_encounteredPiles.insert( pileNumber ).second && // piles may repeat
266 // read object names and their indices
267 vector<string> objectNames(nbNamedObjects);
268 for ( initNameReading( nbNamedObjects ); more(); next() )
269 objectNames[ index() ] = getName();
271 vector<int> nameIndices(nbNamedObjects);
272 for ( initIntReading( nbNamedObjects ); more(); next() )
273 nameIndices[ index() ] = getInt();
275 switch ( pileNumber )
277 case PILE_SOUS_MAILLAGE:
278 read_PILE_SOUS_MAILLAGE(nbObjects, objectNames, nameIndices);
280 case PILE_NODES_FIELD:
281 read_PILE_NODES_FIELD(nbObjects, objectNames, nameIndices);
284 read_PILE_TABLES(nbObjects, objectNames, nameIndices);
287 read_PILE_LREEL(nbObjects, objectNames, nameIndices);
290 read_PILE_LOGIQUES(nbObjects, objectNames, nameIndices);
293 read_PILE_FLOATS(nbObjects, objectNames, nameIndices);
296 read_PILE_INTEGERS(nbObjects, objectNames, nameIndices);
299 read_PILE_STRINGS(nbObjects, objectNames, nameIndices);
302 read_PILE_LMOTS(nbObjects, objectNames, nameIndices);
305 read_PILE_NOEUDS(nbObjects, objectNames, nameIndices);
307 case PILE_COORDONNEES:
308 read_PILE_COORDONNEES(nbObjects, objectNames, nameIndices);
311 read_PILE_MODL(nbObjects, objectNames, nameIndices);
314 read_PILE_FIELD(nbObjects, objectNames, nameIndices);
318 THROW_IK_EXCEPTION("XDR : reading PILE " << pileNumber << " not implemented !!!");
322 //================================================================================
324 * \brief Reads "PILE NUMERO 1": gibi sub-meshes that are converted into med groups
326 //================================================================================
328 void SauvReader::read_PILE_SOUS_MAILLAGE(const int nbObjects,
329 std::vector<std::string>& objectNames,
330 std::vector<int>& nameIndices)
332 _iMed->_groups.reserve(nbObjects*2); // fields may add some groups
335 map<int,int> strangeGroupType;
338 for (int object=0; object!=nbObjects; ++object) // loop on sub-groups
341 int castemCellType = getIntNext();
342 int nbSubGroups = getIntNext();
343 int nbReferences = getIntNext();
344 int nbNodesPerElem = getIntNext();
345 int nbElements = getIntNext();
347 _iMed->_groups.push_back(Group());
348 SauvUtilities::Group & group = _iMed->_groups.back();
350 // Issue 0021311. Allocate places for names of referring groups
351 // that will be possibly filled after reading long names from
352 // PILE_TABLES and PILE_STRINGS
353 group._refNames.resize( nbReferences );
355 // castemCellType=0 corresponds to a sub-mesh composed of other sub-meshes
356 if (castemCellType==0 && nbSubGroups>0)
358 group._groups.resize( nbSubGroups );
359 for ( initIntReading( nbSubGroups ); more(); next() )
360 group._groups[ index() ] = & _iMed->_groups[ getInt() - 1 ];
361 //std::sort( group._groups.begin(), group._groups.end() ); // for _groups comparison in getFieldSupport()
365 for ( i = 0; i < nbReferences; i += 10 ) // FORMAT(10I8)
368 for (initIntReading(nbReferences); more(); next());
372 for ( i = 0; i < nbElements; i += 10 )
375 for (initIntReading(nbElements); more(); next());
377 // not a composit group
378 if (castemCellType>0 && nbSubGroups==0)
380 group._cellType = SauvUtilities::gibi2medGeom(castemCellType);
382 initIntReading( nbElements * nbNodesPerElem );
383 if ( group._cellType == INTERP_KERNEL::NORM_ERROR ) // look for group end
385 for ( ; more(); next());
386 strangeGroupType.insert( make_pair( object, castemCellType ));
390 // if ( group._cellType == MED_POINT1 ) group._cellType = NORM_ERROR; // issue 21199
392 // read connectivity of elements of a group
393 SauvUtilities::Cell ma( nbNodesPerElem );
394 SauvUtilities::Node* pNode;
395 group._cells.resize( nbElements );
396 for ( i = 0; i < nbElements; ++i )
399 for ( int n = 0; n < nbNodesPerElem; ++n )
401 int nodeID = getIntNext();
402 pNode = _iMed->getNode( nodeID );
403 ma._nodes[n] = pNode;
404 _iMed->_nbNodes += ( !pNode->isUsed() );
405 pNode->_number = nodeID;
407 ma._number = _iMed->getNbCellsOfType( group._cellType ) + 1;
408 group._cells[i] = _iMed->insert( group._cellType, ma );
415 for (i=0; i!=(int)objectNames.size(); ++i)
417 int grpID = nameIndices[i];
418 SauvUtilities::Group & grp = _iMed->_groups[ grpID-1 ];
419 if ( !grp._name.empty() ) // a group has several names
420 { // create a group with subgroup grp and named grp.name
421 _iMed->_groups.push_back(Group());
422 _iMed->_groups.back()._groups.push_back( &_iMed->_groups[ grpID-1 ]);
423 _iMed->_groups.back()._name = grp._name;
425 grp._name=objectNames[i];
427 map<int,int>::iterator it = strangeGroupType.find( grpID - 1 );
428 if ( it != strangeGroupType.end() )
429 cout << "Skip " << grp._name << " of not supported CASTEM type: " << it->second << endl;
432 } // read_PILE_SOUS_MAILLAGE()
434 //================================================================================
436 * \brief Skip "PILE NUMERO 18" of XDR file
438 //================================================================================
440 void SauvReader::read_PILE_LREEL (const int nbObjects, std::vector<std::string>&, std::vector<int>&)
444 for (int object=0; object!=nbObjects; ++object) // pour chaque Group
447 int nb_vals = getIntNext();
448 initDoubleReading(nb_vals);
449 for(int i=0; i<nb_vals; i++) next();
454 //================================================================================
456 * \brief Skip "PILE NUMERO 24" of XDR file
458 //================================================================================
460 void SauvReader::read_PILE_LOGIQUES (const int, std::vector<std::string>&, std::vector<int>&)
465 int nb_vals = getIntNext();
466 initIntReading(nb_vals);
467 for(int i=0; i<nb_vals; i++) next();
471 //================================================================================
473 * \brief Skip "PILE NUMERO 25" of XDR file
475 //================================================================================
477 void SauvReader::read_PILE_FLOATS (const int, std::vector<std::string>&, std::vector<int>&)
482 int nb_vals = getIntNext();
483 initDoubleReading(nb_vals);
484 for(int i=0; i<nb_vals; i++) next();
488 //================================================================================
490 * \brief Skip "PILE NUMERO 26" of XDR file
492 //================================================================================
494 void SauvReader::read_PILE_INTEGERS (const int, std::vector<std::string>&, std::vector<int>&)
499 int nb_vals = getIntNext();
500 initIntReading(nb_vals);
501 for(int i=0; i<nb_vals; i++) next();
505 //================================================================================
507 * \brief Skip "PILE NUMERO 29" of XDR file
509 //================================================================================
511 void SauvReader::read_PILE_LMOTS (const int nbObjects, std::vector<std::string>&, std::vector<int>&)
515 for (int object=0; object!=nbObjects; ++object) // pour chaque Group
518 int len = getIntNext();
519 int nb_vals = getIntNext();
520 int nb_char = len*nb_vals;
522 int fixed_length = 71;
523 while (nb_char_tmp < nb_char)
525 int remain_len = nb_char - nb_char_tmp;
527 if ( remain_len > fixed_length )
529 width = fixed_length;
535 initNameReading(1, width);
537 nb_char_tmp += width;
543 //================================================================================
545 * \brief Skip "PILE NUMERO 38" of XDR file
547 //================================================================================
549 void SauvReader::read_PILE_MODL (const int nbObjects, std::vector<std::string>&, std::vector<int>&)
553 for (int object=0; object!=nbObjects; ++object) // pour chaque Group
557 int n1 = getIntNext();
558 int nm2 = getIntNext();
559 int nm3 = getIntNext();
560 int nm4 = getIntNext();
561 int nm5 = getIntNext();
562 int n45 = getIntNext();
563 /*int nm6 =*/ getIntNext();
564 /*int nm7 =*/ getIntNext();
569 for (initIntReading(nm1); more(); next());
570 for (initIntReading(nm9); more(); next());
571 for (initNameReading(nm5, 8); more(); next());
572 for (initNameReading(nm2, 8); more(); next());
573 for (initNameReading(nm3, 8); more(); next());
574 for (initIntReading(nm4); more(); next());
577 } // Fin case pile 38
579 //================================================================================
581 * \brief Read "PILE NUMERO 32": links to node coordinates
583 //================================================================================
585 void SauvReader::read_PILE_NOEUDS (const int nbObjects, std::vector<std::string>&, std::vector<int>&)
588 int nb_indices = getIntNext();
590 if (nb_indices != nbObjects)
591 THROW_IK_EXCEPTION("Error of reading PILE NUMERO " << PILE_NOEUDS << lineNb() );
593 for ( initIntReading( nbObjects ); more(); next() )
595 int coordID = getInt();
596 _iMed->getNode( index()+1 )->_coordID = coordID;
600 //================================================================================
602 * \brief Read "PILE NUMERO 33": node coordinates
604 //================================================================================
606 void SauvReader::read_PILE_COORDONNEES (const int nbObjects, std::vector<std::string>&, std::vector<int>&)
609 int nbReals = getIntNext();
611 if ( nbReals < (int)(_iMed->_nbNodes*(_iMed->_spaceDim+1)) )
612 THROW_IK_EXCEPTION("Error of reading PILE NUMERO " << PILE_COORDONNEES << lineNb() );
614 // there are coordinates + density for each node
615 _iMed->_coords.resize( nbReals - nbReals/(_iMed->_spaceDim+1));
616 double* coordPtr = &_iMed->_coords[0];
618 initDoubleReading( nbReals );
621 for (unsigned j = 0; j < _iMed->_spaceDim; ++j, next())
622 *coordPtr++ = getDouble();
629 //================================================================================
631 * \brief Finds or create a Group equal to a given field support
633 //================================================================================
635 SauvUtilities::Group* SauvReader::getFieldSupport(const vector<SauvUtilities::Group*>& supports)
637 SauvUtilities::Group* group = NULL;
638 set<SauvUtilities::Group*> sup_set( supports.begin(), supports.end() );
639 if (sup_set.size() == 1 ) // one or equal supports
645 // try to find an existing composite group with the same sub-groups
646 for ( size_t i = 0; i < _iMed->_groups.size() && !group; ++i )
648 Group & grp = _iMed->_groups[i];
649 if (sup_set.size() == grp._groups.size())
651 bool sameOrder = true;
652 for ( size_t j = 0; j < supports.size() && sameOrder; ++j )
653 sameOrder = ( supports[j] == grp._groups[ j % grp._groups.size() ]);
655 group = & _iMed->_groups[i];
658 if ( !group ) // no such a group, add a new one
660 vector<SauvUtilities::Group*> newGroups( supports.begin(),
661 supports.begin() + sup_set.size() );
662 // check if supports includes newGroups in the same order
663 bool sameOrder = true;
664 for ( size_t j = newGroups.size(); j < supports.size() && sameOrder; ++j )
665 sameOrder = ( supports[j] == newGroups[ j % newGroups.size() ]);
668 _iMed->_groups.push_back( SauvUtilities::Group() );
669 group = & _iMed->_groups.back();
670 group->_groups.swap( newGroups );
675 group->_isProfile = true;
679 //================================================================================
681 * \brief set field names
683 //================================================================================
685 void SauvReader::setFieldNames(const vector<SauvUtilities::DoubleField* >& fields,
686 const vector<string>& objets_nommes,
687 const vector<int>& indices_objets_nommes)
690 for ( i = 0; i < indices_objets_nommes.size(); ++i )
692 int fieldIndex = indices_objets_nommes[ i ];
693 if ( fields[ fieldIndex - 1 ] )
694 fields[ fieldIndex - 1 ]->_name = objets_nommes[ i ];
698 //================================================================================
700 * \brief Read "PILE NUMERO 2": NODE FIELDS
702 //================================================================================
704 void SauvReader::read_PILE_NODES_FIELD (const int nbObjects,
705 std::vector<std::string>& objectNames,
706 std::vector<int>& nameIndices)
708 _iMed->_nodeFields.resize( nbObjects, (SauvUtilities::DoubleField*) 0 );
709 for (int object=0; object!=nbObjects; ++object) // loop on fields
711 // EXAMPLE ( with no values )
714 // (2) -88 0 3 -89 0 1 -90 0 2 -91
716 // (3) FX FY FZ FZ FX FY FLX
718 // (5) cree par muc pri
722 // (1): nb subcomponents, nb components(total), IFOUR, nb attributes
723 int nb_sub, total_nb_comp, nb_attr;
726 nb_sub = getIntNext();
727 total_nb_comp = getIntNext();
728 next(); // ignore IFOUR
729 nb_attr = getIntNext();
730 if ( nb_sub < 0 || total_nb_comp < 0 || nb_attr < 0 )
731 THROW_IK_EXCEPTION("Error of field reading " << lineNb());
733 // (2) loop on subcomponents of a field, for each read
734 // (a) support, (b) number of values and (c) number of components
735 vector<Group*> supports( nb_sub );
736 vector<int> nb_values ( nb_sub );
737 vector<int> nb_comps ( nb_sub );
738 int total_nb_values = 0;
739 initIntReading( nb_sub * 3 );
740 for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
742 int supId = -getIntNext(); // (a) reference to support
743 if ( supId < 1 || supId > (int)_iMed->_groups.size() )
744 THROW_IK_EXCEPTION("Wrong mesh reference: "<< supId << lineNb() );
745 supports[ i_sub ] = &_iMed->_groups[ supId-1 ]; // (a) reference to support
747 nb_values[ i_sub ] = getIntNext(); // (b) nb points
748 total_nb_values += nb_values[ i_sub ];
749 if ( nb_values[ i_sub ] < 0 )
750 THROW_IK_EXCEPTION(" Wrong nb of points: " << nb_values[ i_sub ] << lineNb() );
751 nb_comps[ i_sub ] = getInt(); next(); // (c) nb of components in i_sub
754 // create a field if there are values
755 SauvUtilities::DoubleField* fdouble = 0;
756 if ( total_nb_values > 0 )
757 fdouble = new DoubleField( nb_sub, total_nb_comp );
758 _iMed->_nodeFields[ object ] = fdouble;
760 // (3) component names
761 initNameReading( total_nb_comp, 4 );
762 for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
764 // store support id and nb components of a sub
766 fdouble->_sub[ i_sub ].setData( nb_comps[ i_sub ], supports[ i_sub ] );
767 for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp, next() )
769 // store component name
770 string compName = getName();
772 fdouble->_sub[ i_sub ].compName( i_comp ) = compName;
775 // (4) nb harmonics ( ignored )
776 for ( initIntReading( total_nb_comp ); more(); next() );
777 // (5) TYPE ( ignored )
778 for (initNameReading(1, /*length=*/71); more(); next());
779 // (6) TITRE ( ignored )
780 for (initNameReading(1, /*length=*/71); more(); next());
781 // (7) attributes ( ignored )
782 for ( initIntReading( nb_attr ); more(); next() );
784 for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
786 // loop on components: read values
787 initDoubleReading( nb_values[ i_sub ] * nb_comps[ i_sub ] );
788 for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp )
792 vector<double>& vals = fdouble->addComponent( nb_values[ i_sub ] );
793 for ( int i = 0; more() && i < nb_values[ i_sub ]; next(), ++i )
794 vals[ i ] = getDouble();
798 for ( int i = 0; i < nb_values[ i_sub ]; next(), ++i );
801 } // loop on subcomponents of a field
803 // set a supporting group including all subs supports but only
804 // if all subs have the same components
805 if ( fdouble && fdouble->hasSameComponentsBySupport() )
806 fdouble->_group = getFieldSupport( supports );
808 for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
809 fdouble->_sub[ i_sub ]._support->_isProfile = true;
811 } // end loop on field objects
814 setFieldNames( _iMed->_nodeFields, objectNames, nameIndices );
816 } // read_PILE_NODES_FIELD()
818 //================================================================================
820 * \brief Read "PILE NUMERO 39": FIELDS
822 //================================================================================
824 void SauvReader::read_PILE_FIELD (const int nbObjects,
825 std::vector<std::string>& objectNames,
826 std::vector<int>& nameIndices)
831 // (2) CARACTERISTIQUES
832 // (3) -15 317773 4 0 0 0 -2 0 3
835 // (6) 317767 317761 317755 317815
836 // (7) YOUN NU H SIGY
837 // (8) REAL*8 REAL*8 REAL*8 REAL*8
839 // (10) 2.00000000000000E+05
841 // (12) 3.30000000000000E-01
843 // (14) 1.00000000000000E+04
845 // (16) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02
846 // (17) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02
849 _iMed->_cellFields.resize( nbObjects, (SauvUtilities::DoubleField*) 0 );
850 for (int object=0; object!=nbObjects; ++object) // pour chaque field
853 int i_sub, nb_sub = getIntNext(); // (1) <nb_sub> 2 6 <title length>
856 int title_length = getIntNext(); // <title length>
858 THROW_IK_EXCEPTION("Error of field reading: wrong nb of subcomponents " << nb_sub << lineNb() );
865 initNameReading(1, title_length);
866 description = getName();
872 getNextLine( line ); // (2) title
873 const int len = 72; // line length
874 description = string(line + len - title_length, title_length); // title is right justified
877 // look for a line starting with '-' : <reference to support>
880 initIntReading( nb_sub * 9 );
885 initIntReading( nb_sub * 9 );
886 } while ( getInt() >= 0 );
888 int total_nb_comp = 0;
889 vector<Group*> supports( nb_sub );
890 vector<int> nb_comp( nb_sub );
891 for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
893 int supportId = -getIntNext(); // <reference to support>
894 next(); // ignore <address>
895 nb_comp [ i_sub ] = getIntNext(); // <nb of components in the sub>
896 for ( int i = 0; i < 6; ++i ) next(); // ignore 6 ints, in example "0 0 0 -2 0 3"
898 if ( supportId < 1 || supportId > (int)_iMed->_groups.size() )
899 THROW_IK_EXCEPTION("Error of field reading: wrong mesh reference "<< supportId << lineNb() );
900 if ( nb_comp[ i_sub ] < 0 )
901 THROW_IK_EXCEPTION("Error of field reading: wrong nb of components " <<nb_comp[ i_sub ] << lineNb() );
903 supports[ i_sub ] = &_iMed->_groups[ supportId-1 ];
904 total_nb_comp += nb_comp[ i_sub ];
907 for ( initNameReading( nb_sub, 17 ); more(); next() );
909 for ( initNameReading( nb_sub ); more(); next() );
911 // loop on subcomponents of a field, each of which refers to
912 // a certain support and has its own number of components;
913 // read component values
914 SauvUtilities::DoubleField* fdouble = 0;
915 for ( i_sub = 0; i_sub < nb_sub; ++ i_sub )
917 vector<string> comp_names( nb_comp[ i_sub ]), comp_type( nb_comp[ i_sub ]);
918 // (6) nb_comp addresses of MELVAL structure
919 for ( initIntReading( nb_comp[ i_sub ] ); more(); next() );
920 // (7) component names
921 for ( initNameReading( nb_comp[ i_sub ] ); more(); next() )
922 comp_names[ index() ] = getName();
923 // (8) component type
924 for ( initNameReading( nb_comp[ i_sub ], 17 ); more(); next() ) // 17 is name width
926 comp_type[ index() ] = getName();
927 // component types must be the same
928 if ( index() > 0 && comp_type[ index() ] != comp_type[ index() - 1] )
929 THROW_IK_EXCEPTION( "Error of field reading: diff component types <"
930 << comp_type[ index() ] << "> != <" << comp_type[ index() - 1 ]
931 << ">" << lineNb() );
933 // now type is known, create a field, one for all subs
934 bool isReal = (nb_comp[i_sub] > 0) ? (comp_type[0] == "REAL*8") : true;
935 if ( !fdouble && total_nb_comp )
938 cout << "Warning: read NOT REAL field, type <" << comp_type[0] << ">" << lineNb() << endl;
939 _iMed->_cellFields[ object ] = fdouble = new SauvUtilities::DoubleField( nb_sub, total_nb_comp );
940 fdouble->_description = description;
942 // store support id and nb components of a sub
944 fdouble->_sub[ i_sub ].setData( nb_comp[ i_sub ], supports[ i_sub ]);
945 // loop on components: read values
946 for ( int i_comp = 0; i_comp < nb_comp[ i_sub ]; ++i_comp )
950 int nb_val_by_elem = getIntNext();
951 int nb_values = getIntNext();
954 fdouble->_sub[ i_sub ]._nb_gauss[ i_comp ] = nb_val_by_elem;
957 nb_values *= nb_val_by_elem;
960 vector<double> & vals = fdouble->addComponent( nb_values );
961 for ( isReal ? initDoubleReading( nb_values ) : initIntReading( nb_values ); more(); next())
962 vals[ index() ] = getDouble();
963 // store component name
964 fdouble->_sub[ i_sub ].compName( i_comp ) = comp_names[ i_comp ];
968 for ( isReal ? initDoubleReading( nb_values ) : initIntReading( nb_values ); more(); next() ) ;
971 } // loop on subcomponents of a field
973 // set id of a group including all sub supports but only
974 // if all subs have the same nb of components
975 if ( fdouble && fdouble->hasSameComponentsBySupport() )
976 fdouble->_group = getFieldSupport( supports );
978 for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
979 fdouble->_sub[ i_sub ]._support->_isProfile = true;
981 } // end loop on field objects
984 setFieldNames( _iMed->_cellFields, objectNames, nameIndices );
986 } // read_PILE_FIELD()
988 //================================================================================
990 * \brief Read "PILE NUMERO 10": TABLES
992 //================================================================================
994 void SauvReader::read_PILE_TABLES (const int nbObjects,
995 std::vector<std::string>& objectNames,
996 std::vector<int>& nameIndices)
998 // IMP 0020434: mapping GIBI names to MED names
1000 string table_med_mail = "MED_MAIL";
1001 string table_med_cham = "MED_CHAM";
1002 string table_med_comp = "MED_COMP";
1003 int table_med_mail_id = -1;
1004 int table_med_cham_id = -1;
1005 int table_med_comp_id = -1;
1006 for (size_t iname = 0; iname < objectNames.size(); iname++)
1007 if (objectNames[iname] == table_med_mail) table_med_mail_id = nameIndices[iname];
1008 else if (objectNames[iname] == table_med_cham) table_med_cham_id = nameIndices[iname];
1009 else if (objectNames[iname] == table_med_comp) table_med_comp_id = nameIndices[iname];
1012 if (table_med_mail_id < 0 && table_med_cham_id < 0 && table_med_comp_id < 0)
1015 for (int itable = 1; itable <= nbObjects; itable++)
1017 // read tables "MED_MAIL", "MED_CHAM" and "MED_COMP", that keeps correspondence
1018 // between GIBI names (8 symbols if any) and MED names (possibly longer)
1020 int nb_table_vals = getIntNext();
1021 if (nb_table_vals < 0)
1022 THROW_IK_EXCEPTION("Error of reading PILE NUMERO 10" << lineNb() );
1024 int name_i_med_pile;
1025 initIntReading(nb_table_vals);
1026 for (int i = 0; i < nb_table_vals/4; i++)
1028 if (itable == table_med_mail_id ||
1029 itable == table_med_cham_id ||
1030 itable == table_med_comp_id)
1032 nameGIBItoMED name_i;
1033 name_i_med_pile = getIntNext();
1034 name_i.med_id = getIntNext();
1035 name_i.gibi_pile = getIntNext();
1036 name_i.gibi_id = getIntNext();
1038 if (name_i_med_pile != PILE_STRINGS)
1040 // error: med(long) names are always kept in PILE_STRINGS
1042 if (itable == table_med_mail_id)
1044 if (name_i.gibi_pile != PILE_SOUS_MAILLAGE) {
1045 // error: must be PILE_SOUS_MAILLAGE
1047 _iMed->_listGIBItoMED_mail.push_back(name_i);
1049 else if (itable == table_med_cham_id)
1051 if (name_i.gibi_pile != PILE_FIELD &&
1052 name_i.gibi_pile != PILE_NODES_FIELD)
1054 // error: must be PILE_FIELD or PILE_NODES_FIELD
1056 _iMed->_listGIBItoMED_cham.push_back(name_i);
1058 else if (itable == table_med_comp_id)
1060 if (name_i.gibi_pile != PILE_STRINGS)
1062 // error: gibi(short) names of components are kept in PILE_STRINGS
1064 _iMed->_listGIBItoMED_comp.push_back(name_i);
1070 for ( int ii = 0; ii < 4; ++ii ) next();
1073 } // for (int itable = 0; itable < nbObjects; itable++)
1076 //================================================================================
1078 * \brief Read "PILE NUMERO 27"
1080 //================================================================================
1082 void SauvReader::read_PILE_STRINGS (const int nbObjects,
1083 std::vector<std::string>& objectNames,
1084 std::vector<int>& nameIndices)
1086 // IMP 0020434: mapping GIBI names to MED names
1088 int stringLen = getIntNext();
1089 int nbSubStrings = getIntNext();
1090 if (nbSubStrings != nbObjects)
1091 THROW_IK_EXCEPTION("Error of reading PILE NUMERO 27" << lineNb() );
1093 string aWholeString;
1096 const int fixedLength = 71;
1097 while ((int)aWholeString.length() < stringLen)
1099 int remainLen = stringLen - aWholeString.length();
1101 if ( remainLen > fixedLength )
1109 initNameReading(1, len);
1110 aWholeString += getName();
1117 const int fixedLength = 71;
1118 while ((int)aWholeString.length() < stringLen)
1120 getNextLine( line );
1121 int remainLen = stringLen - aWholeString.length();
1122 if ( remainLen > fixedLength )
1124 aWholeString += line + 1;
1128 aWholeString += line + ( 72 - remainLen );
1134 initIntReading(nbSubStrings);
1135 for (int istr = 1; istr <= nbSubStrings; istr++, next())
1137 currOffset = getInt();
1139 _iMed->_mapStrings[istr] = aWholeString.substr(prevOffset, currOffset - prevOffset);
1140 prevOffset = currOffset;