Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/med.git] / src / MEDMEM / MEDMEM_Field.cxx
index e570337d52cd5b4b20b568e557ec50ba8bb23540..b136c831cbfcca67cafeffcd04a4eadce2466d4e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "MEDMEM_Field.hxx"
 #include "MEDMEM_Mesh.hxx"
 
@@ -34,11 +35,6 @@ FIELD_::FIELD_():
   _isMinMax(false),
   _name(""), _description(""), _support((SUPPORT *)NULL),
   _numberOfComponents(0), _numberOfValues(0),
-  //_componentsTypes((int *)NULL),
-  //_componentsNames((string *)NULL), 
-  //_componentsDescriptions((string *)NULL),
-  //_componentsUnits((UNIT*)NULL),
-  //_MEDComponentsUnits((string *)NULL),
   _iterationNumber(-1),_time(0.0),_orderNumber(-1),
   _valueType(MED_EN::MED_UNDEFINED_TYPE),
   _interlacingType(MED_EN::MED_UNDEFINED_INTERLACE)
@@ -58,11 +54,6 @@ FIELD_::FIELD_(const SUPPORT * Support, const int NumberOfComponents):
   MESSAGE_MED("FIELD_(const SUPPORT * Support, const int NumberOfComponents)");
 
   _numberOfValues = Support->getNumberOfElements(MED_ALL_ELEMENTS);
-  //_componentsTypes = new int[NumberOfComponents] ;
-  //_componentsNames = new string[NumberOfComponents];
-  //_componentsDescriptions = new string[NumberOfComponents];
-  //_componentsUnits = new UNIT[NumberOfComponents];
-  //_MEDComponentsUnits = new string[NumberOfComponents];
   _componentsTypes.resize(NumberOfComponents);
   _componentsNames.resize(NumberOfComponents);
   _componentsDescriptions.resize(NumberOfComponents);
@@ -83,16 +74,17 @@ FIELD_& FIELD_::operator=(const FIELD_ &m) {
   _isMinMax           = m._isMinMax ;
   _name               = m._name;
   _description        = m._description;
-  _support            = m._support;   //Cf OpĂ©rateur de recopie du Support?
+  if(_support!=m._support)
+    {
+      if(_support)
+        _support->removeReference();
+      _support=m._support;   //Cf OpĂ©rateur de recopie du Support?
+      if(_support)
+        _support->addReference();
+    }
   _numberOfComponents = m._numberOfComponents;
   _numberOfValues     = m._numberOfValues;
 
-  //if (m._componentsTypes != NULL) {
-  //  _componentsTypes = new int[m._numberOfComponents] ;
-  //  memcpy(_componentsTypes,m._componentsTypes,sizeof(int)*m._numberOfComponents);
-  //} else 
-  //  _componentsTypes = (int *) NULL;
-
   _componentsTypes.resize(_numberOfComponents);
   for (int i=0; i<m._numberOfComponents; i++)
     {_componentsTypes[i]=m._componentsTypes[i];}
@@ -102,17 +94,13 @@ FIELD_& FIELD_::operator=(const FIELD_ &m) {
   _componentsUnits.resize(_numberOfComponents);
   _MEDComponentsUnits.resize(_numberOfComponents);
 
-  //_componentsNames = new string[m._numberOfComponents];
   for (int i=0; i<m._numberOfComponents; i++)
     {_componentsNames[i]=m._componentsNames[i];}
-  //_componentsDescriptions = new string[m._numberOfComponents];
   for (int i=0; i<m._numberOfComponents; i++)
     {_componentsDescriptions[i]=m._componentsDescriptions[i];}
-  //_componentsUnits = new UNIT[m._numberOfComponents];
   for (int i=0; i<m._numberOfComponents; i++)
     {_componentsUnits[i] = m._componentsUnits[i];}
   // L'operateur '=' est defini dans la classe UNIT
-  //_MEDComponentsUnits = new string[m._numberOfComponents];
   for (int i=0; i<m._numberOfComponents; i++)
     {_MEDComponentsUnits[i] = m._MEDComponentsUnits[i];}
 
@@ -149,25 +137,6 @@ FIELD_::FIELD_(const FIELD_ &m)
 FIELD_::~FIELD_()
 {
   MESSAGE_MED("~FIELD_()");
-  //if ( _componentsTypes !=NULL)
-  //  delete[] _componentsTypes ;
-  //if ( _componentsNames !=NULL)
-  //  delete[] _componentsNames ;
-  //if ( _componentsDescriptions !=NULL)
-  //  delete[] _componentsDescriptions ;
-  //if ( _componentsUnits !=NULL)
-  //  delete[] _componentsUnits ;
-  //if ( _MEDComponentsUnits !=NULL)
-  //  delete[] _MEDComponentsUnits ;
-  // delete driver
-//   vector<GENDRIVER *>::const_iterator it ;
-//   SCRUTE_MED(_drivers.size());
-//   int i=0;
-//   for (it=_drivers.begin();it!=_drivers.end();it++) {
-//     i++;
-//     SCRUTE_MED(i);
-//     delete (*it) ;
-
 
   MESSAGE_MED("In this object FIELD_ there is(are) " << _drivers.size() << " driver(s)");
 
@@ -176,46 +145,75 @@ FIELD_::~FIELD_()
       SCRUTE_MED(_drivers[index]);
       if ( _drivers[index] != NULL) delete _drivers[index];
     }
-  //CCAR: if _support is a SUPPORTClient remove reference
-  // This is correct but it's highlighting other problem
- // if(_support)
//   _support->removeReference();
+  _drivers.clear();
+  if(_support)
+    _support->removeReference();
 _support=0;
 }
 
-/*! 
+/*!
   \if developper
   PROVISOIRE : retourne des volumes, surfaces ou longueurs suivant les cas
   \endif
 */
-FIELD<double>* FIELD_::_getFieldSize() const
+FIELD<double>* FIELD_::_getFieldSize(const SUPPORT *subSupport) const
 {
-    FIELD<double>* p_field_size;
-    switch (getSupport()->getEntity())
+  FIELD<double>* p_field_size;
+
+  const SUPPORT* support = subSupport;
+  if ( !support )
+    {
+      if ( getSupport()->getEntity() == MED_NODE )
+        support = getSupport()->getMesh()->getSupportOnAll( MED_CELL );
+      else
+        support = getSupport();
+      support->addReference();
+    }
+  const GMESH* mesh = getSupport()->getMesh();
+  switch (getSupport()->getEntity())
     {
-       case MED_CELL :
-           switch (getSupport()->getMesh()->getMeshDimension() ) 
-           {
-               case 1:
-                   p_field_size=getSupport()->getMesh()->getLength(getSupport() );
-                   break;
-               case 2:
-                   p_field_size=getSupport()->getMesh()->getArea(getSupport() );
-                   break;
-               case 3:
-                   p_field_size=getSupport()->getMesh()->getVolume(getSupport() );
-                   break;
-           }
-           break;
-           
-       case MED_FACE :
-           p_field_size=getSupport()->getMesh()->getArea(getSupport() );
-           break;
-
-       case MED_EDGE :
-           p_field_size=getSupport()->getMesh()->getLength(getSupport() );
-           break;
+    case MED_CELL :
+      switch (mesh->getMeshDimension() ) 
+        {
+        case 1:
+          p_field_size=mesh->getLength( support );
+          break;
+        case 2:
+          p_field_size=mesh->getArea( support );
+          break;
+        case 3:
+          p_field_size=mesh->getVolume( support );
+          break;
+        }
+      break;
+
+    case MED_FACE :
+      p_field_size=mesh->getArea( support );
+      break;
+
+    case MED_EDGE :
+      p_field_size=mesh->getLength( support );
+      break;
+    case MED_NODE : // issue 0020120: [CEA 206] normL2 on NODE field
+      {
+        switch (mesh->getMeshDimension() ) 
+          {
+          case 1:
+            p_field_size=mesh->getLength( support );
+            break;
+          case 2:
+            p_field_size=mesh->getArea( support );
+            break;
+          case 3:
+            p_field_size=mesh->getVolume( support );
+            break;
+          }
+        break;
+      }
     }
-    return p_field_size;
+  if(!subSupport && support)
+    support->removeReference();
+  return p_field_size;
 }
 
 
@@ -224,63 +222,91 @@ FIELD<double>* FIELD_::_getFieldSize() const
   Check up the compatibility of field before computing sobolev norm 
   \endif
 */
-void FIELD_::_checkNormCompatibility(const FIELD<double>* support_volume) const throw (MEDEXCEPTION)
+void FIELD_::_checkNormCompatibility(const FIELD<double>* support_volume,
+                                     const bool           nodalAllowed) const throw (MEDEXCEPTION)
 {
-    string diagnosis;
+  string diagnosis;
 
-    if( getSupport()->getEntity() == MED_NODE )
+  if( getSupport()->getEntity() == MED_NODE)
     {
-       diagnosis="Cannot compute sobolev norm on a field "+getName()+
-           " : it has support on nodes!";
-       throw MEDEXCEPTION(diagnosis.c_str());
-    }
-       
-    if (getNumberOfValues()*getNumberOfComponents()<= 0) // Size of array has to be strictly positive
-    {
-       diagnosis="Cannot compute the norm of "+getName()+
-           " : it size is non positive!";
-       throw MEDEXCEPTION(diagnosis.c_str());
+      if ( !nodalAllowed )
+        {
+          diagnosis="Cannot compute sobolev norm on a field "+getName()+
+            " : it has support on nodes!";
+          throw MEDEXCEPTION(diagnosis.c_str());
+        }
+      if ( !getSupport()->getMesh() )
+        {
+          diagnosis="Cannot compute Lnorm of nodal field "+getName()+
+            " : it's support has no mesh reference";
+          throw MEDEXCEPTION(diagnosis.c_str());
+        }
+      if ( !getSupport()->getMesh()->getIsAGrid() &&
+           !( (const MESH*)getSupport()->getMesh() )->existConnectivity(MED_NODAL,MED_CELL) )
+        {
+          diagnosis="Cannot compute Lnorm of nodal field"+getName()+
+            " : it's supporting mesh has no nodal connectivity data";
+          throw MEDEXCEPTION(diagnosis.c_str());
+        }
     }
 
-    if( getSupport()->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS) != getNumberOfValues() ) {
-      diagnosis="Cannot compute Lnorm of "+getName()+
-        " : the suppors size not corresponded to number of elements!";
+  if (getNumberOfValues()*getNumberOfComponents()<= 0) // Size of array has to be strictly positive
+    {
+      diagnosis="Cannot compute the norm of "+getName()+
+        " : it size is non positive!";
       throw MEDEXCEPTION(diagnosis.c_str());
     }
 
-    if (getGaussPresence() ) {
-      diagnosis="Cannot compute Lnorm of "+getName()+
-       " : Gauss numbers greater than one are not yet implemented!";
-      throw MEDEXCEPTION(diagnosis.c_str());
-    }
+  if( getSupport()->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS) != getNumberOfValues() ) {
+    diagnosis="Cannot compute Lnorm of "+getName()+
+      " : the suppors size not corresponded to number of elements!";
+    throw MEDEXCEPTION(diagnosis.c_str());
+  }
 
-    if(support_volume) // if the user has supplied the volume
+  if (getGaussPresence() ) {
+    diagnosis="Cannot compute Lnorm of "+getName()+
+      " : Gauss numbers greater than one are not yet implemented!";
+    throw MEDEXCEPTION(diagnosis.c_str());
+  }
+
+  if(support_volume) // if the user has supplied the volume
     {
-       if(support_volume->getSupport()!=getSupport())
-       {
-           diagnosis="Cannot compute Lnorm of "+getName()+
-           " : the volume furnished has not the same support!";
-           throw MEDEXCEPTION(diagnosis.c_str());
-       }
-       if(support_volume->getNumberOfValues()!=getNumberOfValues())
-       {
-           diagnosis="Cannot compute Lnorm of "+getName()+
-           " : the volume furnished has not the same number of values!";
-           throw MEDEXCEPTION(diagnosis.c_str());
-       }
-        if( getSupport()->getNumberOfElements() != 
-            support_volume->getSupport()->getNumberOfElements() ) {
+      if ( getSupport()->getEntity() == MED_NODE )
+        {
+          if (support_volume->getNumberOfValues()!=
+              getSupport()->getMesh()->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS))
+            {
+              diagnosis="Cannot compute Lnorm of nodal field "+getName()+
+                " : the volume furnished has wrong number of values";
+              throw MEDEXCEPTION(diagnosis.c_str());
+            }
+          return;
+        }
+      if(support_volume->getSupport()!=getSupport())
+        {
+          diagnosis="Cannot compute Lnorm of "+getName()+
+            " : the volume furnished has not the same support!";
+          throw MEDEXCEPTION(diagnosis.c_str());
+        }
+      if(support_volume->getNumberOfValues()!=getNumberOfValues())
+        {
           diagnosis="Cannot compute Lnorm of "+getName()+
-            " : the supports have not the same number of elements!";
+            " : the volume furnished has not the same number of values!";
           throw MEDEXCEPTION(diagnosis.c_str());
         }
+      if( getSupport()->getNumberOfElements() != 
+          support_volume->getSupport()->getNumberOfElements() ) {
+        diagnosis="Cannot compute Lnorm of "+getName()+
+          " : the supports have not the same number of elements!";
+        throw MEDEXCEPTION(diagnosis.c_str());
+      }
     }
 
 }
 
 /*! 
   \if developper
-   Check up the compatibility of fields before performing an arithmetic operation
+  Check up the compatibility of fields before performing an arithmetic operation
   \endif
 */
 void FIELD_::_checkFieldCompatibility(const FIELD_& m, const FIELD_& n, bool checkUnit) throw (MEDEXCEPTION)
@@ -294,8 +320,8 @@ void FIELD_::_checkFieldCompatibility(const FIELD_& m, const FIELD_& n, bool che
 
     if(m._support != n._support)
       {
-       if(!(*m._support==*n._support))
-         diagnosis+="They don't have the same support!";
+        if(!(*m._support==*n._support))
+          diagnosis+="They don't have the same support!";
       }
     else if(m._numberOfComponents != n._numberOfComponents)
       diagnosis+="They don't have the same number of components!";
@@ -305,37 +331,37 @@ void FIELD_::_checkFieldCompatibility(const FIELD_& m, const FIELD_& n, bool che
       diagnosis+="They don't have the same number of values!";
     else
       {
-       if(checkUnit)
-         {
-           for(int i=0; i<m._numberOfComponents; i++)
-             {
-               // Not yet implemented   
-               //          if(m._componentsTypes[i] != n._componentsTypes[i])
-               //          {
-               //              diagnosis+="Components don't have the same types!";
-               //              break;
-               //          }
-               if(m._MEDComponentsUnits[i] != n._MEDComponentsUnits[i])
-                 {
-                   diagnosis+="Components don't have the same units!";
-                   break;
-                 }
-             }
-         }
+        if(checkUnit)
+          {
+            for(int i=0; i<m._numberOfComponents; i++)
+              {
+                // Not yet implemented   
+                //          if(m._componentsTypes[i] != n._componentsTypes[i])
+                //          {
+                //              diagnosis+="Components don't have the same types!";
+                //              break;
+                //          }
+                if(m._MEDComponentsUnits[i] != n._MEDComponentsUnits[i])
+                  {
+                    diagnosis+="Components don't have the same units!";
+                    break;
+                  }
+              }
+          }
       }
 
     if(diagnosis.size()) // if fields are not compatible : complete diagnosis and throw exception
     {
-       diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
-                + n._name + " are not compatible.\n" + diagnosis;
-       throw MEDEXCEPTION(diagnosis.c_str());
+        diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
+                 + n._name + " are not compatible.\n" + diagnosis;
+        throw MEDEXCEPTION(diagnosis.c_str());
     }
 
     if( m.getNumberOfValues()<=0 || m.getNumberOfComponents()<=0) // check up the size is strictly positive
     {
-       diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
-                + n._name + " are empty! (size<=0).\n";
-       throw MEDEXCEPTION(diagnosis.c_str());
+        diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
+                 + n._name + " are empty! (size<=0).\n";
+        throw MEDEXCEPTION(diagnosis.c_str());
     }
 
 }
@@ -351,8 +377,8 @@ void FIELD_::_deepCheckFieldCompatibility(const FIELD_& m, const FIELD_& n , boo
 
     if(m._support != n._support)
       {
-       if(!(m._support->deepCompare(*n._support)))
-         diagnosis+="They don't have the same support!";
+        if(!(m._support->deepCompare(*n._support)))
+          diagnosis+="They don't have the same support!";
       }
     else if (m._valueType != n._valueType)
       diagnosis+="They don't have the same type!";
@@ -362,31 +388,31 @@ void FIELD_::_deepCheckFieldCompatibility(const FIELD_& m, const FIELD_& n , boo
       diagnosis+="They don't have the same number of values!";
     else
       {
-       if(checkUnit)
-         {
-           for(int i=0; i<m._numberOfComponents; i++)
-             {
-               if(m._MEDComponentsUnits[i] != n._MEDComponentsUnits[i])
-                 {
-                   diagnosis+="Components don't have the same units!";
-                   break;
-                 }
-             }
-         }
+        if(checkUnit)
+          {
+            for(int i=0; i<m._numberOfComponents; i++)
+              {
+                if(m._MEDComponentsUnits[i] != n._MEDComponentsUnits[i])
+                  {
+                    diagnosis+="Components don't have the same units!";
+                    break;
+                  }
+              }
+          }
       }
 
     if(diagnosis.size()) // if fields are not compatible : complete diagnosis and throw exception
     {
-       diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
-                + n._name + " are not compatible.\n" + diagnosis;
-       throw MEDEXCEPTION(diagnosis.c_str());
+        diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
+                 + n._name + " are not compatible.\n" + diagnosis;
+        throw MEDEXCEPTION(diagnosis.c_str());
     }
 
     if( m.getNumberOfValues()<=0 || m.getNumberOfComponents()<=0) // check up the size is strictly positive
     {
-       diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
-                + n._name + " are empty! (size<=0).\n";
-       throw MEDEXCEPTION(diagnosis.c_str());
+        diagnosis="Field's operation not allowed!\nThe fields " + m._name + " and " 
+                 + n._name + " are empty! (size<=0).\n";
+        throw MEDEXCEPTION(diagnosis.c_str());
     }
 } 
 
@@ -398,8 +424,8 @@ void     FIELD_::rmDriver      (int index)
 
 int      FIELD_::addDriver     (driverTypes driverType, 
                                 const string & fileName,
-                               const string & driverFieldName,
-                               MED_EN::med_mode_acces access)
+                                const string & driverFieldName,
+                                MED_EN::med_mode_acces access)
 {
   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());
   return 0;
@@ -412,12 +438,17 @@ int      FIELD_::addDriver     (GENDRIVER & driver)
 }
 
 void     FIELD_::openAppend    ( void )                               {}
-void     FIELD_::write         (const GENDRIVER &)                    {}
+void     FIELD_::write         (const GENDRIVER &,
+                                MED_EN::med_mode_acces)               {}
+void     FIELD_::write         (driverTypes driverType,
+                                const std::string & fileName,
+                                MED_EN::med_mode_acces medMode)       {}
 void     FIELD_::writeAppend   (const GENDRIVER &)                    {}
-void     FIELD_::read          (const GENDRIVER &)                    {}
-void     FIELD_::write         (int , const string & ) {}
+void     FIELD_::write         (int ) {}
 void     FIELD_::writeAppend   (int , const string & ) {}
-void     FIELD_::read          (int )                                  {}
+void     FIELD_::read          (int )                                 {}
+void     FIELD_::read          (const GENDRIVER &)                    {}
+void     FIELD_::read          (driverTypes driverType, const std::string & fileName){}
 void     FIELD_::copyGlobalInfo(const FIELD_& m)
 {  
 
@@ -430,32 +461,15 @@ void     FIELD_::copyGlobalInfo(const FIELD_& m)
   for (int i=0; i<m._numberOfComponents; i++)
     {_componentsTypes[i]=m._componentsTypes[i];}
 
-  //if (m._componentsTypes != NULL)
-  //  {
-  //    _componentsTypes = new int[m._numberOfComponents] ;
-  //    memcpy(_componentsTypes,m._componentsTypes,sizeof(int)*m._numberOfComponents);
-  //  }
-  //else
-  //  _componentsTypes = (int *) NULL;
-
-  //_componentsNames = new string[m._numberOfComponents];
   for (int i=0; i<m._numberOfComponents; i++)
     _componentsNames[i]=m._componentsNames[i];
-  //_componentsDescriptions = new string[m._numberOfComponents];
   for (int i=0; i<m._numberOfComponents; i++)
     _componentsDescriptions[i]=m._componentsDescriptions[i];
 
-  //if (m._componentsUnits != NULL)
-  //  {
-  //    _componentsUnits = new UNIT[m._numberOfComponents];
   for (int i=0; i<m._numberOfComponents; i++)
     _componentsUnits[i] = m._componentsUnits[i];
-  //  }
-  //else
-  //  _componentsUnits=(UNIT*)NULL;
   
   // L'operateur '=' est defini dans la classe UNIT
-  //_MEDComponentsUnits = new string[m._numberOfComponents];
   for (int i=0; i<m._numberOfComponents; i++)
     {_MEDComponentsUnits[i] = m._MEDComponentsUnits[i];}