Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/med.git] / src / MEDMEM / MEDMEM_Field.hxx
index 5c39c264ddbbfc5692b22a593dc61e0dc04818e1..f96ecfee0dcb165b85ed9398dcb7c26e10f2e6fc 100644 (file)
@@ -25,6 +25,8 @@
 #ifndef FIELD_HXX
 #define FIELD_HXX
 
+#include "MEDMEM.hxx"
+
 #include <vector>
 #include <map>
 #include <algorithm>
@@ -43,6 +45,9 @@
 #include "MEDMEM_FieldForward.hxx"
 #include "MEDMEM_GaussLocalization.hxx"
 
+#define DBL_MAX 1.0E+308
+#define DBL_MIN -1.0E+308
+
 /*!
 
   This class contains all the informations related with a template class FIELD :
 
 namespace MEDMEM {
 
+  template<class T>
+  struct MinMax {
+  };
+
+  template<>
+  struct MinMax<double> {
+    static double getMin() { return DBL_MIN; }
+    static double getMax() { return DBL_MAX; }
+  };
+
+  template<>
+  struct MinMax<int> {
+    static int getMin() { return INT_MIN; }
+    static int getMax() { return INT_MAX; }
+  };  
+
   template < typename T > struct SET_VALUE_TYPE {
     static const MED_EN::med_type_champ _valueType = MED_EN::MED_UNDEFINED_TYPE;};
   template < > struct SET_VALUE_TYPE<double> {
@@ -61,11 +82,12 @@ namespace MEDMEM {
   template < > struct SET_VALUE_TYPE<int> {
     static const MED_EN::med_type_champ _valueType = MED_EN::MED_INT32; };
 
-class FIELD_    // GENERIC POINTER TO a template <class T, class INTERLACING_TAG> class FIELD
+class MEDMEM_EXPORT FIELD_    // GENERIC POINTER TO a template <class T, class INTERLACING_TAG> class FIELD
 {
 protected:
 
   bool            _isRead ;
+  bool            _isMinMax;
 
   /*!
     \if developper
@@ -579,7 +601,7 @@ inline MED_EN::med_type_champ FIELD_::getValueType () const
 }
 
 /*!
-  Get the FIELD med interlacing type (MED_FULL_INTERLACE or MED_NO_INTERLACE).
+  Get the FIELD med interlacing type (MED_FULL_INTERLACE, MED_NO_INTERLACE or MED_NO_INTERLACE_BY_TYPE).
 */
   inline MED_EN::medModeSwitch FIELD_::getInterlacingType () const
 {
@@ -604,8 +626,8 @@ inline MED_EN::med_type_champ FIELD_::getValueType () const
 /*!
 
   This template class contains informations related with a FIELD :
-  - Values of the field, their type (real or integer), the storage mode (full interlace or
-    no interlace).
+  - Values of the field, their type (real or integer), the storage mode (full interlace,
+    no interlace or no interlace by type).
 
 */
 
@@ -623,10 +645,12 @@ namespace MEDMEM {
 {
 protected:
 
-  typedef typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,NoGauss>::Array ArrayNoGauss;
-  typedef typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,Gauss>::Array   ArrayGauss;
-  typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array     ArrayNo;
-  typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array   ArrayFull;
+  typedef typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,NoGauss>::Array   ArrayNoGauss;
+  typedef typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,Gauss>::Array     ArrayGauss;
+  typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array       ArrayNo;
+  typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array     ArrayFull;
+  typedef typename MEDMEM_ArrayInterface<T,NoInterlaceByType,NoGauss>::Array ArrayNoByType;
+  typedef typename MEDMEM_ArrayInterface<T,NoInterlaceByType,Gauss>::Array   ArrayNoByTypeGauss;
   typedef MEDMEM_Array_ Array;
   typedef T ElementType;
   typedef INTERLACING_TAG InterlacingTag;
@@ -635,6 +659,10 @@ protected:
   // array of value of type T
   Array *_value ;
 
+  // extrema values
+  T _vmin;
+  T _vmax;
+
   map<MED_EN::medGeometryElement,GAUSS_LOCALIZATION_*> _gaussModel; //A changer quand les drivers seront template de l'entrelacement
 
   static T _scalarForPow;
@@ -683,6 +711,16 @@ public:
   static FIELD* div(const FIELD& m, const FIELD& n);
   static FIELD* divDeep(const FIELD& m, const FIELD& n);
   double normMax() const throw (MEDEXCEPTION);
+
+  //------- TDG and BS addings
+
+  void getMinMax(T &vmin, T &vmax) throw (MEDEXCEPTION);
+  vector<int> getHistogram(int &nbint) throw (MEDEXCEPTION);
+  FIELD<double>* buildGradient() const throw (MEDEXCEPTION);
+  FIELD<double>* buildNorm2Field() const throw (MEDEXCEPTION);
+
+  //-------------------
+
   double norm2() const throw (MEDEXCEPTION);
   void   applyLin(T a, T b);
   template <T T_function(T)> void applyFunc();
@@ -735,11 +773,19 @@ public:
   inline T            getValueIJ(int i,int j) const throw (MEDEXCEPTION);
   inline T            getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION);
 
+  inline int          getValueByTypeLength(int t)                const throw (MEDEXCEPTION);
+  inline const T*     getValueByType(int t)                      const throw (MEDEXCEPTION);
+  inline T            getValueIJByType(int i,int j,int t)        const throw (MEDEXCEPTION);
+  inline T            getValueIJKByType(int i,int j,int k,int t) const throw (MEDEXCEPTION);
+
   bool                getValueOnElement(int eltIdInSup,T* retValues) const throw (MEDEXCEPTION);
 
   const int   getNumberOfGeometricTypes() const throw (MEDEXCEPTION);
   const GAUSS_LOCALIZATION<INTERLACING_TAG> & getGaussLocalization(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
   const GAUSS_LOCALIZATION<INTERLACING_TAG> * getGaussLocalizationPtr(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
+  const GAUSS_LOCALIZATION_* getGaussLocalizationRoot(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
+  void setGaussLocalization(MED_EN::medGeometryElement geomElement, const GAUSS_LOCALIZATION<INTERLACING_TAG> & gaussloc);
+  void setGaussLocalization(MED_EN::medGeometryElement geomElement, GAUSS_LOCALIZATION_* gaussloc);
   const int * getNumberOfGaussPoints() const throw (MEDEXCEPTION);
   const int   getNumberOfGaussPoints( MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION);
   const int   getNbGaussI(int i)          const throw (MEDEXCEPTION);
@@ -752,6 +798,9 @@ public:
   inline void setRow( int i, T* value) throw (MEDEXCEPTION);
   inline void setColumn( int i, T* value) throw (MEDEXCEPTION);
   inline void setValueIJ(int i, int j, T value) throw (MEDEXCEPTION);
+  inline void setValueIJK(int i, int j, int k, T value) throw (MEDEXCEPTION);
+  inline void setValueIJByType(int i, int j, int t, T value) throw (MEDEXCEPTION);
+  inline void setValueIJKByType(int i, int j, int k, int t, T value) throw (MEDEXCEPTION);
 
   /*!
     This fonction feeds the FIELD<double> private attributs _value with the
@@ -803,6 +852,8 @@ public:
 
   typedef void (*myFuncType)(const double *,T*);
   void fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION);
+  typedef void (*myFuncType2)(const T *,T*);
+  FIELD<T,INTERLACING_TAG> *execFunc(int nbOfComponents, myFuncType2 f) throw (MEDEXCEPTION);
 };
 }
 
@@ -859,7 +910,7 @@ FIELD<T, INTERLACING_TAG>::FIELD(const SUPPORT * Support,
     // becarefull about the numbre of gauss point
     _numberOfValues = Support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
   }
-#ifdef _DEBUG_
+#if defined(_DEBUG_) || defined(_DEBUG)
   catch (MEDEXCEPTION &ex) {
 #else
   catch (MEDEXCEPTION ) {
@@ -895,17 +946,17 @@ template <class T, class INTERLACING_TAG> FIELD<T, INTERLACING_TAG>::FIELD(const
   if (m._value != NULL)
     {
       if ( m.getGaussPresence() )
-       _value = new ArrayGauss( *(dynamic_cast< ArrayGauss * > (m._value) ) ,false);
+       _value = new ArrayGauss( *(static_cast< ArrayGauss * > (m._value) ) ,false);
       else
-       _value = new ArrayNoGauss( *(dynamic_cast< ArrayNoGauss * > (m._value)) ,false);
+       _value = new ArrayNoGauss( *(static_cast< ArrayNoGauss * > (m._value)) ,false);
     }
   else
     _value = (ArrayNoGauss *) NULL;
   locMap::const_iterator it;
   for ( it = m._gaussModel.begin();it != m._gaussModel.end(); it++ )
-    _gaussModel[dynamic_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ((*it).second)->getType()]=
+    _gaussModel[static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ((*it).second)->getType()]=
       new GAUSS_LOCALIZATION<INTERLACING_TAG>(
-                                             *dynamic_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ( (*it).second )
+                                             *static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ( (*it).second )
                                              );
 
   _valueType       = m._valueType;
@@ -932,9 +983,9 @@ FIELD<T, INTERLACING_TAG> & FIELD<T, INTERLACING_TAG>::operator=(const FIELD &m)
                                //CF :Commentaire dans MEDMEM_Array
   locMap::const_iterator it;
   for ( it = m._gaussModel.begin();it != m._gaussModel.end(); it++ )
-    _gaussModel[dynamic_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ((*it).second)->getType()]=
+    _gaussModel[static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ((*it).second)->getType()]=
       new GAUSS_LOCALIZATION<INTERLACING_TAG>(
-                                             *dynamic_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ( (*it).second )
+                                             *static_cast<const GAUSS_LOCALIZATION<INTERLACING_TAG> * > ( (*it).second )
                                              );
 
   _valueType       = m._valueType;
@@ -1563,6 +1614,297 @@ template <class T, class INTERLACIN_TAG> double FIELD<T, INTERLACIN_TAG>::norm2(
 }
 
 
+//------------- TDG and BS addings 
+
+/*!  Return Extremums of field
+ */
+ template <class T, class INTERLACIN_TAG> void FIELD<T, INTERLACIN_TAG>::getMinMax(T &vmin, T &vmax) throw (MEDEXCEPTION)
+{
+  const T* value=getValue(); // get pointer to the values
+  const int size=getNumberOfValues()*getNumberOfComponents();
+  const T* lastvalue=value+size; // point just after last value
+    
+  if (size <= 0){ // Size of array has to be strictly positive
+      
+    string diagnosis;
+    diagnosis="FIELD<T,INTERLACIN_TAG>::getMinMax() : cannot compute the extremums of "+getName()+
+      " : its size is non positive!";
+    throw MEDEXCEPTION(diagnosis.c_str());
+  }
+    
+  if (!_isMinMax){
+    vmax=MinMax<T>::getMin(); // init a max value
+    vmin=MinMax<T>::getMax(); // init a min value
+      
+    for( ; value!=lastvalue ; ++value){
+      if ( vmin > *value )
+       vmin=*value;
+      if ( vmax < *value )
+       vmax=*value;
+    }
+    _isMinMax=true;
+    _vmin=vmin;
+    _vmax=vmax;
+  }
+  else{
+    vmin = _vmin;
+    vmax = _vmax;
+  }
+
+}
+
+/*!  Return Histogram of field
+ */
+ template <class T, class INTERLACIN_TAG> vector<int> FIELD<T, INTERLACIN_TAG>::getHistogram(int &nbint) throw (MEDEXCEPTION)
+{
+  const T* value=getValue(); // get pointer to the values
+  const int size=getNumberOfValues()*getNumberOfComponents();
+  const T* lastvalue=value+size; // point just after last value
+
+  if (size <= 0){ // Size of array has to be strictly positive
+
+    string diagnosis;
+    diagnosis="FIELD<T,INTERLACIN_TAG>::getHistogram() : cannot compute the histogram of "+getName()+
+      " : it size is non positive!";
+    throw MEDEXCEPTION(diagnosis.c_str());
+  }
+  //    return static_cast<ArrayGauss *>(_value)->getIJ(valIndex,j) ;
+
+  vector<int> Histogram(nbint) ;
+  T vmin,vmax;
+  int j;
+
+  for( j=0 ; j!=nbint ; j++) Histogram[j]=0 ;
+    
+  getMinMax(vmin,vmax);
+  for( ; value!=lastvalue ; ++value){
+    if(*value==vmax) j = nbint-1;
+    else j = (int)(((double)nbint * (*value-vmin))/(vmax-vmin));
+    Histogram[j]+=1 ;
+  }
+
+  return Histogram ;
+
+}
+
+/*!  Return vectorial gradient field
+ */
+template <class T, class INTERLACIN_TAG> 
+FIELD<double, FullInterlace>* FIELD<T, INTERLACIN_TAG>::buildGradient() const throw (MEDEXCEPTION)
+{
+  const char * LOC = "FIELD<T, INTERLACIN_TAG>::buildGradient() : ";
+  BEGIN_OF(LOC);
+
+  // space dimension of input mesh
+  int spaceDim = getSupport()->getMesh()->getSpaceDimension();
+  double *x = new double[spaceDim];
+
+  FIELD<double, FullInterlace>* Gradient =
+    new FIELD<double, FullInterlace>(getSupport(),spaceDim);
+
+  string name("gradient of ");
+  name += getName();
+  Gradient->setName(name);
+  string descr("gradient of ");
+  descr += getDescription();
+  Gradient->setDescription(descr);
+
+  if( _numberOfComponents > 1 ){
+    delete Gradient;
+    delete [] x;
+    throw MEDEXCEPTION("gradient calculation only on scalar field");
+  }
+
+  for(int i=1;i<=spaceDim;i++){
+    string nameC("gradient of ");
+    nameC += getName();
+    Gradient->setComponentName(i,nameC);
+    Gradient->setComponentDescription(i,"gradient");
+    string MEDComponentUnit = getMEDComponentUnit(1)+getSupport()->getMesh()->getCoordinatesUnits()[i-1];
+    Gradient->setMEDComponentUnit(i,MEDComponentUnit);
+  }
+
+  Gradient->setIterationNumber(getIterationNumber());
+  Gradient->setOrderNumber(getOrderNumber());
+  Gradient->setTime(getTime());
+
+  // typ of entity on what is field
+  MED_EN::medEntityMesh typ = getSupport()->getEntity();
+
+  const int *C;
+  const int *iC;  
+  const int *revC;
+  const int *indC;
+  const double *coord;
+  int NumberOf;
+
+  switch (typ) {
+  case MED_CELL:
+  case MED_FACE:
+  case MED_EDGE:
+    {
+      // read connectivity array to have the list of nodes contained by an element
+      C = getSupport()->getMesh()->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,typ,MED_ALL_ELEMENTS);
+      iC = getSupport()->getMesh()->getConnectivityIndex(MED_NODAL,typ);
+      // calculate reverse connectivity to have the list of elements which contains node i
+      revC = getSupport()->getMesh()->getReverseConnectivity(MED_NODAL,typ);
+      indC = getSupport()->getMesh()->getReverseConnectivityIndex(MED_NODAL,typ);
+      // coordinates of each node
+      coord = getSupport()->getMesh()->getCoordinates(MED_FULL_INTERLACE);
+      // number of elements
+      NumberOf = getSupport()->getNumberOfElements(MED_ALL_ELEMENTS);
+      // barycenter field of elements
+      FIELD<double, FullInterlace>* barycenter = getSupport()->getMesh()->getBarycenter(getSupport());
+
+      // calculate gradient vector for each element i
+      for (int i = 1; i < NumberOf + 1; i++) {
+
+        // listElements contains elements which contains a node of element i
+        set <int> listElements;
+        set <int>::iterator elemIt;
+        listElements.clear();
+
+        // for each node j of element i
+        for (int ij = iC[i-1]; ij < iC[i]; ij++) {
+          int j = C[ij-1];
+          for (int k = indC[j-1]; k < indC[j]; k++) {
+            // c element contains node j
+            int c = revC[k-1];
+            // we put the elements in set
+            if (c != i)
+              listElements.insert(c);
+          }
+        }
+        // coordinates of barycentre of element i in space of dimension spaceDim
+        for (int j = 0; j < spaceDim; j++)
+          x[j] = barycenter->getValueIJ(i,j+1);
+
+        for (int j = 0; j < spaceDim; j++) {
+          // value of field of element i
+          double val = getValueIJ(i,1);
+          double grad = 0.;
+          // calculate gradient for each neighbor element
+          for (elemIt = listElements.begin(); elemIt != listElements.end(); elemIt++) {
+            int elem = *elemIt;
+            double d2 = 0.;
+            for (int l = 0; l < spaceDim; l++) {
+              // coordinate of barycenter of element elem
+              double xx = barycenter->getValueIJ(elem, l+1);
+              d2 += (x[l]-xx) * (x[l]-xx);
+            }
+            grad += (barycenter->getValueIJ(elem,j+1)-x[j])*(getValueIJ(elem,1)-val)/sqrt(d2);
+          }
+          if (listElements.size() != 0) grad /= listElements.size();
+          Gradient->setValueIJ(i,j+1,grad);
+        }
+      }
+      delete barycenter;
+    }
+    break;
+  case MED_NODE:
+    // read connectivity array to have the list of nodes contained by an element
+    C = getSupport()->getMesh()->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_ALL_ELEMENTS);
+    iC = getSupport()->getMesh()->getConnectivityIndex(MED_NODAL,MED_CELL);
+    // calculate reverse connectivity to have the list of elements which contains node i
+    revC=getSupport()->getMesh()->getReverseConnectivity(MED_NODAL,MED_CELL);
+    indC=getSupport()->getMesh()->getReverseConnectivityIndex(MED_NODAL,MED_CELL);
+    // coordinates of each node
+    coord = getSupport()->getMesh()->getCoordinates(MED_FULL_INTERLACE);
+
+    // calculate gradient for each node
+    NumberOf = getSupport()->getNumberOfElements(MED_ALL_ELEMENTS);
+    for (int i=1; i<NumberOf+1; i++){
+      // listNodes contains nodes neigbor of node i 
+      set <int> listNodes;
+      set <int>::iterator nodeIt ;
+      listNodes.clear();
+      for(int j=indC[i-1];j<indC[i];j++){
+       // c element contains node i
+       int c=revC[j-1];
+       // we put the nodes of c element in set
+       for(int k=iC[c-1];k<iC[c];k++)
+         if(C[k-1] != i)
+           listNodes.insert(C[k-1]);
+      }
+      // coordinates of node i in space of dimension spaceDim
+      for(int j=0;j<spaceDim;j++)
+       x[j] = coord[(i-1)*spaceDim+j];
+      
+      for(int j=0;j<spaceDim;j++){
+       // value of field
+       double val = getValueIJ(i,1);
+       double grad = 0.;
+       // calculate gradient for each neighbor node
+       for(nodeIt=listNodes.begin();nodeIt!=listNodes.end();nodeIt++){
+         int node = *nodeIt;
+         double d2 = 0.;
+         for(int l=0;l<spaceDim;l++){
+           double xx = coord[(node-1)*spaceDim+l];
+           d2 += (x[l]-xx) * (x[l]-xx);
+         }
+         grad += (coord[(node-1)*spaceDim+j]-x[j])*(getValueIJ(node,1)-val)/sqrt(d2);
+       }
+       if(listNodes.size() != 0) grad /= listNodes.size();
+       Gradient->setValueIJ(i,j+1,grad);
+      }
+    }
+    break;
+  case MED_ALL_ENTITIES:
+    delete [] x;
+    delete Gradient;
+    throw MEDEXCEPTION("gradient calculation not yet implemented on all elements");
+    break;
+  }
+
+  delete [] x;
+
+  END_OF(LOC);
+  return Gradient;
+}
+
+/*!  Return scalar norm2 field
+ */
+template <class T, class INTERLACIN_TAG> 
+FIELD<double, FullInterlace>* FIELD<T, INTERLACIN_TAG>::buildNorm2Field() const throw (MEDEXCEPTION)
+{
+  const char * LOC = "FIELD<T, INTERLACIN_TAG>::buildNorm2Field() : ";
+  BEGIN_OF(LOC);
+
+  FIELD<double, FullInterlace>* Norm2Field =
+    new FIELD<double, FullInterlace>(getSupport(),1);
+
+  string name("norm2 of ");
+  name += getName();
+  Norm2Field->setName(name);
+  string descr("norm2 of ");
+  descr += getDescription();
+  Norm2Field->setDescription(descr);
+
+  string nameC("norm2 of ");
+  nameC += getName();
+  Norm2Field->setComponentName(1,nameC);
+  Norm2Field->setComponentDescription(1,"norm2");
+  string MEDComponentUnit = getMEDComponentUnit(1);
+  Norm2Field->setMEDComponentUnit(1,MEDComponentUnit);
+
+  Norm2Field->setIterationNumber(getIterationNumber());
+  Norm2Field->setOrderNumber(getOrderNumber());
+  Norm2Field->setTime(getTime());
+
+  // calculate nom2 for each element
+  int NumberOf = getSupport()->getNumberOfElements(MED_ALL_ELEMENTS);
+  for (int i=1; i<NumberOf+1; i++){
+    double norm2 = 0.;
+    for(int j=1;j<=getNumberOfComponents();j++)
+      norm2 += getValueIJ(i,j)*getValueIJ(i,j);
+    Norm2Field->setValueIJ(i,1,sqrt(norm2));
+  }
+
+  END_OF(LOC);
+  return Norm2Field;
+
+}
+
 /*!  Apply to each (scalar) field component the template parameter T_function,
  *   which is a pointer to function.
  *   Since the pointer is known at compile time, the function is inlined into the inner loop!
@@ -1703,11 +2045,16 @@ double FIELD<T, INTERLACING_TAG>::normL2(int component,
     ArrayNo * myArray   = NULL;
     if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
       value = getValue();
+    else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) {
+      myArray = ArrayConvert2No( *( dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ) ));
+      value   = myArray->getPtr();
+    }
     else {
       myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) ));
       value   = myArray->getPtr();
     }
-
+    
+    value = value + (component-1) * getNumberOfValues();
     const T* lastvalue=value+getNumberOfValues(); // pointing just after the end of column
 
     double integrale=0.0;
@@ -1720,7 +2067,7 @@ double FIELD<T, INTERLACING_TAG>::normL2(int component,
 
     if(!p_field_volume) // if the user didn't supply the volume
        delete p_field_size; // delete temporary volume field
-    if ( getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) delete myArray;
+    if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete myArray;
     if( totVol <= 0)
        throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
 
@@ -1747,6 +2094,10 @@ double FIELD<T, INTERLACING_TAG>::normL2(const FIELD<double, FullInterlace> * p_
     ArrayNo * myArray   = NULL;
     if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
       value = getValue();
+    else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ){
+      myArray = ArrayConvert2No( *( dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ) ));
+      value   = myArray->getPtr();
+    }
     else {
       myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) ));
       value   = myArray->getPtr();
@@ -1764,7 +2115,7 @@ double FIELD<T, INTERLACING_TAG>::normL2(const FIELD<double, FullInterlace> * p_
 
     if(!p_field_volume) // if the user didn't supply the volume
        delete p_field_size; // delete temporary volume field
-    if ( getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) delete myArray;
+    if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete myArray;
     if( totVol <= 0)
        throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
 
@@ -1793,6 +2144,10 @@ double FIELD<T, INTERLACING_TAG>::normL1(int component,
     ArrayNo * myArray   = NULL;
     if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
       value = getColumn(component);
+    else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) {
+      myArray = ArrayConvert2No( *( dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ) ));
+      value   = myArray->getColumn(component);
+    }
     else {
       myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) ));
       value   = myArray->getColumn(component);
@@ -1810,7 +2165,7 @@ double FIELD<T, INTERLACING_TAG>::normL1(int component,
 
     if(!p_field_volume) // if the user didn't supply the volume
        delete p_field_size; // delete temporary volume field
-    if ( getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) delete myArray;
+    if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete myArray;
     if( totVol <= 0)
        throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
 
@@ -1837,6 +2192,10 @@ double FIELD<T, INTERLACING_TAG>::normL1(const FIELD<double, FullInterlace> * p_
     ArrayNo * myArray   = NULL;
     if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE )
       value = getValue();
+    else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) {
+      myArray = ArrayConvert2No( *( dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ) ));
+      value   = myArray->getPtr();
+    }
     else {
       myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) ));
       value   = myArray->getPtr();
@@ -1854,7 +2213,7 @@ double FIELD<T, INTERLACING_TAG>::normL1(const FIELD<double, FullInterlace> * p_
 
     if(!p_field_volume) // if the user didn't supply the volume
        delete p_field_size; // delete temporary volume field
-    if ( getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) delete myArray;
+    if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete myArray;
     if( totVol <= 0)
        throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!"));
 
@@ -2415,7 +2774,7 @@ FIELD<T, INTERLACING_TAG>::getArrayGauss() const throw (MEDEXCEPTION)
   BEGIN_OF(LOC);
 
   if ( getGaussPresence() )
-    return dynamic_cast<ArrayGauss *> (_value);
+    return static_cast<ArrayGauss *> (_value);
   else
     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<
                                 "The field has no Gauss Point"));
@@ -2432,7 +2791,7 @@ FIELD<T, INTERLACING_TAG>::getArrayNoGauss() const throw (MEDEXCEPTION)
   BEGIN_OF(LOC);
 
   if ( ! getGaussPresence() )
-    return dynamic_cast < ArrayNoGauss * > (_value);
+    return static_cast < ArrayNoGauss * > (_value);
   else
     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<
                                 "The field has Gauss Point"));
@@ -2464,9 +2823,9 @@ inline int FIELD<T, INTERLACING_TAG>::getValueLength() const
   throw (MEDEXCEPTION)
 {
   if ( getGaussPresence() )
-    return dynamic_cast<ArrayGauss *>(_value)->getArraySize() ;
+    return static_cast<ArrayGauss *>(_value)->getArraySize() ;
   else
-    return dynamic_cast<ArrayNoGauss *>(_value)->getArraySize() ;
+    return static_cast<ArrayNoGauss *>(_value)->getArraySize() ;
 }
 
 /*!
@@ -2478,9 +2837,9 @@ inline const T* FIELD<T, INTERLACIN_TAG>::getValue() const throw (MEDEXCEPTION)
   const char * LOC ="FIELD<T, INTERLACING_TAG>::getValue() : ";
   BEGIN_OF(LOC);
   if ( getGaussPresence() )
-    return dynamic_cast<ArrayGauss *>(_value)->getPtr() ;
+    return static_cast<ArrayGauss *>(_value)->getPtr() ;
   else
-    return dynamic_cast<ArrayNoGauss *>(_value)->getPtr() ;
+    return static_cast<ArrayNoGauss *>(_value)->getPtr() ;
 }
 /*!
   Return a reference to i^{th} row
@@ -2518,7 +2877,7 @@ FIELD<T,INTERLACING_TAG>::getRow(int i) const throw (MEDEXCEPTION)
 template <class T,class INTERLACING_TAG> inline const T*
 FIELD<T,INTERLACING_TAG>::getColumn(int j) const throw (MEDEXCEPTION)
 {
-  const char * LOC ="FIELD<T,INTERLACING_TAG>::getColumn(int j) : ";
+  //const char * LOC ="FIELD<T,INTERLACING_TAG>::getColumn(int j) : ";
   //BEGIN_OF(LOC);
   if ( getGaussPresence() )
     return static_cast<ArrayGauss *>(_value)->getColumn(j) ;
@@ -2564,6 +2923,84 @@ template <class T,class INTERLACING_TAG> inline T FIELD<T,INTERLACING_TAG>::getV
     return static_cast<ArrayNoGauss *>(_value)->getIJK(valIndex,j,k) ;
 }
 
+/*!
+  Return number of values of a geomertic type in NoInterlaceByType mode
+*/
+template <class T, class INTERLACIN_TAG>
+inline int FIELD<T, INTERLACIN_TAG>::getValueByTypeLength(int t) const throw (MEDEXCEPTION)
+{
+  const char * LOC ="getValueByTypeLength() : ";
+  //BEGIN_OF(LOC);
+  if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
+    throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" ));
+
+  if ( getGaussPresence() ) {
+    ArrayNoByTypeGauss* array = static_cast<ArrayNoByTypeGauss *>(_value);
+    if (  t < 1 || t > array->getNbGeoType() )
+      throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Invalid type: "<< t ));
+    return array->getLengthOfType( t );
+  }
+  else {
+    ArrayNoByType* array = static_cast<ArrayNoByType *>(_value);
+    if (  t < 1 || t > array->getNbGeoType() )
+      throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Invalid type: "<< t ));
+    return array->getLengthOfType( t );
+  }
+}
+
+/*!
+  Return a reference to values array to read them.
+*/
+template <class T, class INTERLACIN_TAG>
+inline const T* FIELD<T, INTERLACIN_TAG>::getValueByType(int t) const throw (MEDEXCEPTION)
+{
+  const char * LOC ="getValueByType() : ";
+  //BEGIN_OF(LOC);
+  if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
+    throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" ));
+
+  if ( getGaussPresence() ) {
+    ArrayNoByTypeGauss* array = static_cast<ArrayNoByTypeGauss *>(_value);
+    return array->getPtr() + array->getIndex( t );
+  }
+  else {
+    ArrayNoByType* array = static_cast<ArrayNoByType *>(_value);
+    return array->getPtr() + array->getIndex( t );
+  }
+}
+
+/*!
+  Return the value of i^{th} element in indicated type t and j^{th} component.
+*/
+template <class T,class INTERLACING_TAG> inline T FIELD<T,INTERLACING_TAG>::getValueIJByType(int i,int j, int t) const throw (MEDEXCEPTION)
+{
+  const char * LOC = "getValueIJByType(..)";
+  //BEGIN_OF(LOC);
+  if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
+    throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" ));
+    
+  if ( getGaussPresence() )
+    return static_cast<ArrayNoByTypeGauss *>(_value)->getIJByType(i,j,t) ;
+  else
+    return static_cast<ArrayNoByType *>(_value)->getIJByType(i,j,t) ;
+}
+
+/*!
+  Return the j^{th} component of k^{th} gauss points of i^{th} value with type t.
+*/
+template <class T,class INTERLACING_TAG> inline T FIELD<T,INTERLACING_TAG>::getValueIJKByType(int i,int j,int k,int t) const throw (MEDEXCEPTION)
+{
+  const char * LOC = "getValueIJKByType(..)";
+  //BEGIN_OF(LOC);
+  if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
+    throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" ));
+
+  if ( getGaussPresence() )
+    return static_cast<ArrayNoByTypeGauss *>(_value)->getIJKByType(i,j,k,t) ;
+  else
+    return static_cast<ArrayNoByType      *>(_value)->getIJKByType(i,j,k,t) ;
+}
+
 
 template <class T,class INTERLACING_TAG> const int FIELD<T,INTERLACING_TAG>::getNumberOfGeometricTypes() const throw (MEDEXCEPTION)
 {
@@ -2609,6 +3046,53 @@ FIELD<T,INTERLACING_TAG>::getGaussLocalizationPtr(MED_EN::medGeometryElement geo
 
 };
 
+/*!
+ * \brief Return GAUSS_LOCALIZATION_* whose interlacing type may differ from one of the field
+ */
+template <class T,class INTERLACING_TAG> const GAUSS_LOCALIZATION_ *
+FIELD<T,INTERLACING_TAG>::getGaussLocalizationRoot(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION)
+{
+  const char * LOC ="getGaussLocalizationRoot(MED_EN::medGeometryElement geomElement) : ";
+
+  locMap::const_iterator it;
+  if ( ( it = _gaussModel.find(geomElement)) != _gaussModel.end() ) {
+       return (*it).second;
+  }
+  else
+    throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Can't find any GaussLocalization on this geometric type: "<< geomElement ));
+
+};
+
+/*!
+ * \brief Take onership of GAUSS_LOCALIZATION_* whose interlacing type may differ from one of the field
+ */
+template <class T,class INTERLACING_TAG> void
+FIELD<T,INTERLACING_TAG>::setGaussLocalization(MED_EN::medGeometryElement geomElement, GAUSS_LOCALIZATION_* gaussloc)
+{
+  locMap::iterator it = _gaussModel.find(geomElement);
+  if ( it != _gaussModel.end() ) {
+    delete it->second;
+    it->second = gaussloc;
+  }
+  else {
+    _gaussModel[ geomElement ] = gaussloc;
+  }
+};
+
+
+template <class T,class INTERLACING_TAG> void
+FIELD<T,INTERLACING_TAG>::setGaussLocalization(MED_EN::medGeometryElement geomElement, const GAUSS_LOCALIZATION<INTERLACING_TAG>& gaussloc)
+{
+  locMap::iterator it = _gaussModel.find(geomElement);
+  if ( it != _gaussModel.end() ) {
+    delete it->second;
+    it->second = new GAUSS_LOCALIZATION<INTERLACING_TAG> (gaussloc);
+  }
+  else {
+    _gaussModel[ geomElement ] = new GAUSS_LOCALIZATION<INTERLACING_TAG> (gaussloc);
+  }
+};
+
 /*!
   Returns number of Gauss points for this medGeometryElement.
 
@@ -2656,7 +3140,7 @@ template <class T,class INTERLACING_TAG> const int * FIELD<T,INTERLACING_TAG>::g
 
   if (_value)
     if ( getGaussPresence() ) {
-      return dynamic_cast<ArrayGauss *>(_value)->getNbGaussGeo()+1;
+      return static_cast<ArrayGauss *>(_value)->getNbGaussGeo()+1;
     } else
       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"value hasn't Gauss points " ));
 
@@ -2731,9 +3215,9 @@ template <class T,class INTERLACING_TAG> bool  FIELD<T,INTERLACING_TAG>::isOnAll
 template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValue( T* value) throw (MEDEXCEPTION) 
 {
   if ( getGaussPresence() )
-    return dynamic_cast<ArrayGauss *>(_value)->setPtr(value) ;
+    static_cast<ArrayGauss *>(_value)->setPtr(value) ;
   else
-    return dynamic_cast<ArrayNoGauss *>(_value)->setPtr(value) ;
+    static_cast<ArrayNoGauss *>(_value)->setPtr(value) ;
 }
 
 /*!
@@ -2751,9 +3235,9 @@ inline void FIELD<T,INTERLACING_TAG>::setRow( int i, T* value) throw (MEDEXCEPTI
     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
 
   if ( getGaussPresence() )
-    return static_cast<ArrayGauss *>(_value)->setRow(valIndex, value) ;
+    static_cast<ArrayGauss *>(_value)->setRow(valIndex, value) ;
   else
-    return static_cast<ArrayNoGauss *>(_value)->setRow(valIndex, value) ;
+    static_cast<ArrayNoGauss *>(_value)->setRow(valIndex, value) ;
 }
 
 /*!
@@ -2764,9 +3248,9 @@ template <class T,class INTERLACING_TAG>
 inline void FIELD<T,INTERLACING_TAG>::setColumn( int j, T* value) throw (MEDEXCEPTION)
 {
   if ( getGaussPresence() )
-    return static_cast<ArrayGauss *>(_value)->setColumn(j, value) ;
+    static_cast<ArrayGauss *>(_value)->setColumn(j, value) ;
   else
-    return static_cast<ArrayNoGauss *>(_value)->setColumn(j, value) ;
+    static_cast<ArrayNoGauss *>(_value)->setColumn(j, value) ;
 }
 
 /*!
@@ -2782,9 +3266,57 @@ template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::s
     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
 
   if ( getGaussPresence() )
-    return static_cast<ArrayGauss *>(_value)->setIJ(valIndex,j,value) ;
+    static_cast<ArrayGauss *>(_value)->setIJ(valIndex,j,value) ;
+  else
+    static_cast<ArrayNoGauss *>(_value)->setIJ(valIndex,j,value) ;
+}
+
+/*!
+  Set the value of i^{th} element, j^{th} component and k^{th} gauss point with the given one.
+*/
+template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValueIJK(int i, int j, int k, T value) throw (MEDEXCEPTION) 
+{
+  const char * LOC = "FIELD<T,INTERLACING_TAG>::setValueIJ(int i, int j, T value) : ";
+  int valIndex=-1;
+  if (_support)
+    valIndex = _support->getValIndFromGlobalNumber(i);
+  else
+    throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not define |" ));
+
+  if ( getGaussPresence() )
+    static_cast<ArrayGauss *>(_value)->setIJK(valIndex,j,k,value) ;
+  else
+    static_cast<ArrayNoGauss *>(_value)->setIJK(valIndex,j,k,value) ;
+}
+
+/*!
+  Set the value of i^{th} element and j^{th} component with the given one.
+*/
+template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValueIJByType(int i, int j, int t, T value) throw (MEDEXCEPTION) 
+{
+  const char * LOC = "FIELD<T,INTERLACING_TAG>::setValueIJByType(int i, int j, int t, T value) : ";
+  if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
+    throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" ));
+
+  if ( getGaussPresence() )
+    return static_cast<ArrayNoByTypeGauss *>(_value)->setIJByType(i,j,t,value) ;
+  else
+    return static_cast<ArrayNoByType *>(_value)->setIJByType(i,j,t,value) ;
+}
+
+/*!
+  Set the value of component of k^{th} gauss points of i^{th} element and j^{th} component with the given one.
+*/
+template <class T,class INTERLACING_TAG> inline void FIELD<T,INTERLACING_TAG>::setValueIJKByType(int i, int j, int k, int t, T value) throw (MEDEXCEPTION) 
+{
+  const char * LOC = "FIELD<T,INTERLACING_TAG>::setValueIJKByType(int i, int j, int t, int k, T value) : ";
+  if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
+    throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" ));
+
+  if ( getGaussPresence() )
+    return static_cast<ArrayNoByTypeGauss *>(_value)->setIJKByType(i,j,k,t,value) ;
   else
-    return static_cast<ArrayNoGauss *>(_value)->setIJ(valIndex,j,value) ;
+    return static_cast<ArrayNoByType *>(_value)->setIJKByType(i,j,k,t,value) ;
 }
 
 /*
@@ -2963,6 +3495,22 @@ void FIELD<T, INTERLACING_TAG>::fillFromAnalytic(myFuncType f) throw (MEDEXCEPTI
       delete [] xyz[j];
   delete [] xyz;
 }
+/*!
+  Execute a function on _values on 'this' and put the result on a newly created field that has to be deallocated.
+  WARNING : "this" must have allocated its array by setting this->_support and this->_numberOfComponents properly.
+  Typically you should use it on a field built with constructor FIELD<T>::FIELD<T>(SUPPORT *,int nbOfComponents)
+ */
+                                                                         template <class T, class INTERLACING_TAG>
+                                                                         FIELD<T,INTERLACING_TAG> *FIELD<T, INTERLACING_TAG>::execFunc(int nbOfComponents, myFuncType2 f) throw (MEDEXCEPTION)
+{
+  FIELD<T,INTERLACING_TAG> *ret=new FIELD<T,INTERLACING_TAG>(_support,nbOfComponents);
+  const T* valsInput=getValue();
+  T* valsOutPut=(T*)ret->getValue();
+  int i;
+  for(i=0;i<_numberOfValues;i++)
+    f(valsInput+i*_numberOfComponents,valsOutPut+i*nbOfComponents);
+  return ret;
+}
 
 }//End namespace MEDMEM