Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/med.git] / src / MEDMEM / MEDMEM_MedFieldDriver21.hxx
index 8912451da57d81665602c6045a20aa31387ce313..e96d5703f6546bb3fa3fbe18e16e5d28741f1cdc 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "MEDMEM_Support.hxx"
 #include "MEDMEM_Mesh.hxx"
+#include "MEDMEM_GaussLocalization.hxx"
 
 namespace MEDMEM {
 
@@ -57,6 +58,7 @@ protected:
                          med_2_1::med_int ndt,
                          med_2_1::med_int od,
                          SUPPORT & support,
+                         vector<int> & numberOfGaussPoint,
                          string & meshName) const throw (MEDEXCEPTION);
 
   void getMeshGeometricType(med_2_1::med_idt id,
@@ -336,11 +338,12 @@ private:
 
 template <class T> bool
 MED_FIELD_DRIVER21<T>::createFieldSupport(med_2_1::med_idt id,
-                                       string & fieldName,
-                                       med_2_1::med_int ndt,
-                                       med_2_1::med_int od,
-                                       SUPPORT & support,
-                                       string & meshName) const throw (MEDEXCEPTION)
+                                          string & fieldName,
+                                          med_2_1::med_int ndt,
+                                          med_2_1::med_int od,
+                                          SUPPORT & support,
+                                          vector<int> & numberOfGaussPoints,
+                                          string & meshName) const throw (MEDEXCEPTION)
 {
 
   //EF : Gérer le meshName pour le driver 2.2
@@ -359,13 +362,14 @@ MED_FIELD_DRIVER21<T>::createFieldSupport(med_2_1::med_idt id,
 
   //med_2_1::med_entite_maillage
   MED_EN::medEntityMesh entity;
-  bool alreadyFoundAnEntity=false, alreadyFoundPdtIt = false, anyGauss=false;
+  bool alreadyFoundAnEntity=false, alreadyFoundPdtIt = false/*, anyGauss=false*/;
   int  numberOfElements = 0, numberOfElements1 = 0,numberOfElements2 = 0;
   int  numberOfGeometricType = 0;
   //med_2_1::med_geometrie_element..
   MED_EN::medGeometryElement geometricType[MED_NBR_GEOMETRIE_MAILLE];
   int numberOfElementsOfType[MED_NBR_GEOMETRIE_MAILLE];
-  int numberOfGaussPoints[MED_NBR_GEOMETRIE_MAILLE];
+  //int numberOfGaussPoints[MED_NBR_GEOMETRIE_MAILLE];
+  numberOfGaussPoints.resize(MED_NBR_GEOMETRIE_MAILLE, 1);
 
   med_2_1::med_int ngauss=0, numdt=-1, numo=-1, nbPdtIt=0; //nmaa=0
   char dtunit[MED_TAILLE_PNOM21+1], maa[MED_TAILLE_NOM+1];
@@ -437,6 +441,8 @@ MED_FIELD_DRIVER21<T>::createFieldSupport(med_2_1::med_idt id,
                                         (med_2_1::med_entite_maillage) entityCurrent,
                                         (med_2_1::med_geometrie_element)  *currentGeometry,
                                         j,maa,&ngauss,&numdt,dtunit,&dt,&numo);
+       
+       MED_FIELD_DRIVER<T>::_ptrField->setTime(dt); // PAL12664
 
        //          ret = med_2_2::MEDpasdetempsInfo(id, const_cast <char*> ( fieldName.c_str() ),
        //                                  (med_2_1::med_entite_maillage)   (*currentEntity).first,
@@ -479,12 +485,19 @@ MED_FIELD_DRIVER21<T>::createFieldSupport(med_2_1::med_idt id,
                                     << "| with (ndt,or) = ("
                                     << ndt << "," << od << ") for (entityType,geometricType)=("
                                     << MED_EN::entNames[entityCurrent] << ","
-                                    << MED_EN::geoNames[*currentGeometry] << ")" )); ;
+                                    << MED_EN::geoNames[*currentGeometry] << ")" ));
+      if ( ngauss > 1000 ) { // some gabage
+        INFOS( "Set to 1 invalid nb of Gauss points " << ngauss << " for  Field |" << fieldName
+               << "| with (ndt,or) = (" << ndt << "," << od << ") for (entityType,geometricType)=("
+               << MED_EN::entNames[entityCurrent] << ","
+               << MED_EN::geoNames[*currentGeometry] << ")" );
+        ngauss = 1;
+      }
 
       //totalNumberOfElements+=numberOfElements;
       numberOfElementsOfType[numberOfGeometricType] = numberOfElements/ngauss;
       numberOfGaussPoints[numberOfGeometricType] = ngauss;
-      anyGauss = (anyGauss || (ngauss-1) );
+      //anyGauss = (anyGauss || (ngauss-1) );
       geometricType[numberOfGeometricType]= *currentGeometry;
       numberOfGeometricType++;
 
@@ -582,8 +595,12 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void)
   const char * LOC = " MED_FIELD_RDONLY_DRIVER21::read() " ;
   BEGIN_OF(LOC);
 
-  typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array   ArrayNo;
-  typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull;
+  typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array       ArrayNo;
+  typedef typename MEDMEM_ArrayInterface<T,NoInterlace,Gauss>::Array         ArrayNoWg;
+  typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array     ArrayFull;
+  typedef typename MEDMEM_ArrayInterface<T,FullInterlace,Gauss>::Array       ArrayFullWg;
+  typedef typename MEDMEM_ArrayInterface<T,NoInterlaceByType,NoGauss>::Array ArrayByType;
+  typedef typename MEDMEM_ArrayInterface<T,NoInterlaceByType,Gauss>::Array   ArrayByTypeWg;
 
   if ( ( MED_FIELD_DRIVER<T>::_fieldName.empty()       ) &&
        ( MED_FIELD_DRIVER<T>::_ptrField->_name.empty() )    )
@@ -717,10 +734,11 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void)
   // (MED_MAILLE ou MED_NOEUD uniquement car MEDMEMOIRE ne gère pas la connectivité descendante).
   // et crée le support correspondant.
   SUPPORT * mySupport = new SUPPORT();
+  vector<int> numberOfGaussPoints;
   bool found = createFieldSupport(id,MED_FIELD_DRIVER<T>::_fieldName,
                                  MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber,
                                  MED_FIELD_DRIVER<T>::_ptrField->_orderNumber,
-                                 *mySupport, meshName) ;
+                                 *mySupport, numberOfGaussPoints, meshName) ;
   if ( !found ) {
     delete mySupport; delete[] componentName; delete[] unitName;
     MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ;
@@ -760,12 +778,12 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void)
   // Pour tester les profils aussi ?
   vector< MED_EN::medGeometryElement >  meshGeoType;
   vector< int >  meshNbOfElOfType;
-  getMeshGeometricType(id,meshName,mySupport->getEntity(),meshGeoType,meshNbOfElOfType);
-  vector < MED_EN::medGeometryElement > v1(  mySupport->getTypes(),
-                                            mySupport->getTypes()+mySupport->getNumberOfTypes() );
-  vector < int > v2(mySupport->getNumberOfElements(),
-                   mySupport->getNumberOfElements()+mySupport->getNumberOfTypes() );
-  if ( ( meshGeoType != v1 )  || meshNbOfElOfType != v2  ) {
+  MED_FIELD_DRIVER21<T>::getMeshGeometricType(id,meshName,mySupport->getEntity(),meshGeoType,meshNbOfElOfType);
+  vector<MED_EN::medGeometryElement> supGeoType(mySupport->getTypes(),
+                                                mySupport->getTypes()+mySupport->getNumberOfTypes());
+  vector < int > supNbOfElOfType(mySupport->getNumberOfElements(),
+                                 mySupport->getNumberOfElements()+mySupport->getNumberOfTypes() );
+  if ( ( meshGeoType != supGeoType )  || meshNbOfElOfType != supNbOfElOfType  ) {
     mySupport->setAll(false);
   }
 
@@ -784,9 +802,9 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void)
   for (int i=0; i<numberOfComponents; i++)
     {
       MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes[i] = 1 ;
-      MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i] = string(componentName,i*MED_TAILLE_PNOM21,MED_TAILLE_PNOM21) ;
+      MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i] = string(componentName+i*MED_TAILLE_PNOM21,MED_TAILLE_PNOM21) ;
       SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i]);
-      MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i] = string(unitName,i*MED_TAILLE_PNOM21,MED_TAILLE_PNOM21) ;
+      MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i] = string(unitName+i*MED_TAILLE_PNOM21,MED_TAILLE_PNOM21) ;
       SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i]);
     }
 
@@ -801,21 +819,44 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void)
   int TotalNumberOfValues = 0 ; // Profils a gerer en 2.2 Rmq from EF
   MESSAGE ("NumberOfTypes :"<< NumberOfTypes);
   MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues=0 ;
+  bool anyGauss=false;
+
+  MED_EN::medModeSwitch interlacingType = MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType();
+  bool isFullInterlace     = ( interlacingType == MED_EN::MED_FULL_INTERLACE );
+  bool isNoInterlaceByType = ( interlacingType == MED_EN::MED_NO_INTERLACE_BY_TYPE );//PAL17011
+
+  // PAL16681 (Read no interlace field from file) ->
+  // use medModeSwitch of a field in MEDMEMchampLire() if there is one geometric type
+  // to exclude array conversion
+  med_2_1::med_mode_switch modswt = med_2_1::MED_NO_INTERLACE;
+  // NOTE: field can be either of 3 medModeSwitch'es, MED_NO_INTERLACE_BY_TYPE added (PAL17011)
+  if ( NumberOfTypes == 1 && isFullInterlace )
+    modswt = med_2_1::MED_FULL_INTERLACE;
 
   for (int i=0; i<NumberOfTypes; i++) {
     MESSAGE ("Type["<<i+1<<"] :"<< Types[i]);
     MESSAGE ("Entity :"<< mySupport->getEntity());
 
-//     NumberOfValues[i] = 
-//       MEDnVal(MED_FIELD_DRIVER21<T>::_medIdt,
-//           const_cast <char*> (MED_FIELD_DRIVER<T>::_fieldName.c_str()),
-//           (med_2_1::med_entite_maillage)MED_FIELD_DRIVER<T>::_ptrField->_support->getEntity(),
-//           (med_2_1::med_geometrie_element)Types[i],
-//           MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber,
-//           MED_FIELD_DRIVER<T>::_ptrField->_orderNumber) ;
-
-    NumberOfValues[i] = mySupport->getNumberOfElements(Types[i])
-      * MED_FIELD_DRIVER<T>::_ptrField->getNumberOfGaussPoints(Types[i]);
+    int refNumberOfValues = 
+      MEDnVal(MED_FIELD_DRIVER21<T>::_medIdt,
+             const_cast <char*> (MED_FIELD_DRIVER<T>::_fieldName.c_str()),
+             (med_2_1::med_entite_maillage)mySupport->getEntity(),
+             (med_2_1::med_geometrie_element)Types[i],
+             MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber,
+             MED_FIELD_DRIVER<T>::_ptrField->_orderNumber);
+
+    NumberOfValues[i] = mySupport->getNumberOfElements(Types[i]) * numberOfGaussPoints[i];
+      // * MED_FIELD_DRIVER<T>::_ptrField->getNumberOfGaussPoints(Types[i]);
+
+    // protect against spoiling memory when reading field values
+    if ( NumberOfValues[i] < refNumberOfValues )
+      throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "  Too many values (" << refNumberOfValues
+                                  << ") in field |" << MED_FIELD_DRIVER<T>::_fieldName
+                                  << "| with (it,or) = ("
+                                  << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
+                                  << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), on mesh "
+                                  << meshName << "| while only " << NumberOfValues[i] 
+                                  << " values expected"));
 
     myValues[i] = new T[ NumberOfValues[i]*numberOfComponents ] ;
     TotalNumberOfValues+=NumberOfValues[i] ;
@@ -831,7 +872,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void)
     MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues+=mySupport->getNumberOfElements(Types[i]); // Ne doit pas prendre en compte les points de Gauss
 
     med_2_1::med_err ret;
-#if defined(IRIX64) || defined(OSF1) || defined(VPP5000)
+#if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) || defined(PCLINUX64_32)
     int lgth2=NumberOfValues[i]*numberOfComponents;
     if(MED_FIELD_DRIVER<T>::_ptrField->getValueType()==MED_EN::MED_INT32)
       {
@@ -839,7 +880,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void)
        ret=med_2_1::MEDchampLire(id,const_cast <char*> (meshName.c_str()),
                                  const_cast <char*> (MED_FIELD_DRIVER<T>::_fieldName.c_str()),
                                  (unsigned char*) temp,
-                                 med_2_1::MED_NO_INTERLACE,
+                                 modswt /*med_2_1::MED_NO_INTERLACE*/, // PAL16681,17011
                                  MED_ALL,
                                  ProfilName,
                                  (med_2_1::med_entite_maillage) mySupport->getEntity(),
@@ -856,7 +897,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void)
       ret=med_2_1::MEDchampLire(id,const_cast <char*> (meshName.c_str()),
                                const_cast <char*> (MED_FIELD_DRIVER<T>::_fieldName.c_str()),
                                (unsigned char*) myValues[i],
-                               med_2_1::MED_NO_INTERLACE,
+                                modswt /*med_2_1::MED_NO_INTERLACE*/, // PAL16681,17011
                                MED_ALL,
                                ProfilName,
                                (med_2_1::med_entite_maillage) mySupport->getEntity()
@@ -866,7 +907,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void)
                                ); 
     if (ret < 0)
       {
-      // The Field can't be read then we mustdelete all previously allocated members in FIELD
+      // The Field can't be read then we must delete all previously allocated members in FIELD
        for(int j=0; j<=i;j++)
          delete[] myValues[j];
        delete[] myValues;
@@ -887,55 +928,212 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void)
       }
 
     delete[] ProfilName ;
+
   }
   // allocate _value
-  // probleme avec les points de gauss : voir lorsqu-il y en a (!= 1)
-  // Creer un driver spécifique pour les modes MED_FULL_INTERLACE et MED_NO_INTERLACE
-  // serait plus efficicace.
-  ArrayNo * Values = new ArrayNo(numberOfComponents,TotalNumberOfValues);
+  MEDMEM_Array_ * Values;
+  if ( anyGauss ) {
+    vector<int> nbelgeoc( supNbOfElOfType.size()+1, 0 ), nbgaussgeo( supNbOfElOfType.size()+1, 0);
+    for ( int t = 0; t < NumberOfTypes; t++ ) {
+      nbelgeoc  [ t+1 ] = nbelgeoc  [ t ] + supNbOfElOfType    [ t ];
+      nbgaussgeo[ t+1 ] = /*nbgaussgeo[ t ] +*/ numberOfGaussPoints[ t ];
+    }
 
-  for (int i=0; i<numberOfComponents; i++)
+    // PAL16681. If NumberOfTypes == 1 then myValues[0] is what should be
+    // in a field value, i.e. no conversion needed
+    if ( NumberOfTypes == 1 )
     {
-      //T * ValuesT = Values->getRow(i+1) ;
-      int Count = 1 ;
-      for (int j=0; j<NumberOfTypes; j++)
-       {
-         T * myValue = myValues[j] ;
-         int NumberOf = NumberOfValues[j] ;
-         //      MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues+=NumberOf; // problem with gauss point : _numberOfValues != TotalNumberOfValues !!!!!!!
-         int offset = NumberOf*i ;
-         for (int k=0 ; k<NumberOf; k++) {
-           //ValuesT[Count]=myValue[k+offset] ;
-           Values->setIJ(Count,i+1,myValue[k+offset]);
-           //jfa 22.07.2005:SCRUTE(Count);
-           //jfa 22.07.2005:SCRUTE(Values->getIJ(Count,i+1));
-           Count++;
-         }
-       }
+      if ( isNoInterlaceByType ) // PAL17011
+        Values = new ArrayByTypeWg(myValues[0],
+                                   numberOfComponents,TotalNumberOfValues,NumberOfTypes,
+                                   &nbelgeoc[0], &nbgaussgeo[0],
+                                   true, //shallowCopy
+                                   true); // ownershipOfValues
+      else if ( !isFullInterlace )
+        Values = new ArrayNoWg(myValues[0],
+                               numberOfComponents,TotalNumberOfValues,NumberOfTypes,
+                               &nbelgeoc[0], &nbgaussgeo[0],
+                               true, true);
+      else
+        Values = new ArrayFullWg(myValues[0],
+                                 numberOfComponents,TotalNumberOfValues,NumberOfTypes,
+                                 &nbelgeoc[0], &nbgaussgeo[0],
+                                 true, true);
     }
-      
-  for (int j=0; j<NumberOfTypes; j++)
-    delete[] myValues[j] ;
+    else if ( isNoInterlaceByType )  // PAL17011
+    {
+      ArrayByTypeWg* aValues = new ArrayByTypeWg(numberOfComponents,TotalNumberOfValues,
+                                                 NumberOfTypes, &nbelgeoc[0], &nbgaussgeo[0]);
+      Values = aValues;
+      T * myValue = new T[ aValues->getArraySize() ];
+      int Count = 0 ;
+      for (int t=0; t<NumberOfTypes; t++)
+      {
+        int nbElem  = supNbOfElOfType[ t ];
+        int nbGauss = numberOfGaussPoints[ t ];
+        int tSize   = nbElem * nbGauss * numberOfComponents;
+        memcpy( myValue+Count, myValues[t], sizeof(T)*tSize );
+        Count += tSize;
+      }
+      aValues->setPtr( myValue, true, true );
+    }
+    else
+    {
+      ArrayNoWg* aValues = new ArrayNoWg(numberOfComponents,TotalNumberOfValues,NumberOfTypes,
+                                         &nbelgeoc[0], &nbgaussgeo[0]);
+      Values = aValues;
+      for (int j=1; j<=numberOfComponents; j++)
+      {
+        int Count = 1 ;
+        for (int t=0; t<NumberOfTypes; t++)
+        {
+          T * myValue = myValues[t] ;
+          int nbElem  = supNbOfElOfType[ t ];
+          int nbGauss = numberOfGaussPoints[ t ];
+          nbelgeoc[1] = nbElem;
+          nbgaussgeo[1] = nbGauss;
+          ArrayNoWg indexer( numberOfComponents, nbElem, 1, &nbelgeoc[0], &nbgaussgeo[0]);
+          for (int i=1; i<=nbElem; i++) {
+            for (int k=1 ; k<=nbGauss; k++)
+              aValues->setIJK( Count, j, k, myValue[ indexer.getIndex( i, j, k )]);
+            Count++;
+          }
+        }
+      }
+    }
+  }
+  else { // if ( anyGauss )
+
+    // PAL16681. If NumberOfTypes == 1 then myValues[0] is what should be
+    // in a field value, i.e. no conversion needed
+    vector<int> nbelgeoc( supNbOfElOfType.size()+1, 0 );
+    for ( int t = 0; t < NumberOfTypes; t++ ) 
+      nbelgeoc[ t+1 ] = nbelgeoc[ t ] + supNbOfElOfType[ t ];
+    if ( NumberOfTypes == 1 ) {
+      if ( isNoInterlaceByType ) // PAL17011
+        Values = new ArrayByType(myValues[0],numberOfComponents,TotalNumberOfValues,
+                                 NumberOfTypes, &nbelgeoc[0],
+                                 true, //shallowCopy
+                                 true); // ownershipOfValues
+      else if ( !isFullInterlace )
+        Values = new ArrayNo( myValues[0],numberOfComponents,TotalNumberOfValues,true, true);
+      else
+        Values = new ArrayFull( myValues[0],numberOfComponents,TotalNumberOfValues,true, true);
+    }
+    else if ( isNoInterlaceByType )  // PAL17011
+    {
+      ArrayByType* aValues = new ArrayByType(numberOfComponents,TotalNumberOfValues,
+                                             NumberOfTypes, &nbelgeoc[0]);
+      Values = aValues;
+      T * myValue = new T[ aValues->getArraySize() ];
+      int Count = 0 ;
+      for (int t=0; t<NumberOfTypes; t++)
+      {
+        int nbElem  = supNbOfElOfType[ t ];
+        int tSize   = nbElem * numberOfComponents;
+        memcpy( myValue+Count, myValues[t], sizeof(T)*tSize );
+        Count += tSize;
+      }
+      aValues->setPtr( myValue, true, true );
+    }
+    else {
+      ArrayNo* aValues = new ArrayNo(numberOfComponents,TotalNumberOfValues);
+      Values = aValues;
+
+      for (int i=0; i<numberOfComponents; i++)
+      {
+        //T * ValuesT = Values->getRow(i+1) ;
+        int Count = 1 ;
+        for (int j=0; j<NumberOfTypes; j++)
+        {
+          T * myValue = myValues[j] ;
+          int NumberOf = NumberOfValues[j] ;
+          int offset = NumberOf*i ;
+          for (int k=0 ; k<NumberOf; k++) {
+            //ValuesT[Count]=myValue[k+offset] ;
+            aValues->setIJ(Count,i+1,myValue[k+offset]);
+            Count++;
+          }
+        }
+      }
+    }
+  }
+   
+  // PAL16681. If NumberOfTypes == 1 then myValues[0] is used in field value
+  if ( NumberOfTypes != 1 )
+    for (int j=0; j<NumberOfTypes; j++)
+      delete[] myValues[j] ;
   delete[] myValues ;
   delete[] NumberOfValues ;
 
   if (MED_FIELD_DRIVER<T>::_ptrField->_value != NULL)
     delete MED_FIELD_DRIVER<T>::_ptrField->_value;
 
-  if ( MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE )
-    {
-      // dynamic_cast inutile
-      MED_FIELD_DRIVER<T>::_ptrField->_value=dynamic_cast<ArrayFull *>(ArrayConvert(*Values));
-      delete Values;
-    }
+  if ( NumberOfTypes != 1 &&  // PAL16681
+       isFullInterlace )
+  {
+    // Convert MED_NO_INTERLACE -> MED_FULL_INTERLACE
+    if (Values->getGaussPresence())
+      MED_FIELD_DRIVER<T>::_ptrField->_value=ArrayConvert(*static_cast<ArrayNoWg*>(Values));
+    else
+      MED_FIELD_DRIVER<T>::_ptrField->_value=ArrayConvert(*static_cast<ArrayNo*  >(Values));
+    delete Values;
+  }
   else
+  {
     MED_FIELD_DRIVER<T>::_ptrField->_value=Values;
-  
+  }
   MED_FIELD_DRIVER<T>::_ptrField->_isRead = true ;
 
   MED_FIELD_DRIVER<T>::_ptrField->_support=mySupport; //Prévenir l'utilisateur ?
+
+  // check support entity and isOnAllElements
+  if ( haveSupport && mySupport->getEntity() != MED_EN::MED_NODE ) {
+    // check if support geometry corresponds to support entity in mesh
+    MESH* mesh = mySupport->getMesh();
+    const MED_EN::medGeometryElement *meshGeoms, *endGeom, *foundGeom;
+    meshGeoms = mesh->getTypesWithPoly( mySupport->getEntity() );
+    endGeom = meshGeoms + mesh->getNumberOfTypesWithPoly( mySupport->getEntity() );
+    foundGeom = std::find( meshGeoms, endGeom, mySupport->getTypes()[ 0 ]);
+    bool geomFound = ( foundGeom != endGeom );
+    if ( !geomFound ) // support geom type is missing in types of the entity in mesh
+    { // find entity corresponding to support geom type in the mesh
+      MED_EN::MESH_ENTITIES::const_iterator ent_geoms = MED_EN::meshEntities.begin();
+      for ( ; ent_geoms != MED_EN::meshEntities.end(); ++ent_geoms ) {
+        if ( ent_geoms->first == mySupport->getEntity() )
+          continue;
+        if ( mesh->getNumberOfElementsWithPoly( ent_geoms->first, MED_EN::MED_ALL_ELEMENTS)) {
+          meshGeoms = mesh->getTypesWithPoly( ent_geoms->first );
+          endGeom = meshGeoms + mesh->getNumberOfTypesWithPoly( ent_geoms->first );
+          foundGeom = std::find( meshGeoms, endGeom, mySupport->getTypes()[ 0 ]);
+          if ( foundGeom != endGeom ) { // geom type found
+            mySupport->setEntity( ent_geoms->first );
+            break;
+          }
+        }
+      }
+    }
+    if ( !mySupport->isOnAllElements() ) {
+      // recheck isAll
+      meshGeoType = vector<MED_EN::medGeometryElement>(meshGeoms, endGeom);
+      bool isAll = ( meshGeoType == supGeoType );
+      for ( int i = 0; ( isAll && i < supGeoType.size()); ++i )
+        isAll = ( supNbOfElOfType[ i ] ==
+                  mesh->getNumberOfElementsWithPoly( mySupport->getEntity(), supGeoType[ i ]));
+      mySupport->setAll( isAll );
+    }
+    if ( !geomFound ) { // initial entity was wrong
+      // update support name
+      string supportName;
+      if ( mySupport->isOnAllElements() )
+        supportName = "SupportOnAll_" + MED_EN::entNames[ mySupport->getEntity() ];
+      else
+        supportName = MED_FIELD_DRIVER<T>::_fieldName + "_Support";
+      mySupport->setName( supportName );
+    }
+  }
       
-  END_OF(LOC);
+  //  END_OF(LOC);
 }
 
 template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::write( void ) const
@@ -965,7 +1163,10 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const
 
   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;
 
+  //if (MED_FIELD_DRIVER<T>::_status==MED_OPENED &&
+  //    MED_FIELD_DRIVER<T>::_ptrField->_isRead )
   if (MED_FIELD_DRIVER<T>::_status==MED_OPENED)
     {
       int err ;
@@ -975,7 +1176,11 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const
       string   component_unit(component_count*MED_TAILLE_PNOM21,' ') ;
 
       const string * listcomponent_name=MED_FIELD_DRIVER<T>::_ptrField->getComponentsNames() ;
-      const string * listcomponent_unit=MED_FIELD_DRIVER<T>::_ptrField->getMEDComponentsUnits() ;
+      const string * listcomponent_unit=MED_FIELD_DRIVER<T>::_ptrField->getMEDComponentsUnits();
+      if ( ! listcomponent_name || ! listcomponent_unit )
+        throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<" Udefined components of FIELD : "
+                                     << MED_FIELD_DRIVER<T>::_ptrField->getName() << "."));
+
       int length ;
       for (int i=0; i < component_count ; i++) {
        length = min(MED_TAILLE_PNOM21,(int)listcomponent_name[i].size());
@@ -1073,8 +1278,17 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const
 
       const T * value     = NULL;
       ArrayFull * myArray = NULL;
-      if ( MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE )
+
+      med_2_1::med_mode_switch       modswt = med_2_1::MED_FULL_INTERLACE;
+      MED_EN::medModeSwitch interlacingType = MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType();
+
+      if ( interlacingType == MED_EN::MED_FULL_INTERLACE ) {
        myArray = MED_FIELD_DRIVER<T>::_ptrField->getArrayNoGauss();
+      }
+      else if ( interlacingType == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { //PAL17011
+        // no need to convert, that is what this improvement is needed for
+        modswt = med_2_1::MED_NO_INTERLACE;
+      }
       else {
        // En attendant la convertion de FIELD, on utilise le ArrayConvert
        // ( les infos _ptrField-> sont les mêmes )
@@ -1083,15 +1297,18 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const
                                    ))
                                );
       }
-
       for (int i=0;i<NumberOfType;i++) {
        int NumberOfElements = mySupport->getNumberOfElements(Types[i]) ;
-       int NumberOfGaussPoints = MED_FIELD_DRIVER<T>::_ptrField->getNumberOfGaussPoints(Types[i]) ;
+        int NumberOfGaussPoints = MED_FIELD_DRIVER<T>::_ptrField->getNumberOfGaussPoints(Types[i]) ;
 
 //     const T * value = MED_FIELD_DRIVER<T>::_ptrField->getValueI(MED_EN::MED_FULL_INTERLACE,Index) ;
 
-       value = myArray->getRow(Index) ;
-       
+        if ( interlacingType == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { //PAL17011
+          value = MED_FIELD_DRIVER<T>::_ptrField->getValueByType(i+1);
+        }
+        else {
+          value = myArray->getRow(Index) ;
+       }
        MESSAGE("MED_FIELD_DRIVER21<T>::_medIdt                         : "<<MED_FIELD_DRIVER21<T>::_medIdt);
        MESSAGE("MeshName.c_str()                : "<<MeshName.c_str());
        MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getName()            : "<<MED_FIELD_DRIVER<T>::_ptrField->getName());
@@ -1123,10 +1340,10 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const
        cout<<"==================> nom unit lu       = "<<chaunit<<endl;
        cout<<"==================> valeur de med_2_1::MED_REEL64 = "<<med_2_1::MED_REEL64<<endl;
 */     
-#if defined(IRIX64) || defined(OSF1) || defined(VPP5000)
-       if(_ptrField->getValueType()==MED_EN::MED_INT32)
+#if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) || defined(PCLINUX64_32)
+       if(MED_FIELD_DRIVER<T>::_ptrField->getValueType()==MED_EN::MED_INT32)
          {
-           int lgth2=_ptrField->getNumberOfValues();
+           int lgth2=MED_FIELD_DRIVER<T>::_ptrField->getNumberOfValues();
            med_2_1::med_int *temp=new med_2_1::med_int[lgth2];
            for(int i2=0;i2<lgth2;i2++)
              temp[i2]=(int)(value[i2]);
@@ -1134,7 +1351,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const
                                    const_cast <char*> ( MeshName.c_str()) ,                         //( string(mesh_name).resize(MED_TAILLE_NOM).c_str())
                                    const_cast <char*> ( (MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()),
                                    (unsigned char*)temp, 
-                                   med_2_1::MED_FULL_INTERLACE,
+                                    modswt /*med_2_1::MED_FULL_INTERLACE*/, //PAL17011
                                    NumberOfElements,
                                    NumberOfGaussPoints,
                                    MED_ALL,
@@ -1155,7 +1372,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const
                                const_cast <char*> ( MeshName.c_str()) ,                         //( string(mesh_name).resize(MED_TAILLE_NOM).c_str())
                                const_cast <char*> ( (MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()),
                                (unsigned char*)value, 
-                               med_2_1::MED_FULL_INTERLACE,
+                                modswt /*med_2_1::MED_FULL_INTERLACE*/, //PAL17011
                                NumberOfElements,
                                NumberOfGaussPoints,
                                MED_ALL,