1 #ifndef DRIVERTOOLS_HXX
2 #define DRIVERTOOLS_HXX
5 #include "MEDMEM_define.hxx"
6 #include "MEDMEM_Exception.hxx"
7 #include "MEDMEM_Field.hxx"
25 std::vector<double> coord;
28 typedef pair<int,int> _link; // a pair of node numbers
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
39 _maille() : geometricType(MED_EN::MED_NONE),ordre(0),reverse(false)
42 _maille(MED_EN::medGeometryElement _geometricType, size_t nelem) : geometricType(_geometricType),ordre(0),reverse(false)
44 sommets.reserve(nelem);
46 int dimension() const // retourne la dimension de la maille
48 return geometricType/100;
50 bool operator < (const _maille& ma) const;
51 MED_EN::medEntityMesh getEntity(const int meshDimension) const throw (MEDEXCEPTION);
52 _link link(int i) const;
55 struct _mailleIteratorCompare // pour ordonner le set d'iterateurs sur mailles
57 bool operator () (std::set<_maille>::iterator i1, std::set<_maille>::iterator i2)
65 typedef std::vector< std::set<_maille>::iterator>::const_iterator mailleIter;
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(); }
79 MED_EN::med_type_champ type;
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() {}
89 template< class T > class _field: public _fieldBase
91 std::vector< std::vector< T > > comp_values;
92 std::vector< int > comp_supp_ids;
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;
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.
110 struct _intermediateMED
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
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 );
128 void getFields(std::list< FIELD_* >& fields);
130 // used by previous functions to renumber points & mesh.
131 void treatGroupes(); // detect groupes of mixed dimention
132 void numerotationMaillage();
133 void numerotationPoints();
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* );
147 std::vector< T >& MEDMEM::_field< T >::addComponent( int support_id, int nb_values )
149 if ( comp_supp_ids.empty() ) {
150 comp_supp_ids.reserve( nb_subcomponents * nb_components );
151 comp_values.reserve( nb_subcomponents * nb_components );
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 );
162 std::list<MEDMEM::FIELD_*> MEDMEM::_field< T >::getField(std::vector<_groupe> & groupes) const
164 std::list<FIELD_*> res;
165 int i, j, i_comp, last_comp = 0;
166 while ( last_comp < comp_values.size() )
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
175 _groupe& grp = groupes[ group_id ];
178 int nb_val = grp.relocMap.size();
182 FIELD< T > * f = new FIELD< T >;
183 f->setNumberOfComponents( nb_components );
184 f->setComponentsNames( &comp_names[0] );
185 f->setNumberOfValues ( nb_val );
187 f->setValueType( type );
188 vector<string> str( nb_components );
189 f->setComponentsDescriptions( &str[0] );
190 f->setMEDComponentsUnits( &str[0] );
193 MESSAGE(" make field <" << name << "> on group_id " << group_id <<
194 " relocMap.size: " << nb_val << " nb mailles: " << grp.mailles.size());
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 )
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() )
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);
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 )
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() )
224 (LOCALIZED(STRING("_field< T >::getField(), cant find elem index. ")
225 << k << "-th elem: " << ma));
226 if ( ma_i->second > nb_val )
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 );
240 template <class T> void MEDMEM::_field< T >::dump(std::ostream& os) const
242 _fieldBase::dump(os);
244 for ( int i = 0 ; i < comp_values.size(); ++i )
246 os << " group: " << setw(3) << comp_supp_ids[ i ] <<
247 " nb values: " << comp_values[ i ].size() << endl;
250 #endif /* DRIVERTOOLS_HXX */