From: eap Date: Wed, 4 Dec 2013 10:54:11 +0000 (+0000) Subject: 0022430: [CEA 1017] Memory corruption on sauv to med operation X-Git-Tag: V7_3_0b1~4 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=9eb549fe0bd44a474015050ad0de05b2f76a2e91;p=modules%2Fmed.git 0022430: [CEA 1017] Memory corruption on sauv to med operation Sort field sub-components by cell type to correspond to cell order after relocation - SauvUtilities::Group* getFieldSupport(const std::vector& fieldSupports); + void setFieldSupport(const std::vector& supports, + SauvUtilities::DoubleField* field); --- diff --git a/src/MEDLoader/SauvReader.cxx b/src/MEDLoader/SauvReader.cxx index 428658fc2..7c76e36cb 100644 --- a/src/MEDLoader/SauvReader.cxx +++ b/src/MEDLoader/SauvReader.cxx @@ -642,7 +642,8 @@ void SauvReader::read_PILE_COORDONNEES (const int nbObjects, std::vector& supports) +void SauvReader::setFieldSupport(const vector& supports, + SauvUtilities::DoubleField* field) { SauvUtilities::Group* group = NULL; set sup_set( supports.begin(), supports.end() ); @@ -652,19 +653,31 @@ SauvUtilities::Group* SauvReader::getFieldSupport(const vector_groups.size() && !group; ++i ) + // check if sub-components are on cells of different types + map 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::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 newGroups( supports.begin(), @@ -680,15 +693,67 @@ SauvUtilities::Group* SauvReader::getFieldSupport(const vector_groups.swap( newGroups ); } } + // sort field sub-components and supports by cell type + if ( group && !isSameCellType ) + { + // sort groups + vector& 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; diff --git a/src/MEDLoader/SauvReader.hxx b/src/MEDLoader/SauvReader.hxx index abf232a05..cb7b7e6b6 100644 --- a/src/MEDLoader/SauvReader.hxx +++ b/src/MEDLoader/SauvReader.hxx @@ -72,7 +72,8 @@ class SauvReader : public ParaMEDMEM::RefCountObject void read_PILE_MODL (const int nbObjects, std::vector& objectNames, std::vector& nameIndices); void read_PILE_FIELD (const int nbObjects, std::vector& objectNames, std::vector& nameIndices); - SauvUtilities::Group* getFieldSupport(const std::vector& fieldSupports); + void setFieldSupport(const std::vector& supports, + SauvUtilities::DoubleField* field); void setFieldNames(const std::vector& fields, const std::vector& objectNames, const std::vector& nameIndices);