Back to index

salome-med  6.5.0
MEDMEM_Field.cxx
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 #include "MEDMEM_Field.hxx"
00024 #include "MEDMEM_Mesh.hxx"
00025 
00026 using namespace std;
00027 using namespace MEDMEM;
00028 using namespace MED_EN;
00029 
00030 // ---------------------------------
00031 // FIELD_ : Constructors
00032 // ---------------------------------
00033 FIELD_::FIELD_(): 
00034   _isRead(false),
00035   _isMinMax(false),
00036   _name(""), _description(""), _support((SUPPORT *)NULL),
00037   _numberOfComponents(0), _numberOfValues(0),
00038   _iterationNumber(-1),_time(0.0),_orderNumber(-1),
00039   _valueType(MED_EN::MED_UNDEFINED_TYPE),
00040   _interlacingType(MED_EN::MED_UNDEFINED_INTERLACE)
00041 {
00042   MESSAGE_MED("Constructeur FIELD_ sans parametre");
00043 }
00044 
00045 FIELD_::FIELD_(const SUPPORT * Support, const int NumberOfComponents):
00046   _isRead(false),
00047   _isMinMax(false),
00048   _name(""), _description(""), _support(Support),
00049   _numberOfComponents(NumberOfComponents),
00050   _iterationNumber(-1),_time(0.0),_orderNumber(-1),
00051   _valueType(MED_EN::MED_UNDEFINED_TYPE),
00052   _interlacingType(MED_EN::MED_UNDEFINED_INTERLACE)
00053 {
00054   MESSAGE_MED("FIELD_(const SUPPORT * Support, const int NumberOfComponents)");
00055 
00056   _numberOfValues = Support->getNumberOfElements(MED_ALL_ELEMENTS);
00057   _componentsTypes.resize(NumberOfComponents);
00058   _componentsNames.resize(NumberOfComponents);
00059   _componentsDescriptions.resize(NumberOfComponents);
00060   _componentsUnits.resize(NumberOfComponents);
00061   _MEDComponentsUnits.resize(NumberOfComponents);
00062   for(int i=0;i<NumberOfComponents;i++) {
00063     _componentsTypes[i] = 0 ;
00064   }
00065   if(_support)
00066     _support->addReference();
00067 }
00068 
00069 FIELD_& FIELD_::operator=(const FIELD_ &m) {
00070 
00071   if ( this == &m) return *this;
00072 
00073   _isRead             = m._isRead ;
00074   _isMinMax           = m._isMinMax ;
00075   _name               = m._name;
00076   _description        = m._description;
00077   if(_support!=m._support)
00078     {
00079       if(_support)
00080         _support->removeReference();
00081       _support=m._support;   //Cf Opérateur de recopie du Support?
00082       if(_support)
00083         _support->addReference();
00084     }
00085   _numberOfComponents = m._numberOfComponents;
00086   _numberOfValues     = m._numberOfValues;
00087 
00088   _componentsTypes.resize(_numberOfComponents);
00089   for (int i=0; i<m._numberOfComponents; i++)
00090     {_componentsTypes[i]=m._componentsTypes[i];}
00091 
00092   _componentsNames.resize(_numberOfComponents);
00093   _componentsDescriptions.resize(_numberOfComponents);
00094   _componentsUnits.resize(_numberOfComponents);
00095   _MEDComponentsUnits.resize(_numberOfComponents);
00096 
00097   for (int i=0; i<m._numberOfComponents; i++)
00098     {_componentsNames[i]=m._componentsNames[i];}
00099   for (int i=0; i<m._numberOfComponents; i++)
00100     {_componentsDescriptions[i]=m._componentsDescriptions[i];}
00101   for (int i=0; i<m._numberOfComponents; i++)
00102     {_componentsUnits[i] = m._componentsUnits[i];}
00103   // L'operateur '=' est defini dans la classe UNIT
00104   for (int i=0; i<m._numberOfComponents; i++)
00105     {_MEDComponentsUnits[i] = m._MEDComponentsUnits[i];}
00106 
00107   _iterationNumber = m._iterationNumber;
00108   _time            = m._time;
00109   _orderNumber     = m._orderNumber;
00110 
00111   // _valueType et _interlacingType doivent uniquement être recopiés 
00112   // par l'opérateur de recopie de FIELD<T,...>
00113 
00114   //_drivers = m._drivers ; // PG : Well, same driver, what about m destructor !
00115 
00116   return *this;
00117 }
00118 
00119 FIELD_::FIELD_(const FIELD_ &m)
00120 {
00121   _isRead = m._isRead ;
00122   _isMinMax = m._isMinMax ;
00123   _name = m._name;
00124   _description = m._description;
00125   _support = m._support;
00126   if(_support)
00127     _support->addReference();
00128   _numberOfComponents = m._numberOfComponents;
00129   _numberOfValues = m._numberOfValues;
00130   copyGlobalInfo(m);
00131   //_valueType = m._valueType;
00132   // _valueType et _interlacingType doivent uniquement être recopiés 
00133   // par l'opérateur de recopie de FIELD<T,...>
00134   //_drivers = m._drivers ; // PG : Well, same driver, what about m destructor !
00135 }
00136 
00137 FIELD_::~FIELD_()
00138 {
00139   MESSAGE_MED("~FIELD_()");
00140 
00141   MESSAGE_MED("In this object FIELD_ there is(are) " << _drivers.size() << " driver(s)");
00142 
00143   for (unsigned int index=0; index < _drivers.size(); index++ )
00144     {
00145       SCRUTE_MED(_drivers[index]);
00146       if ( _drivers[index] != NULL) delete _drivers[index];
00147     }
00148   _drivers.clear();
00149   if(_support)
00150     _support->removeReference();
00151   _support=0;
00152 }
00153 
00159 FIELD<double>* FIELD_::_getFieldSize(const SUPPORT *subSupport) const
00160 {
00161   FIELD<double>* p_field_size;
00162 
00163   const SUPPORT* support = subSupport;
00164   if ( !support )
00165     {
00166       if ( getSupport()->getEntity() == MED_NODE )
00167         support = getSupport()->getMesh()->getSupportOnAll( MED_CELL );
00168       else
00169         support = getSupport();
00170       support->addReference();
00171     }
00172   const GMESH* mesh = getSupport()->getMesh();
00173   switch (getSupport()->getEntity())
00174     {
00175     case MED_CELL :
00176       switch (mesh->getMeshDimension() ) 
00177         {
00178         case 1:
00179           p_field_size=mesh->getLength( support );
00180           break;
00181         case 2:
00182           p_field_size=mesh->getArea( support );
00183           break;
00184         case 3:
00185           p_field_size=mesh->getVolume( support );
00186           break;
00187         }
00188       break;
00189 
00190     case MED_FACE :
00191       p_field_size=mesh->getArea( support );
00192       break;
00193 
00194     case MED_EDGE :
00195       p_field_size=mesh->getLength( support );
00196       break;
00197     case MED_NODE : // issue 0020120: [CEA 206] normL2 on NODE field
00198       {
00199         switch (mesh->getMeshDimension() ) 
00200           {
00201           case 1:
00202             p_field_size=mesh->getLength( support );
00203             break;
00204           case 2:
00205             p_field_size=mesh->getArea( support );
00206             break;
00207           case 3:
00208             p_field_size=mesh->getVolume( support );
00209             break;
00210           }
00211         break;
00212       }
00213     }
00214   if(!subSupport && support)
00215     support->removeReference();
00216   return p_field_size;
00217 }
00218 
00219 
00225 void FIELD_::_checkNormCompatibility(const FIELD<double>* support_volume,
00226                                      const bool           nodalAllowed) const throw (MEDEXCEPTION)
00227 {
00228   string diagnosis;
00229 
00230   if( getSupport()->getEntity() == MED_NODE)
00231     {
00232       if ( !nodalAllowed )
00233         {
00234           diagnosis="Cannot compute sobolev norm on a field "+getName()+
00235             " : it has support on nodes!";
00236           throw MEDEXCEPTION(diagnosis.c_str());
00237         }
00238       if ( !getSupport()->getMesh() )
00239         {
00240           diagnosis="Cannot compute Lnorm of nodal field "+getName()+
00241             " : it's support has no mesh reference";
00242           throw MEDEXCEPTION(diagnosis.c_str());
00243         }
00244       if ( !getSupport()->getMesh()->getIsAGrid() &&
00245            !( (const MESH*)getSupport()->getMesh() )->existConnectivity(MED_NODAL,MED_CELL) )
00246         {
00247           diagnosis="Cannot compute Lnorm of nodal field"+getName()+
00248             " : it's supporting mesh has no nodal connectivity data";
00249           throw MEDEXCEPTION(diagnosis.c_str());
00250         }
00251     }
00252 
00253   if (getNumberOfValues()*getNumberOfComponents()<= 0) // Size of array has to be strictly positive
00254     {
00255       diagnosis="Cannot compute the norm of "+getName()+
00256         " : it size is non positive!";
00257       throw MEDEXCEPTION(diagnosis.c_str());
00258     }
00259 
00260   if( getSupport()->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS) != getNumberOfValues() ) {
00261     diagnosis="Cannot compute Lnorm of "+getName()+
00262       " : the suppors size not corresponded to number of elements!";
00263     throw MEDEXCEPTION(diagnosis.c_str());
00264   }
00265 
00266   if (getGaussPresence() ) {
00267     diagnosis="Cannot compute Lnorm of "+getName()+
00268       " : Gauss numbers greater than one are not yet implemented!";
00269     throw MEDEXCEPTION(diagnosis.c_str());
00270   }
00271 
00272   if(support_volume) // if the user has supplied the volume
00273     {
00274       if ( getSupport()->getEntity() == MED_NODE )
00275         {
00276           if (support_volume->getNumberOfValues()!=
00277               getSupport()->getMesh()->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS))
00278             {
00279               diagnosis="Cannot compute Lnorm of nodal field "+getName()+
00280                 " : the volume furnished has wrong number of values";
00281               throw MEDEXCEPTION(diagnosis.c_str());
00282             }
00283           return;
00284         }
00285       if(support_volume->getSupport()!=getSupport())
00286         {
00287           diagnosis="Cannot compute Lnorm of "+getName()+
00288             " : the volume furnished has not the same support!";
00289           throw MEDEXCEPTION(diagnosis.c_str());
00290         }
00291       if(support_volume->getNumberOfValues()!=getNumberOfValues())
00292         {
00293           diagnosis="Cannot compute Lnorm of "+getName()+
00294             " : the volume furnished has not the same number of values!";
00295           throw MEDEXCEPTION(diagnosis.c_str());
00296         }
00297       if( getSupport()->getNumberOfElements() != 
00298           support_volume->getSupport()->getNumberOfElements() ) {
00299         diagnosis="Cannot compute Lnorm of "+getName()+
00300           " : the supports have not the same number of elements!";
00301         throw MEDEXCEPTION(diagnosis.c_str());
00302       }
00303     }
00304 
00305 }
00306 
00312 void FIELD_::_checkFieldCompatibility(const FIELD_& m, const FIELD_& n, bool checkUnit) throw (MEDEXCEPTION)
00313 {
00314     string diagnosis;
00315 
00316     // check-up, fill diagnosis if some incompatibility is found.
00317 
00318     // Ne pas vérifier l'entrelacement
00319     // Le compilo s'en occupe Rmq from EF
00320 
00321     if(m._support != n._support)
00322       {
00323         if(!(*m._support==*n._support))
00324           diagnosis+="They don't have the same support!";
00325       }
00326     else if(m._numberOfComponents != n._numberOfComponents)
00327       diagnosis+="They don't have the same number of components!";
00328     else if (m._valueType != n._valueType)
00329       diagnosis+="They don't have the same type!";
00330     else if(m._numberOfValues != n._numberOfValues)
00331       diagnosis+="They don't have the same number of values!";
00332     else
00333       {
00334         if(checkUnit)
00335           {
00336             for(int i=0; i<m._numberOfComponents; i++)
00337               {
00338                 // Not yet implemented   
00339                 //          if(m._componentsTypes[i] != n._componentsTypes[i])
00340                 //          {
00341                 //              diagnosis+="Components don't have the same types!";
00342                 //              break;
00343                 //          }
00344                 if(m._MEDComponentsUnits[i] != n._MEDComponentsUnits[i])
00345                   {
00346                     diagnosis+="Components don't have the same units!";
00347                     break;
00348                   }
00349               }
00350           }
00351       }
00352 
00353     if(diagnosis.size()) // if fields are not compatible : complete diagnosis and throw exception
00354     {
00355         diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
00356                  + n._name + " are not compatible.\n" + diagnosis;
00357         throw MEDEXCEPTION(diagnosis.c_str());
00358     }
00359 
00360     if( m.getNumberOfValues()<=0 || m.getNumberOfComponents()<=0) // check up the size is strictly positive
00361     {
00362         diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
00363                  + n._name + " are empty! (size<=0).\n";
00364         throw MEDEXCEPTION(diagnosis.c_str());
00365     }
00366 
00367 }
00368 
00369 void FIELD_::_deepCheckFieldCompatibility(const FIELD_& m, const FIELD_& n , bool checkUnit ) throw (MEDEXCEPTION)
00370 {
00371   string diagnosis;
00372 
00373   // check-up, fill diagnosis if some incompatibility is found.
00374 
00375   // Ne pas vérifier l'entrelacement
00376   // Le compilo s'en occupe Rmq from EF
00377 
00378     if(m._support != n._support)
00379       {
00380         if(!(m._support->deepCompare(*n._support)))
00381           diagnosis+="They don't have the same support!";
00382       }
00383     else if (m._valueType != n._valueType)
00384       diagnosis+="They don't have the same type!";
00385     else if(m._numberOfComponents != n._numberOfComponents)
00386       diagnosis+="They don't have the same number of components!";
00387     else if(m._numberOfValues != n._numberOfValues)
00388       diagnosis+="They don't have the same number of values!";
00389     else
00390       {
00391         if(checkUnit)
00392           {
00393             for(int i=0; i<m._numberOfComponents; i++)
00394               {
00395                 if(m._MEDComponentsUnits[i] != n._MEDComponentsUnits[i])
00396                   {
00397                     diagnosis+="Components don't have the same units!";
00398                     break;
00399                   }
00400               }
00401           }
00402       }
00403 
00404     if(diagnosis.size()) // if fields are not compatible : complete diagnosis and throw exception
00405     {
00406         diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
00407                  + n._name + " are not compatible.\n" + diagnosis;
00408         throw MEDEXCEPTION(diagnosis.c_str());
00409     }
00410 
00411     if( m.getNumberOfValues()<=0 || m.getNumberOfComponents()<=0) // check up the size is strictly positive
00412     {
00413         diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
00414                  + n._name + " are empty! (size<=0).\n";
00415         throw MEDEXCEPTION(diagnosis.c_str());
00416     }
00417 } 
00418 
00419 
00420 void     FIELD_::rmDriver      (int index)
00421 {
00422   MESSAGE_MED("void FIELD_::rmDriver(int index) : removing the driver " << index);
00423 }
00424 
00425 int      FIELD_::addDriver     (driverTypes driverType, 
00426                                 const string & fileName,
00427                                 const string & driverFieldName,
00428                                 MED_EN::med_mode_acces access)
00429 {
00430   MESSAGE_MED("int FIELD_::addDriver(driverTypes driverType, const string & fileName, const string & driverFieldName) : adding the driver " << driverType << " fileName = " << fileName.c_str() << " driverFieldName = " << driverFieldName.c_str());
00431   return 0;
00432 }
00433 
00434 int      FIELD_::addDriver     (GENDRIVER & driver)
00435 {
00436   MESSAGE_MED("int FIELD_::addDriver(GENDRIVER & driver) : driver " << driver);
00437   return 0;
00438 }
00439 
00440 void     FIELD_::openAppend    ( void )                               {}
00441 void     FIELD_::write         (const GENDRIVER &,
00442                                 MED_EN::med_mode_acces)               {}
00443 void     FIELD_::write         (driverTypes driverType,
00444                                 const std::string & fileName,
00445                                 MED_EN::med_mode_acces medMode)       {}
00446 void     FIELD_::writeAppend   (const GENDRIVER &)                    {}
00447 void     FIELD_::write         (int ) {}
00448 void     FIELD_::writeAppend   (int , const string & ) {}
00449 void     FIELD_::read          (int )                                 {}
00450 void     FIELD_::read          (const GENDRIVER &)                    {}
00451 void     FIELD_::read          (driverTypes driverType, const std::string & fileName){}
00452 void     FIELD_::copyGlobalInfo(const FIELD_& m)
00453 {  
00454 
00455   _componentsTypes.resize(_numberOfComponents);
00456   _componentsNames.resize(_numberOfComponents);
00457   _componentsDescriptions.resize(_numberOfComponents);
00458   _componentsUnits.resize(_numberOfComponents);
00459   _MEDComponentsUnits.resize(_numberOfComponents);
00460 
00461   for (int i=0; i<m._numberOfComponents; i++)
00462     {_componentsTypes[i]=m._componentsTypes[i];}
00463 
00464   for (int i=0; i<m._numberOfComponents; i++)
00465     _componentsNames[i]=m._componentsNames[i];
00466   for (int i=0; i<m._numberOfComponents; i++)
00467     _componentsDescriptions[i]=m._componentsDescriptions[i];
00468 
00469   for (int i=0; i<m._numberOfComponents; i++)
00470     _componentsUnits[i] = m._componentsUnits[i];
00471   
00472   // L'operateur '=' est defini dans la classe UNIT
00473   for (int i=0; i<m._numberOfComponents; i++)
00474     {_MEDComponentsUnits[i] = m._MEDComponentsUnits[i];}
00475 
00476   _iterationNumber = m._iterationNumber;
00477   _time = m._time;
00478   _orderNumber = m._orderNumber;
00479 }