1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/
20 #ifndef DRIVERTOOLS_HXX
21 #define DRIVERTOOLS_HXX
24 #include "MEDMEM_define.hxx"
25 #include "MEDMEM_Exception.hxx"
26 #include "MEDMEM_Field.hxx"
44 std::vector<double> coord;
47 typedef pair<int,int> _link; // a pair of node numbers
51 typedef std::map<int,_noeud>::iterator iter;
52 MED_EN::medGeometryElement geometricType;
53 std::vector< iter > sommets;
54 mutable unsigned ordre; // l'ordre est fixé après insertion dans le set, et ne change ni l'état, ni l'ordre -> mutable
55 mutable bool reverse; // to reverse sommets of a face
56 mutable list<unsigned> groupes; // the GROUPs maille belongs to, used to create families
58 _maille() : geometricType(MED_EN::MED_NONE),ordre(0),reverse(false)
61 _maille(MED_EN::medGeometryElement _geometricType, size_t nelem) : geometricType(_geometricType),ordre(0),reverse(false)
63 sommets.reserve(nelem);
65 int dimension() const // retourne la dimension de la maille
67 return geometricType/100;
69 bool operator < (const _maille& ma) const;
70 MED_EN::medEntityMesh getEntity(const int meshDimension) const throw (MEDEXCEPTION);
71 _link link(int i) const;
74 struct _mailleIteratorCompare // pour ordonner le set d'iterateurs sur mailles
76 bool operator () (std::set<_maille>::iterator i1, std::set<_maille>::iterator i2)
84 typedef std::vector< std::set<_maille>::iterator>::const_iterator mailleIter;
86 std::vector< std::set<_maille>::iterator > mailles; // iterateurs sur les mailles composant le groupe
87 std::vector<int> groupes; // indices des sous-groupes composant le groupe
88 std::map<const _maille*,int> relocMap; // map _maille* -> index in MEDMEM::GROUP.getNumber(MED_ALL_ELEMENTS). It is built by _intermediateMED::getGroups()
89 bool empty() const { return mailles.empty() && groupes.empty(); }
93 // a field contains several subcomponents each referring to its own support and
94 // having several named components
96 int _supp_id; // group index within _intermediateMED::groupes
97 std::vector<std::string> _comp_names; // componenet names
98 void setData( int nb_comp, int supp_id )
99 { _supp_id = supp_id - 1; _comp_names.resize(nb_comp); }
100 int nbComponents() const { return _comp_names.size(); }
101 std::string & compName( int i_comp ) { return _comp_names[ i_comp ]; }
103 std::vector< _sub_data > _sub;
104 int _group_id; // group index within _intermediateMED::groupes
105 // if _group_id == -1 then each subcomponent makes a separate MEDMEM::FIELD, else all subcomponents
106 // are converted into one MEDMEM::FIELD. The latter is possible only if nb of components in all subs
107 // is the same and supports of subcomponents do not overlap
108 MED_EN::med_type_champ _type;
111 _fieldBase( MED_EN::med_type_champ theType, int nb_sub )
112 : _group_id(-1),_type(theType) { _sub.resize( nb_sub ); }
113 virtual std::list<std::pair< FIELD_*, int> > getField(std::vector<_groupe>& groupes) const = 0;
114 void getGroupIds( std::set<int> & ids, bool all ) const; // return ids of main and/or sub-groups
115 bool hasCommonSupport() const { return _group_id >= 0; } // true if there is one support for all subs
116 bool hasSameComponentsBySupport() const;
117 virtual void dump(std::ostream&) const;
118 virtual ~_fieldBase() {}
121 template< class T > class _field: public _fieldBase
123 std::vector< std::vector< T > > comp_values;
125 _field< T > ( MED_EN::med_type_champ theType, int nb_sub, int total_nb_comp )
126 : _fieldBase( theType, nb_sub ) { comp_values.reserve( total_nb_comp ); }
127 std::vector< T >& addComponent( int nb_values ); // return a vector ready to fill in
128 std::list<std::pair< FIELD_*, int> > getField(std::vector<_groupe>& groupes) const;
129 virtual void dump(std::ostream&) const;
134 * Intermediate structure used by drivers to store data read from the other format file.
135 * The structure provides functions that transform the stored data to the MED format :
136 * getCoordinate(), getConnectivity(), getGroups().
137 * The elements inserted in maillage and points are automaticaly ordered.
138 * Renumbering are performed by getConnectivity & getGroups before writing the MED structures.
139 * Read the conception ducumentation for more details.
142 struct _intermediateMED
144 std::set<_maille> maillage;
145 std::vector<_groupe> groupes;
146 std::vector<GROUP *> medGroupes;
147 std::map< int, _noeud > points;
148 std::list< _fieldBase* > fields;
149 bool hasMixedCells; // true if there are groups with mixed entity types
151 CONNECTIVITY * getConnectivity(); // set MED connectivity from the intermediate structure
152 COORDINATE * getCoordinate(const string & coordinateSystem="CARTESIAN"); // set MED coordinate from the
153 // intermediate structure
154 void getFamilies(std::vector<FAMILY *> & _famCell, std::vector<FAMILY *> & _famFace,
155 std::vector<FAMILY *> & _famEdge, std::vector<FAMILY *> & _famNode, MESH * _ptrMesh);
156 void getGroups(std::vector<GROUP *> & _groupCell, std::vector<GROUP *> & _groupFace,
157 std::vector<GROUP *> & _groupEdge, std::vector<GROUP *> & _groupNode, MESH * _ptrMesh);
158 GROUP * getGroup( int i );
160 void getFields(std::list< FIELD_* >& fields);
162 // used by previous functions to renumber points & mesh.
163 void treatGroupes(); // detect groupes of mixed dimention
164 void numerotationMaillage();
165 void numerotationPoints();
170 std::ostream& operator << (std::ostream& , const _maille& );
171 std::ostream& operator << (std::ostream& , const _groupe& );
172 std::ostream& operator << (std::ostream& , const _noeud& );
173 std::ostream& operator << (std::ostream& , const _intermediateMED& );
174 std::ostream& operator << (std::ostream& , const _fieldBase* );
176 // ===========================================================
177 // field template implementation //
178 // ===========================================================
181 std::vector< T >& _field< T >::addComponent( int nb_values )
183 comp_values.push_back( std::vector< T >() );
184 std::vector< T >& res = comp_values.back();
185 res.resize( nb_values );
189 //=======================================================================
190 //function : getField
191 //purpose : return list of pairs< field, supporting_group_id >
192 //=======================================================================
195 std::list<std::pair< FIELD_*, int> > _field< T >::getField(std::vector<_groupe> & groupes) const
197 std::list<std::pair< FIELD_*, int> > res;
200 if ( hasCommonSupport() ) { // several subs are combined into one field
201 grp = & groupes[ _group_id ];
202 if ( !grp || grp->empty() )
206 int i_comp_tot = 0, nb_fields = 0;
207 std::set<int> supp_id_set;
208 // loop on subs of this field
209 std::vector< _sub_data >::const_iterator sub_data = _sub.begin();
210 for ( int i_sub = 1; sub_data != _sub.end(); ++sub_data, ++i_sub )
212 // nb values in a field
213 if ( !hasCommonSupport() )
214 grp = & groupes[ sub_data->_supp_id ];
215 int nb_val = grp->relocMap.size();
217 INFOS("Skip field <" << _name << ">: invalid supporting group "
218 << (hasCommonSupport() ? _group_id : sub_data->_supp_id )
219 << " of " << i_sub << "-th subcomponent" );
224 if ( !f || !hasCommonSupport() || !supp_id_set.insert( sub_data->_supp_id ).second )
229 f->setNumberOfComponents( sub_data->nbComponents() );
230 f->setComponentsNames( & sub_data->_comp_names[ 0 ] );
231 f->setNumberOfValues ( nb_val );
233 f->setValueType( _type );
234 vector<string> str( sub_data->nbComponents() );
235 f->setComponentsDescriptions( &str[0] );
236 f->setMEDComponentsUnits( &str[0] );
237 res.push_back( make_pair( f , hasCommonSupport() ? _group_id : sub_data->_supp_id ));
238 MESSAGE(" MAKE " << nb_fields << "-th field <" << _name << "> on group_id " << _group_id );
241 MEDARRAY< T > * medarray =
242 new MEDARRAY< T >( sub_data->nbComponents(), nb_val, MED_EN::MED_NO_INTERLACE );
243 f->setValue( medarray );
244 // loop on components of a sub
245 for ( int i_comp = 0; i_comp < sub_data->nbComponents(); ++i_comp )
247 // get nb elements in a group
248 _groupe & sub_grp = groupes[ sub_data->_supp_id ];
249 int nb_supp_elems = sub_grp.mailles.size();
250 MESSAGE("insert sub data, group_id: " << sub_data->_supp_id <<
251 ", nb values: " << comp_values[ i_comp_tot ].size() <<
252 ", relocMap.size: " << sub_grp.relocMap.size() <<
253 ", nb mailles: " << nb_supp_elems);
256 const std::vector< T > & values = comp_values[ i_comp_tot++ ];
257 bool oneValue = ( values.size() == 1 );
258 ASSERT( oneValue || values.size() == nb_supp_elems );
259 for ( int k = 0; k < nb_supp_elems; ++k )
261 const T& val = oneValue ? values[ 0 ] : values[ k ];
262 const _maille* ma = &(*sub_grp.mailles[ k ]);
263 std::map<const _maille*,int>::const_iterator ma_i = grp->relocMap.find( ma );
264 if ( ma_i == grp->relocMap.end() )
266 (LOCALIZED(STRING("_field< T >::getField(), cant find elem index. ")
267 << k << "-th elem: " << ma));
268 if ( ma_i->second > nb_val )
270 (LOCALIZED(STRING("_field< T >::getField(), wrong elem position. ")
271 << k << "-th elem: " << ma
272 << ", pos (" << ma_i->second << ") must be <= " << nb_val));
273 medarray->setIJ( ma_i->second, i_comp + 1, val );
281 template <class T> void _field< T >::dump(std::ostream& os) const
283 _fieldBase::dump(os);
285 for ( int i = 0 ; i < comp_values.size(); ++i )
287 os << " " << i+1 << "-th component, nb values: " << comp_values[ i ].size() << endl;
291 }; // namespace MEDMEM
293 #endif /* DRIVERTOOLS_HXX */