Back to index

salome-med  6.5.0
MEDMEM_DriverTools.hxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #ifndef DRIVERTOOLS_HXX
00024 #define DRIVERTOOLS_HXX
00025 
00026 #include <MEDMEM.hxx>
00027 
00028 #include "MEDMEM_define.hxx"
00029 #include "MEDMEM_Exception.hxx"
00030 #include "MEDMEM_FieldForward.hxx"
00031 #include "MEDMEM_ArrayInterface.hxx"
00032 #include "MEDMEM_Group.hxx"
00033 #include "MEDMEM_GaussLocalization.hxx"
00034 
00035 #include <string>
00036 #include <vector>
00037 #include <set>
00038 #include <list>
00039 #include <map>
00040 #include <iostream>
00041 #include <iomanip>
00042 #include <algorithm>
00043 
00044 // Way of storing values with gauss points by CASTEM: full/no interlace.
00045 // Remove code switched by this symbol as soon as the way is found out,
00046 // from here and from gibi driver
00047 #define CASTEM_FULL_INTERLACE
00048 
00049 
00050 namespace MEDMEM {
00051 class MESH;
00052 class CONNECTIVITY;
00053 class COORDINATE;
00054 class GROUP;
00055 class FAMILY;
00056 class FIELD_;
00057 class _intermediateMED;
00058 
00059 // ==============================================================================
00060 struct MEDMEM_EXPORT _noeud
00061 {
00062   mutable int number; // negative if node is merged
00063   std::vector<double> coord;
00064 };
00065 
00066 // ==============================================================================
00067 typedef pair<int,int> _link; // a pair of node numbers
00068 
00069 // ==============================================================================
00070 struct MEDMEM_EXPORT _maille
00071 {
00072   typedef std::map<int,_noeud>::iterator TNoeud; //iter;
00073   std::vector< TNoeud >      sommets;
00074   MED_EN::medGeometryElement geometricType;
00075   mutable bool               reverse; // to reverse sommets of a face
00076   mutable int*               sortedNodeIDs; // for comparison and merge
00077   //mutable list<unsigned>   groupes; // the GROUPs maille belongs to, used to create families
00078 
00079   _maille(MED_EN::medGeometryElement type=MED_EN::MED_NONE, size_t nelem=0)
00080     : geometricType(type),reverse(false),sortedNodeIDs(0),_ordre(0) { sommets.reserve(nelem); }
00081 
00082   _maille(const _maille& ma);
00083   void init() const { if ( sortedNodeIDs ) delete [] sortedNodeIDs; sortedNodeIDs = 0; }
00084   ~_maille() { init(); }
00085 
00086   int dimension() const // retourne la dimension de la maille
00087   { return geometricType/100; }
00088 
00089   int dimensionWithPoly() const // retourne la dimension de la maille
00090   { return geometricType >= MED_EN::MED_POLYGON ? dimension()-2 : dimension(); }
00091 
00092   const int* getSortedNodes() const; // creates if needed and return sortedNodeIDs
00093   bool operator < (const _maille& ma) const;
00094   MED_EN::medEntityMesh getEntity(const int meshDimension) const throw (MEDEXCEPTION);
00095   _link link(int i) const;
00096 
00097   //bool isMerged(int i) const { return sommets[i]->second.number < 0; }
00098   int nodeNum(int i) const { return abs( sommets[i]->second.number ); }
00099   int nodeID (int i) const { return sommets[i]->first; } // key in points map
00100 
00101   unsigned ordre() const { return abs( _ordre ); }
00102   bool isMerged() const { return _ordre < 0; }
00103   void setMergedOrdre(unsigned o) const { _ordre = -o; }
00104   void setOrdre(int o) const { _ordre = o; }
00105 
00106 private:
00107   mutable int _ordre; // l'ordre est fixé après insertion dans le set, et ne change ni l'état, ni l'ordre -> mutable
00108   _maille& operator=(const _maille& ma);
00109 };
00110 
00111 // ==============================================================================
00112 struct MEDMEM_EXPORT _mailleIteratorCompare // pour ordonner le set d'iterateurs sur mailles
00113 {
00114   // this operator is used for ordering mailles thinin a group, which happens when
00115   // right numbers are already given to _maille's, so we can use _maille::ordre
00116   // for comparison instead of a heavy _maille::operator <
00117   bool operator () (std::set<_maille>::iterator i1, std::set<_maille>::iterator i2)
00118   {
00119     //return *i1<*i2;
00120     return i1->ordre() < i2->ordre();
00121   }
00122 };
00123 
00124 // ==============================================================================
00125 struct MEDMEM_EXPORT _groupe
00126 {
00127   typedef std::set<_maille>::iterator            TMaille;
00128   typedef std::vector< TMaille >::const_iterator TMailleIter;
00129   std::string            nom;
00130   std::vector< TMaille > mailles; // iterateurs sur les mailles composant le groupe
00131   std::vector<int>       groupes; // indices des sous-groupes composant le groupe
00132   std::map<unsigned,int> relocMap; // map _maille::ordre() -> index in GROUP, built by getGroups()
00133   GROUP*                 medGroup;
00134 
00135   std::vector<std::string> refNames; /* names of groups referring this one;
00136                                         refNames is resized according to nb of references
00137                                         while reading a group (pile 1) and it is filled with
00138                                         names while reading long names (pile 27); each named
00139                                         reference is converted into a copy of the medGroup
00140                                         (issue 0021311)
00141                                       */
00142   const _maille& maille(int index) { return *mailles[index]; }
00143   bool empty() const { return mailles.empty() && groupes.empty(); }
00144 #ifdef WNT
00145   int  size()  const { return (mailles.size()>relocMap.size())?mailles.size():relocMap.size(); }
00146 #else
00147   int  size()  const { return std::max( mailles.size(), relocMap.size() ); }
00148 #endif
00149   _groupe():medGroup(0) {}
00150 };
00151 
00152 // ==============================================================================
00153 struct MEDMEM_EXPORT _fieldBase {
00154   // a field contains several subcomponents each referring to its own support and
00155   // having several named components
00156   // ----------------------------------------------------------------------------
00157   struct _sub_data // a subcomponent
00158   // --------------------------------
00159   {
00160     int                      _supp_id;    // group index within _intermediateMED::groupes
00161     std::vector<std::string> _comp_names; // component names
00162     std::vector<int>         _nb_gauss;   // nb values per element in a component
00163 
00164     void setData( int nb_comp, int supp_id )
00165     { _supp_id = supp_id - 1; _comp_names.resize(nb_comp); _nb_gauss.resize(nb_comp,1); }
00166     int nbComponents() const { return _comp_names.size(); }
00167     std::string & compName( int i_comp ) { return _comp_names[ i_comp ]; }
00168     bool isValidNbGauss() const { return *std::max_element( _nb_gauss.begin(), _nb_gauss.end() ) ==
00169                                     *std::min_element( _nb_gauss.begin(), _nb_gauss.end() ); }
00170 #ifdef WNT
00171     int nbGauss() const { return (1>_nb_gauss[0])?1:_nb_gauss[0]; }
00172 #else
00173     int nbGauss() const { return std::max( 1, _nb_gauss[0] ); }
00174 #endif
00175     bool hasGauss() const { return nbGauss() > 1; }
00176   };
00177   // ----------------------------------------------------------------------------
00178   std::vector< _sub_data > _sub;
00179   int                      _group_id; // group index within _intermediateMED::groupes
00180   // if _group_id == -1 then each subcomponent makes a separate MEDMEM::FIELD, else all subcomponents
00181   // are converted into one MEDMEM::FIELD. The latter is possible only if nb of components in all subs
00182   // is the same and supports of subcomponents do not overlap
00183   MED_EN::med_type_champ   _type;
00184   std::string              _name;
00185   std::string              _description;// field description
00186 
00187   _fieldBase( MED_EN::med_type_champ theType, int nb_sub )
00188     : _group_id(-1),_type(theType) { _sub.resize( nb_sub ); }
00189   virtual std::list<std::pair< FIELD_*, int> > getField(std::vector<_groupe>& groupes) const = 0;
00190   void getGroupIds( std::set<int> & ids, bool all ) const; // return ids of main and/or sub-groups
00191   bool hasCommonSupport() const { return _group_id >= 0; } // true if there is one support for all subs
00192   bool hasSameComponentsBySupport() const;
00193   virtual void dump(std::ostream&) const;
00194   virtual ~_fieldBase() {}
00195 };
00196 
00197 // ==============================================================================
00198 template< class T > class _field: public _fieldBase
00199 {
00200   std::vector< std::vector< T > > comp_values;
00201  public:
00202   _field< T > ( MED_EN::med_type_champ theType, int nb_sub, int total_nb_comp )
00203     : _fieldBase( theType, nb_sub ) { comp_values.reserve( total_nb_comp ); }
00204   std::vector< T >& addComponent( int nb_values ); // return a vector ready to fill in
00205   std::list<std::pair< FIELD_*, int> > getField(std::vector<_groupe>& groupes) const;
00206   virtual void dump(std::ostream&) const;
00207 };
00208 
00209 // ==============================================================================
00215 class MEDMEM_EXPORT _maillageByDimIterator
00216 {
00217 public:
00218   // if (convertPoly) then treat poly as 2d and 3d, else as 4d and 5d (=medGeometryElement/100)
00219   _maillageByDimIterator( const _intermediateMED & medi,
00220                           const int                dim=-1, // dim=-1 - for all dimensions
00221                           const bool               convertPoly = false )
00222   { myImed = & medi; init( dim, convertPoly ); }
00223 
00224   // if (convertPoly) then treat poly as 2d and 3d, else as 4d and 5d (=medGeometryElement/100)
00225   void init(const int  dim=-1, // dim=-1 - for all dimensions
00226             const bool convertPoly = false );
00227 
00229   const std::set<_maille > * nextType() {
00230     while ( myIt != myEnd )
00231       if ( !myIt->second.empty() && ( myDim < 0 || dim(false) == myDim ))
00232         return & (myIt++)->second;
00233       else
00234         ++myIt;
00235     return 0;
00236   }
00238   int dim(const bool last=true) const {
00239     iterator it = myIt;
00240     if ( last ) --it;
00241     return myConvertPoly ?
00242       it->second.begin()->dimensionWithPoly() :
00243       it->second.begin()->dimension();
00244   }
00246   MED_EN::medGeometryElement type() const { iterator it = myIt; return (--it)->first; }
00247 
00249   int sizeWithoutMerged() const {
00250     iterator it = myIt;
00251     removed::const_iterator tNb = nbRemovedByType->find( (--it)->first );
00252     return it->second.size() - ( tNb == nbRemovedByType->end() ? 0 : tNb->second );
00253   }
00254 private:
00255   typedef std::map<MED_EN::medGeometryElement, int >                removed;
00256   typedef std::map<MED_EN::medGeometryElement, std::set<_maille > > TMaillageByType;
00257   typedef TMaillageByType::const_iterator                                 iterator;
00258 
00259   const _intermediateMED* myImed;
00260   iterator myIt, myEnd;
00261   int myDim, myConvertPoly;
00262   const removed * nbRemovedByType;
00263 };
00264 
00265 // ==============================================================================
00276 struct MEDMEM_EXPORT _intermediateMED
00277 {
00278   typedef std::map<MED_EN::medGeometryElement, std::set<_maille > > TMaillageByType;
00279   typedef std::map<MED_EN::medGeometryElement, int >                TNbByType;
00280   typedef std::map< const _maille*, std::vector<int> >              TPolyherdalNbFaceNodes;
00281 
00282   TNbByType                nbRemovedByType; // nb mailles removed by merge
00283   std::vector<_groupe>     groupes;
00284   //std::vector<GROUP *>     medGroupes;
00285   std::map< int, _noeud >  points;
00286   std::list< _fieldBase* > fields;
00287   bool                     hasMixedCells; // true if there are groups with mixed entity types
00288   TPolyherdalNbFaceNodes   polyherdalNbFaceNodes; // nb of nodes in faces for each polyhedron
00289 
00290   inline _groupe::TMaille insert(const _maille& ma);
00291 
00292   int getMeshDimension() const;
00293   void mergeNodesAndElements(double tolerance); // optionally merge nodes and elements
00294   CONNECTIVITY * getConnectivity(); // creates MED connectivity from the intermediate structure
00295   COORDINATE * getCoordinate(const string & coordinateSystem="CARTESIAN"); // makes MED coordinate
00296 //   void getFamilies(std::vector<FAMILY *> & _famCell, std::vector<FAMILY *> & _famFace,
00297 //                    std::vector<FAMILY *> & _famEdge, std::vector<FAMILY *> & _famNode,
00298 //                    MESH * _ptrMesh);
00299   void getGroups(std::vector<GROUP *> & _groupCell, std::vector<GROUP *> & _groupFace,
00300                  std::vector<GROUP *> & _groupEdge, std::vector<GROUP *> & _groupNode,
00301                  MESH * _ptrMesh);
00302   //GROUP * getGroup( int i );
00303 
00304   void getFields(std::list< FIELD_* >& fields);
00305 
00306   // used by previous functions to renumber points & mesh.
00307   bool myGroupsTreated;
00308   void treatGroupes(); // detect groupes of mixed dimension
00309   void numerotationMaillage();
00310   bool numerotationPoints(); // return true if renumeration done
00311   int nbMerged(int geoType) const; 
00312 
00313   _intermediateMED()
00314   { myNodesNumerated = myMaillesNumerated = myGroupsTreated = false; currentTypeMailles = 0; }
00315   ~_intermediateMED();
00316 
00317 private:
00318 
00319   bool myNodesNumerated, myMaillesNumerated;
00320   // mailles groupped by geom type; use insert() for filling in and
00321   // _maillageByDimIterator for exploring it
00322   //std::set<_maille> maillage;
00323   TMaillageByType              maillageByType;
00324   TMaillageByType::value_type* currentTypeMailles; // for fast insertion
00325   friend class _maillageByDimIterator;
00326 };
00327 //-----------------------------------------------------------------------
00328 _groupe::TMaille _intermediateMED::insert(const _maille& ma)
00329 {
00330   if ( !currentTypeMailles || currentTypeMailles->first != ma.geometricType )
00331     currentTypeMailles = & *maillageByType.insert
00332       ( make_pair( ma.geometricType, std::set<_maille >())).first;
00333 
00334   _groupe::TMaille res = currentTypeMailles->second.insert( ma ).first;
00335 
00336   ((_maille&)ma).init(); // this method was added for the sake of this call which is needed to
00337   // remove comparison key (sortedNodeIDs) from a temporary _maille ma
00338 
00339   return res;
00340 }
00341 
00342 // ==============================================================================
00343 
00344 std::ostream& operator << (std::ostream& , const _maille& );
00345 std::ostream& operator << (std::ostream& , const _groupe& );
00346 std::ostream& operator << (std::ostream& , const _noeud& );
00347 std::ostream& operator << (std::ostream& , const _intermediateMED& );
00348 std::ostream& operator << (std::ostream& , const _fieldBase* );
00349 
00350 // ===========================================================
00351 //                 field template implementation           //
00352 // ===========================================================
00353 
00354 template <class T>
00355   std::vector< T >& _field< T >::addComponent( int nb_values )
00356 {
00357   comp_values.push_back( std::vector< T >() );
00358   std::vector< T >& res = comp_values.back();
00359   res.resize( nb_values );
00360   return res;
00361 }
00362 
00363 //=======================================================================
00364 //function : getField
00365 //purpose  : return list of pairs< field, supporting_group_id >
00366 //=======================================================================
00367 
00368 template <class T>
00369 std::list<std::pair< FIELD_*, int> > _field< T >::getField(std::vector<_groupe> & groupes) const
00370 {
00371   const char* LOC = "_field< T >::getField()";
00372 
00373   std::list<std::pair< FIELD_*, int> > res;
00374 
00375   // gauss array data
00376   int nbtypegeo = 0;
00377   vector<int> nbelgeoc(2,0), nbgaussgeo(2,0);
00378 
00379   int i_comp_tot = 0, nb_fields = 0;
00380   std::set<int> supp_id_set; // to create a new field when support repeats if hasCommonSupport()
00381   std::vector< _sub_data >::const_iterator sub_data, sub_end = _sub.end();
00382 
00383   _groupe*  grp = 0;
00384   GROUP* medGrp = 0;
00385   if ( hasCommonSupport() ) // several subs are combined into one field
00386   {
00387     grp    = & groupes[ _group_id ];
00388     medGrp = grp->medGroup;
00389     if ( !grp || grp->empty() || !medGrp || !medGrp->getNumberOfTypes())
00390       return res;
00391 
00392     // Make gauss array data
00393     nbtypegeo = medGrp->getNumberOfTypes();
00394     nbelgeoc  .resize( nbtypegeo + 1, 0 );
00395     nbgaussgeo.resize( nbtypegeo + 1, 0 );
00396     const int *                nbElemByType = medGrp->getNumberOfElements();
00397     const MED_EN::medGeometryElement* types = medGrp->getTypes();
00398     for (int iType = 0; iType < nbtypegeo; ++iType) {
00399       // nb elem by type
00400       nbelgeoc  [ iType+1 ] = nbelgeoc[ iType ] + nbElemByType[ iType ];
00401       // nb gauss by type; find a sub for a geo type
00402       for ( sub_data = _sub.begin(); sub_data != sub_end; ++sub_data ) {
00403         _groupe & sub_grp = groupes[ sub_data->_supp_id ];
00404         if ( !sub_grp.empty() && sub_grp.mailles[0]->geometricType == types[ iType ])
00405           break;
00406       }
00407       ASSERT_MED( sub_data != sub_end );
00408       nbgaussgeo[ iType+1 ] = sub_data->nbGauss();
00409     }
00410   }
00411   typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array TArrayNoGauss;
00412   typedef typename MEDMEM_ArrayInterface<T,FullInterlace,Gauss>::Array   TArrayGauss;
00413   FIELD< T, FullInterlace > * f = 0;
00414   TArrayNoGauss * arrayNoGauss = 0;
00415   TArrayGauss   * arrayGauss = 0;
00416 
00417   // loop on subs of this field
00418   int i_sub = 1;
00419   for ( sub_data = _sub.begin(); sub_data != sub_end; ++sub_data, ++i_sub )
00420   {
00421     // nb values in a field
00422     if ( !hasCommonSupport() ) {
00423       grp    = & groupes[ sub_data->_supp_id ];
00424       medGrp = grp->medGroup;
00425     }
00426     int nb_val = grp->size();
00427 
00428     // check validity of a sub_data
00429     bool validSub = true;
00430     if ( !nb_val ) {
00431       INFOS_MED("Skip field <" << _name << ">: invalid supporting group "
00432             << (hasCommonSupport() ? _group_id : sub_data->_supp_id )
00433             << " of " << i_sub << "-th subcomponent" );
00434       validSub = false;
00435     }
00436     if ( !sub_data->isValidNbGauss() ) {
00437       INFOS_MED("Skip field <" << _name << ">: different nb of gauss points in components ");
00438       validSub = false;
00439     }
00440     if ( !validSub ) {
00441       if ( hasCommonSupport() ) {
00442         if ( !res.empty() ) {
00443           if(f)
00444             f->removeReference();
00445           res.clear();
00446         }
00447         return res;
00448       }
00449       i_comp_tot += sub_data->nbComponents();
00450       continue;
00451     }
00452 
00453     // Create a field
00454 
00455     if ( !f || !hasCommonSupport() || !supp_id_set.insert( sub_data->_supp_id ).second )
00456     {
00457       ++nb_fields;
00458       supp_id_set.clear();
00459       arrayNoGauss = 0;
00460       arrayGauss = 0;
00461 
00462       f = new FIELD< T, FullInterlace >();
00463 
00464       f->setNumberOfComponents( sub_data->nbComponents() );
00465       f->setComponentsNames( & sub_data->_comp_names[ 0 ] );
00466       f->setNumberOfValues ( nb_val );
00467       f->setName( _name );
00468       f->setDescription( _description );
00469       vector<string> str( sub_data->nbComponents() );
00470       f->setComponentsDescriptions( &str[0] );
00471       f->setMEDComponentsUnits( &str[0] );
00472       if ( !hasCommonSupport() && nb_fields > 1 )
00473       {
00474         f->setName( MEDMEM::STRING(_name) << "_Sub_" << nb_fields );
00475         INFOS_MED("Warning: field |" <<_name<<"| is incompatible with MED format (has "
00476                   "sub-fields of different nature), so we map its sub-field #"<< nb_fields <<
00477                   " into a separate field |"<<f->getName() << "|");
00478       }
00479       res.push_back( make_pair( f , hasCommonSupport() ? _group_id : sub_data->_supp_id ));
00480       MESSAGE_MED(" MAKE " << nb_fields << "-th field <" << _name << "> on group_id " << _group_id );
00481 
00482       // make an array
00483       if ( !sub_data->hasGauss() ) {
00484         arrayNoGauss = new TArrayNoGauss( sub_data->nbComponents(), nb_val );
00485         f->setArray( arrayNoGauss );
00486       }
00487       else {
00488         if ( !hasCommonSupport() ) {
00489           nbtypegeo = 1;
00490           nbelgeoc  [1] = nb_val;
00491           nbgaussgeo[1] = sub_data->nbGauss();
00492         }
00493         arrayGauss = new TArrayGauss(sub_data->nbComponents(), nb_val,
00494                                      nbtypegeo, & nbelgeoc[0], & nbgaussgeo[0]);
00495         f->setArray( arrayGauss );
00496 
00497         // PAL11040 "GIBI driver for Castem fields with Gauss point values"
00498         const MED_EN::medGeometryElement* types = medGrp->getTypes();
00499         for (int iGeom = 0; iGeom < nbtypegeo; ++iGeom) {
00500           ostringstream name;
00501           name << "Gauss_" << nbgaussgeo[iGeom+1] << "points_on" << types[iGeom] << "geom";
00502           GAUSS_LOCALIZATION_* loc = GAUSS_LOCALIZATION_::makeDefaultLocalization
00503             (name.str(), types[iGeom], nbgaussgeo[iGeom+1]);
00504           f->setGaussLocalization( types[iGeom], loc );
00505         }
00506       }
00507     }
00508 
00509     // Set values
00510 
00511     // get nb elements in a group
00512     _groupe & sub_grp = groupes[ sub_data->_supp_id ];
00513     int nb_supp_elems = sub_grp.mailles.size();
00514     int nb_gauss      = sub_data->nbGauss();
00515     MESSAGE_MED("insert sub data, group_id: " << sub_data->_supp_id <<
00516             ", nb values: "               << comp_values[ i_comp_tot ].size() <<
00517             ", relocMap size: "           << sub_grp.relocMap.size() <<
00518             ", nb mailles: "              << nb_supp_elems);
00519 
00520 #ifdef CASTEM_FULL_INTERLACE
00521     const int gauss_step = 1;
00522     const int elem_step = nb_gauss;
00523 #else
00524     const int gauss_step = nb_supp_elems;
00525     const int elem_step = 1;
00526 #endif
00527     int i; // elem index
00528     // loop on components of a sub
00529     for ( int i_comp = 1; i_comp <= sub_data->nbComponents(); ++i_comp )
00530     {
00531       // store values
00532       const std::vector< T > & values = comp_values[ i_comp_tot++ ];
00533       bool oneValue = ( values.size() == 1 );
00534       ASSERT_MED( oneValue || (int)values.size() == nb_supp_elems * nb_gauss );
00535       for ( int k = 0; k < nb_supp_elems; ++k )
00536       {
00537         const T& val = oneValue ? values[ 0 ] : values[ k * elem_step ];
00538         const _maille& ma = sub_grp.maille( k );
00539         if ( medGrp->isOnAllElements() ) {
00540           i = ma.ordre();
00541         }
00542         else {
00543           std::map<unsigned,int>::const_iterator ordre_i = grp->relocMap.find( ma.ordre() );
00544           if ( ordre_i == grp->relocMap.end() )
00545             throw MEDEXCEPTION (LOCALIZED(STRING(LOC) << ", cant find elem index. "
00546                                           << k << "-th elem: " << ma));
00547           i = ordre_i->second;
00548         }
00549         if ( arrayNoGauss ) {
00550           arrayNoGauss->setIJ( i, i_comp, val );
00551         }
00552         else {
00553           const T* pVal = & val;
00554           for ( int iGauss = 1; iGauss <= nb_gauss; ++iGauss, pVal += gauss_step )
00555             arrayGauss->setIJK( i, i_comp, iGauss, *pVal);
00556         }
00557       }
00558     }
00559   } // loop on subs of the field
00560 
00561   return res;
00562 }
00563 
00564 
00565 // ==============================================================================
00566 template <class T> void _field< T >::dump(std::ostream& os) const
00567 // ==============================================================================
00568 {
00569   _fieldBase::dump(os);
00570   os << endl;
00571   for ( int i = 0 ; i < (int)comp_values.size(); ++i )
00572   {
00573     os << "    " << i+1 << "-th component, nb values: " << comp_values[ i ].size() << endl;
00574   }
00575 }
00576 
00577 } // namespace MEDMEM
00578 
00579 #endif /* DRIVERTOOLS_HXX */