]> SALOME platform Git repositories - modules/med.git/commitdiff
Salome HOME
0022430: [CEA 1017] Memory corruption on sauv to med operation
authoreap <eap@opencascade.com>
Wed, 4 Dec 2013 10:54:11 +0000 (10:54 +0000)
committereap <eap@opencascade.com>
Wed, 4 Dec 2013 10:54:11 +0000 (10:54 +0000)
Sort field sub-components by cell type to correspond to cell order
after relocation

-  SauvUtilities::Group* getFieldSupport(const std::vector<SauvUtilities::Group*>& fieldSupports);
+  void setFieldSupport(const std::vector<SauvUtilities::Group*>& supports,
+                       SauvUtilities::DoubleField*               field);

src/MEDLoader/SauvReader.cxx
src/MEDLoader/SauvReader.hxx

index 428658fc2cae707f48c8103f3d340056f3903230..7c76e36cb53991f0b233e3051ecda1da142ab820 100644 (file)
@@ -642,7 +642,8 @@ void SauvReader::read_PILE_COORDONNEES (const int nbObjects, std::vector<std::st
  */
 //================================================================================
 
-SauvUtilities::Group* SauvReader::getFieldSupport(const vector<SauvUtilities::Group*>& supports)
+void SauvReader::setFieldSupport(const vector<SauvUtilities::Group*>& supports,
+                                 SauvUtilities::DoubleField*          field)
 {
   SauvUtilities::Group* group = NULL;
   set<SauvUtilities::Group*> sup_set( supports.begin(), supports.end() );
@@ -652,19 +653,31 @@ SauvUtilities::Group* SauvReader::getFieldSupport(const vector<SauvUtilities::Gr
     }
   else
     {
-      // try to find an existing composite group with the same sub-groups
-      for ( size_t i = 0; i < _iMed->_groups.size() && !group; ++i )
+      // check if sub-components are on cells of different types
+      map<int,int> nbGaussByCellType;
+      for ( size_t i = 0; i < supports.size(); ++i )
         {
-          Group & grp = _iMed->_groups[i];
-          if (sup_set.size() == grp._groups.size())
-            {
-              bool sameOrder = true;
-              for ( size_t j = 0; j < supports.size() && sameOrder; ++j )
-                sameOrder = ( supports[j] == grp._groups[ j % grp._groups.size() ]);
-              if ( sameOrder )
-                group = & _iMed->_groups[i];
-            }
+          map<int,int>::iterator ct2ng = nbGaussByCellType.find( supports[i]->_cellType );
+          if ( ct2ng == nbGaussByCellType.end() )
+            nbGaussByCellType[ supports[i]->_cellType ] = field->_sub[i].nbGauss();
+          else if ( ct2ng->second != field->_sub[i].nbGauss() )
+            return;
         }
+      bool isSameCellType = ( nbGaussByCellType.size() == 1 );
+      // try to find an existing composite group with the same sub-groups
+      if ( isSameCellType )
+        for ( size_t i = 0; i < _iMed->_groups.size() && !group; ++i )
+          {
+            Group & grp = _iMed->_groups[i];
+            if (sup_set.size() == grp._groups.size())
+              {
+                bool sameOrder = true;
+                for ( size_t j = 0; j < supports.size() && sameOrder; ++j )
+                  sameOrder = ( supports[j] == grp._groups[ j % grp._groups.size() ]);
+                if ( sameOrder )
+                  group = & _iMed->_groups[i];
+              }
+          }
       if ( !group ) // no such a group, add a new one
         {
           vector<SauvUtilities::Group*> newGroups( supports.begin(),
@@ -680,15 +693,67 @@ SauvUtilities::Group* SauvReader::getFieldSupport(const vector<SauvUtilities::Gr
               group->_groups.swap( newGroups );
             }
         }
+      // sort field sub-components and supports by cell type
+      if ( group && !isSameCellType )
+        {
+          // sort groups
+          vector<SauvUtilities::Group*>& groups = group->_groups;
+          bool isModified = false, isSwapped = true;
+          while ( isSwapped )
+            {
+              isSwapped = false;
+              for ( size_t i = 1; i < groups.size(); ++i )
+                {
+                  int nbN1 = groups[i-1]->empty() ? 0 : groups[i-1]->_cells[0]->_nodes.size();
+                  int nbN2 = groups[i  ]->empty() ? 0 : groups[i  ]->_cells[0]->_nodes.size();
+                  if ( nbN1 > nbN2 )
+                    {
+                      isSwapped = isModified = true;
+                      std::swap( groups[i], groups[i-1] );
+                    }
+                }
+            }
+          // relocate sub-components according to a new order of groups
+          if ( isModified )
+            {
+              vector< DoubleField::_Sub_data > newSub( field->_sub.size() );
+              vector< vector< double > >       newValues( field->_comp_values.size() );
+              size_t iFromSub = 0, iNewSub = 0, iNewComp = 0;
+              for ( ; iFromSub < field->_sub.size(); iFromSub += groups.size() )
+                {
+                  size_t iFromComp = iNewComp;
+                  for ( size_t iG = 0; iG < groups.size(); ++iG )
+                    {
+                      size_t iComp = iFromComp;
+                      for ( size_t iSub = iFromSub; iSub < field->_sub.size(); ++iSub )
+                        if ( field->_sub[ iSub ]._support == groups[ iG ] )
+                          {
+                            newSub[ iNewSub++ ] = field->_sub[ iSub ];
+                            int iC = 0, nbC = field->_sub[ iSub ].nbComponents();
+                            for ( ; iC < nbC; ++iC )
+                              newValues[ iNewComp++ ].swap( field->_comp_values[ iComp++ ]);
+                            break;
+                          }
+                        else
+                          {
+                            iComp += field->_sub[ iSub ].nbComponents();
+                          }
+                    }
+                }
+              field->_sub.swap( newSub );
+              field->_comp_values.swap( newValues );
+            }
+        }
     }
   if ( group )
     group->_isProfile = true;
-  return group;
+
+  field->_group = group;
 }
 
 //================================================================================
 /*!
- * \brief set field names
+ * \brief Set field names
  */
 //================================================================================
 
@@ -813,7 +878,7 @@ void SauvReader::read_PILE_NODES_FIELD (const int                 nbObjects,
       // set a supporting group including all subs supports but only
       // if all subs have the same components
       if ( fdouble && fdouble->hasSameComponentsBySupport() )
-        fdouble->_group = getFieldSupport( supports );
+        setFieldSupport( supports, fdouble );
       else
         for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
           fdouble->_sub[ i_sub ]._support->_isProfile = true;
@@ -983,7 +1048,7 @@ void SauvReader::read_PILE_FIELD (const int                 nbObjects,
       // set id of a group including all sub supports but only
       // if all subs have the same nb of components
       if ( fdouble && fdouble->hasSameComponentsBySupport() )
-        fdouble->_group = getFieldSupport( supports );
+        setFieldSupport( supports, fdouble );
       else
         for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
           fdouble->_sub[ i_sub ]._support->_isProfile = true;
index abf232a05d3e741a518956216151ee1a024d8ed7..cb7b7e6b6e03e2de2039cf69aa28ee11ba20e1aa 100644 (file)
@@ -72,7 +72,8 @@ class SauvReader : public ParaMEDMEM::RefCountObject
   void read_PILE_MODL         (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices);
   void read_PILE_FIELD        (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices);
 
-  SauvUtilities::Group* getFieldSupport(const std::vector<SauvUtilities::Group*>& fieldSupports);
+  void setFieldSupport(const std::vector<SauvUtilities::Group*>& supports,
+                       SauvUtilities::DoubleField*               field);
   void setFieldNames(const std::vector<SauvUtilities::DoubleField*>& fields,
                      const std::vector<std::string>& objectNames,
                      const std::vector<int>& nameIndices);