]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_DriverTools.hxx
Salome HOME
remove a reference to the $MED_ROOT_DIR in the Makefile.in wich is useless
[modules/med.git] / src / MEDMEM / MEDMEM_DriverTools.hxx
1 #ifndef DRIVERTOOLS_HXX
2 #define DRIVERTOOLS_HXX
3
4
5 #include "MEDMEM_define.hxx"
6 #include "MEDMEM_Exception.hxx"
7 #include "MEDMEM_Field.hxx"
8 #include <string>
9 #include <vector>
10 #include <set>
11 #include <list>
12 #include <map>
13 #include <iostream>
14 #include <iomanip>
15
16 namespace MEDMEM {
17 class MESH;
18 class CONNECTIVITY;
19 class COORDINATE;
20 class GROUP;
21 class FAMILY;
22 struct _noeud
23 {
24     mutable int number;
25     std::vector<double> coord;
26 };
27
28 typedef pair<int,int> _link; // a pair of node numbers
29
30 struct _maille
31 {
32     typedef std::map<int,_noeud>::iterator iter;
33     MED_EN::medGeometryElement geometricType;
34     std::vector< iter > sommets;
35     mutable unsigned ordre; // l'ordre est fixé après insertion dans le set, et ne change ni l'état, ni l'ordre -> mutable
36     mutable bool reverse; // to reverse sommets of a face
37     mutable list<unsigned> groupes; // the GROUPs maille belongs to, used to create families
38
39     _maille() : geometricType(MED_EN::MED_NONE),ordre(0),reverse(false)
40     {
41     };
42     _maille(MED_EN::medGeometryElement _geometricType, size_t nelem) : geometricType(_geometricType),ordre(0),reverse(false)
43     {
44         sommets.reserve(nelem);
45     };
46     int dimension() const // retourne la dimension de la maille
47     {
48         return geometricType/100;
49     };
50     bool operator < (const _maille& ma) const;
51     MED_EN::medEntityMesh getEntity(const int meshDimension) const throw (MEDEXCEPTION);
52    _link link(int i) const;
53 };
54
55 struct _mailleIteratorCompare // pour ordonner le set d'iterateurs sur mailles
56 {
57     bool operator () (std::set<_maille>::iterator i1, std::set<_maille>::iterator i2)
58     {
59         return *i1<*i2;
60     }
61 };
62
63 struct _groupe
64 {
65     typedef std::vector< std::set<_maille>::iterator>::const_iterator mailleIter;
66     std::string nom;
67     std::vector< std::set<_maille>::iterator > mailles; // iterateurs sur les mailles composant le groupe
68 //     std::set< std::set<_maille>::iterator, _mailleIteratorCompare > mailles; // iterateurs sur les mailles composant le groupe
69     std::vector<int> groupes; // indices des sous-groupes composant le groupe
70     std::map<const _maille*,int> relocMap; // map _maille* -> index in MEDMEM::GROUP.getNumber(MED_ALL_ELEMENTS). It is built by _intermediateMED::getGroups()
71     bool empty() const { return mailles.empty() && groupes.empty(); }
72 };
73
74 class _fieldBase {
75  public:
76   int                      nb_subcomponents;
77   int                      nb_components;
78   int                      group_id;
79   MED_EN::med_type_champ   type;
80   string                   name;
81   std::vector<std::string> comp_names;
82   _fieldBase( MED_EN::med_type_champ theType )
83     : nb_subcomponents(0), nb_components(0),group_id(-1),type(theType) {}
84   virtual std::list<FIELD_*> getField(std::vector<_groupe>& groupes) const = 0;
85   virtual void dump(std::ostream&) const;
86   virtual ~_fieldBase() {}
87 };
88
89 template< class T > class _field: public _fieldBase
90 {
91   std::vector< std::vector< T > > comp_values;
92   std::vector< int >              comp_supp_ids;
93  public:
94   _field< T > ( MED_EN::med_type_champ theType ): _fieldBase( theType ) {}
95   std::vector< T >& addComponent( int support_id, int nb_values );
96   std::list<FIELD_*> getField(std::vector<_groupe>& groupes) const;
97   virtual void dump(std::ostream&) const;
98 };
99
100 /*!
101  * \if developper
102  * Intermediate structure used by drivers to store data read from the other format file.
103  * The structure provides functions that transform the stored data to the MED format : 
104  * getCoordinate(), getConnectivity(), getGroups().
105  * The elements inserted in maillage and points are automaticaly ordered.
106  * Renumbering are performed by getConnectivity & getGroups before writing the MED structures.
107  * Read the conception ducumentation for more details.
108  * \endif
109  */
110 struct _intermediateMED
111 {
112     std::set<_maille> maillage;
113     std::vector<_groupe> groupes;
114     std::vector<GROUP *> medGroupes;
115     std::map< int, _noeud > points;
116     std::list< _fieldBase* > fields;
117     bool hasMixedCells; // true if there are groups with mixed entity types
118
119     CONNECTIVITY * getConnectivity(); // set MED connectivity from the intermediate structure
120     COORDINATE * getCoordinate(const string & coordinateSystem="CARTESIAN"); // set MED coordinate from the 
121                                                                              // intermediate structure
122     void getFamilies(std::vector<FAMILY *> & _famCell, std::vector<FAMILY *> & _famFace, 
123                      std::vector<FAMILY *> & _famEdge, std::vector<FAMILY *> & _famNode, MESH * _ptrMesh);
124     void getGroups(std::vector<GROUP *> & _groupCell, std::vector<GROUP *> & _groupFace, 
125             std::vector<GROUP *> & _groupEdge, std::vector<GROUP *> & _groupNode, MESH * _ptrMesh);
126     GROUP * getGroup( int i );
127
128     void getFields(std::list< FIELD_* >& fields);
129
130     // used by previous functions to renumber points & mesh.
131     void treatGroupes(); // detect groupes of mixed dimention
132     void numerotationMaillage(); 
133     void numerotationPoints();
134
135     ~_intermediateMED();
136 };
137
138 std::ostream& operator << (std::ostream& , const _maille& );
139 std::ostream& operator << (std::ostream& , const _groupe& );
140 std::ostream& operator << (std::ostream& , const _noeud& );
141 std::ostream& operator << (std::ostream& , const _intermediateMED& );
142 std::ostream& operator << (std::ostream& , const _fieldBase* );
143
144 };
145
146 template <class T>
147   std::vector< T >& MEDMEM::_field< T >::addComponent( int support_id, int nb_values )
148 {
149   if ( comp_supp_ids.empty() ) {
150     comp_supp_ids.reserve( nb_subcomponents * nb_components );
151     comp_values.reserve( nb_subcomponents * nb_components );
152   }
153   comp_supp_ids.push_back( support_id );
154   comp_values.push_back( std::vector< T >() );
155   std::vector< T >& res = comp_values.back();
156   res.resize( nb_values );
157   return res;
158 }
159
160
161 template <class T> 
162 std::list<MEDMEM::FIELD_*> MEDMEM::_field< T >::getField(std::vector<_groupe> & groupes) const
163 {
164   std::list<FIELD_*> res;
165   int i, j, i_comp, last_comp = 0;
166   while ( last_comp < comp_values.size() )
167   {
168     // find the first array of the next field - last_comp
169     int first_comp = last_comp;
170     std::set<int> id_set;
171     for ( i = first_comp + nb_components - 1; i < comp_values.size(); i += nb_components )
172       if ( id_set.insert( comp_supp_ids[ i ] ).second ) // unique support
173         last_comp = i + 1;
174
175     _groupe& grp = groupes[ group_id ];
176     if ( grp.empty () )
177       continue;
178     int nb_val = grp.relocMap.size();
179     ASSERT ( nb_val );
180
181     //create a filed
182     FIELD< T > * f = new FIELD< T >;
183     f->setNumberOfComponents( nb_components );
184     f->setComponentsNames( &comp_names[0] );
185     f->setNumberOfValues ( nb_val );
186     f->setName( name );
187     f->setValueType( type );
188     vector<string> str( nb_components );
189     f->setComponentsDescriptions( &str[0] );
190     f->setMEDComponentsUnits( &str[0] );
191     res.push_back( f );
192
193     MESSAGE(" make field <" << name << "> on group_id " << group_id <<
194             " relocMap.size: " << nb_val << " nb mailles: " << grp.mailles.size());
195     // set values
196     MEDARRAY< T > * medarray = new MEDARRAY< T >( nb_components, nb_val, MED_EN::MED_NO_INTERLACE );
197     f->setValue( medarray );
198     for ( j = 1; j <= nb_components; ++j ) {
199       // loop on arrays of j-th component
200       for ( i_comp = first_comp++; i_comp < last_comp; i_comp += nb_components )
201       {
202         // get nb elements in a group
203         int gr_id = comp_supp_ids[ i_comp ] - 1;
204         if ( gr_id < 0 || gr_id >= groupes.size() )
205           throw MEDEXCEPTION
206             (LOCALIZED(STRING("_field< T >::getField(), invalid group id: ")
207                               << gr_id << ", nb groups: " << groupes.size()));
208         _groupe & sub_grp = groupes[ gr_id ];
209         int nb_supp_elems = sub_grp.mailles.size();
210         MESSAGE(" comp_group_id " << gr_id << " nb values " << comp_values[ i_comp ].size() <<
211                 " relocMap.size: " << sub_grp.relocMap.size() << " nb mailles: " << nb_supp_elems);
212
213         // store values
214         const std::vector< T > & values = comp_values[ i_comp ];
215         bool oneValue = ( values.size() == 1 );
216         ASSERT( oneValue || values.size() == nb_supp_elems );
217         for ( int k = 0; k < nb_supp_elems; ++k )
218         {
219           const T& val = oneValue ? values[ 0 ] : values[ k ];
220           const _maille* ma = &(*sub_grp.mailles[ k ]);
221           std::map<const _maille*,int>::const_iterator ma_i = grp.relocMap.find( ma );
222           if ( ma_i == grp.relocMap.end() )
223             throw MEDEXCEPTION
224               (LOCALIZED(STRING("_field< T >::getField(), cant find elem index. ")
225                          << k << "-th elem: " << ma));
226           if ( ma_i->second > nb_val )
227             throw MEDEXCEPTION
228               (LOCALIZED(STRING("_field< T >::getField(), wrong elem position. ")
229                          << k << "-th elem: " << ma
230                          << ", pos (" << ma_i->second << ") must be <= " << nb_val));
231           medarray->setIJ( ma_i->second, j, val );
232         }
233       }
234     }
235   }
236   return res;
237 }
238
239
240 template <class T> void MEDMEM::_field< T >::dump(std::ostream& os) const
241 {
242   _fieldBase::dump(os);
243   os << endl;
244   for ( int i = 0 ; i < comp_values.size(); ++i )
245   {
246     os << "  group: " << setw(3) << comp_supp_ids[ i ] <<
247       "  nb values: " << comp_values[ i ].size() << endl;
248   }
249 }
250 #endif /* DRIVERTOOLS_HXX */