///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2015- Statoil ASA // Copyright (C) 2015- Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ResInsight 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 General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #pragma once //================================================================================================== /// //================================================================================================== #include "RigFemPartCollection.h" #include "RigFemPartResultsCollection.h" #include "RigFemResultAddress.h" #include "RigGeoMechCaseData.h" #include "RigStatisticsCalculator.h" #include "cvfArray.h" class RigFemPartResultsCollection; class RigFemNativeVisibleCellsStatCalc : public RigStatisticsCalculator { public: RigFemNativeVisibleCellsStatCalc( RigGeoMechCaseData* femCase, const RigFemResultAddress& resVarAddr, const cvf::UByteArray* cellVisibilities ); void minMaxCellScalarValues( size_t timeStepIndex, double& min, double& max ) override; void posNegClosestToZero( size_t timeStepIndex, double& pos, double& neg ) override; void valueSumAndSampleCount( size_t timeStepIndex, double& valueSum, size_t& sampleCount ) override; void addDataToHistogramCalculator( size_t timeStepIndex, RigHistogramCalculator& histogramCalculator ) override; void uniqueValues( size_t timeStepIndex, std::set& values ) override; size_t timeStepCount() override; private: RigGeoMechCaseData* m_caseData; RigFemPartResultsCollection* m_resultsData; RigFemResultAddress m_resVarAddr; cvf::cref m_cellVisibilities; template void traverseElementNodes( StatisticsAccumulator& accumulator, size_t timeStepIndex ) { int partCount = m_caseData->femParts()->partCount(); for ( int pIdx = 0; pIdx < partCount; ++pIdx ) { RigFemPart* part = m_caseData->femParts()->part( pIdx ); int elmCount = part->elementCount(); m_resultsData->findOrLoadScalarResult( pIdx, m_resVarAddr ); auto [stepIdx, frameIdx] = m_resultsData->stepListIndexToTimeStepAndDataFrameIndex( timeStepIndex ); const std::vector& values = m_resultsData->resultValues( m_resVarAddr, pIdx, stepIdx, frameIdx ); if ( values.empty() ) continue; if ( m_resVarAddr.resultPosType == RIG_NODAL ) { size_t nodeCount = values.size(); cvf::UByteArray nodeVisibilities( nodeCount ); nodeVisibilities.setAll( false ); for ( int elmIdx = 0; elmIdx < elmCount; ++elmIdx ) { if ( !( *m_cellVisibilities )[elmIdx] ) continue; int elmNodeCount = RigFemTypes::elementNodeCount( part->elementType( elmIdx ) ); for ( int elmLocIdx = 0; elmLocIdx < elmNodeCount; ++elmLocIdx ) { size_t elmNodeResIdx = part->elementNodeResultIdx( elmIdx, elmLocIdx ); int nodeIdx = part->nodeIdxFromElementNodeResultIdx( elmNodeResIdx ); nodeVisibilities[nodeIdx] = true; } } for ( size_t nodeIdx = 0; nodeIdx < nodeCount; ++nodeIdx ) { if ( nodeVisibilities[nodeIdx] ) { accumulator.addValue( values[nodeIdx] ); } } } else if ( m_resVarAddr.resultPosType == RIG_ELEMENT ) { for ( int elmIdx = 0; elmIdx < elmCount; ++elmIdx ) { if ( !( *m_cellVisibilities )[elmIdx] ) continue; accumulator.addValue( values[elmIdx] ); } } else { for ( int elmIdx = 0; elmIdx < elmCount; ++elmIdx ) { if ( !( *m_cellVisibilities )[elmIdx] ) continue; int elmNodeCount = RigFemTypes::elementNodeCount( part->elementType( elmIdx ) ); for ( int elmLocIdx = 0; elmLocIdx < elmNodeCount; ++elmLocIdx ) { size_t elmNodeResIdx = part->elementNodeResultIdx( elmIdx, elmLocIdx ); accumulator.addValue( values[elmNodeResIdx] ); } } } } } };