Refactor: extract Allan diagram computation.

This commit is contained in:
Kristian Bendiksen 2023-04-19 10:15:48 +02:00
parent 9b78826f03
commit d11f51fcae
5 changed files with 198 additions and 141 deletions

View File

@ -6,6 +6,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RigIndexIjkResultCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RigOilVolumeResultCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RigCellVolumeResultCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RigAllanUtil.h
)
set(SOURCE_GROUP_SOURCE_FILES
@ -16,6 +17,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RigIndexIjkResultCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RigOilVolumeResultCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RigCellVolumeResultCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RigAllanUtil.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@ -0,0 +1,160 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023- Equinor ASA
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigAllanUtil.h"
#include "RigAllanDiagramData.h"
#include "RigCaseCellResultsData.h"
#include "RigFormationNames.h"
#include "RigMainGrid.h"
#include "RigNNCData.h"
#include "RigNncConnection.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigAllanUtil::computeAllanResults( RigCaseCellResultsData* cellResultsData, RigMainGrid* mainGrid, bool includeInactiveCells )
{
CVF_ASSERT( mainGrid );
CVF_ASSERT( cellResultsData );
if ( cellResultsData && cellResultsData->activeFormationNames() && !cellResultsData->activeFormationNames()->formationNames().empty() )
{
auto fnNamesResAddr =
RigEclipseResultAddress( RiaDefines::ResultCatType::FORMATION_NAMES, RiaResultNames::activeFormationNamesResultName() );
auto fnAllanResultResAddr =
RigEclipseResultAddress( RiaDefines::ResultCatType::ALLAN_DIAGRAMS, RiaResultNames::formationAllanResultName() );
auto fnBinAllanResAddr =
RigEclipseResultAddress( RiaDefines::ResultCatType::ALLAN_DIAGRAMS, RiaResultNames::formationBinaryAllanResultName() );
// Create and retrieve nnc result arrays
std::vector<double>& fnAllanNncResults =
mainGrid->nncData()->makeStaticConnectionScalarResult( RiaResultNames::formationAllanResultName() );
std::vector<double>& fnBinAllanNncResults =
mainGrid->nncData()->makeStaticConnectionScalarResult( RiaResultNames::formationBinaryAllanResultName() );
// Associate them with eclipse result address
mainGrid->nncData()->setEclResultAddress( RiaResultNames::formationAllanResultName(), fnAllanResultResAddr );
mainGrid->nncData()->setEclResultAddress( RiaResultNames::formationBinaryAllanResultName(), fnBinAllanResAddr );
const std::vector<double>& fnData = cellResultsData->cellScalarResults( fnNamesResAddr, 0 );
// Add a result entry for the special Allan grid data (used only for the grid cells without nnc coverage)
cellResultsData->addStaticScalarResult( RiaDefines::ResultCatType::ALLAN_DIAGRAMS,
RiaResultNames::formationAllanResultName(),
false,
fnData.size() );
cellResultsData->addStaticScalarResult( RiaDefines::ResultCatType::ALLAN_DIAGRAMS,
RiaResultNames::formationBinaryAllanResultName(),
false,
fnData.size() );
std::vector<double>* alData = cellResultsData->modifiableCellScalarResult( fnAllanResultResAddr, 0 );
std::vector<double>* binAlData = cellResultsData->modifiableCellScalarResult( fnBinAllanResAddr, 0 );
( *alData ) = fnData;
for ( double& val : ( *binAlData ) )
{
val = 0.0;
}
size_t formationCount = 0;
if ( cellResultsData->activeFormationNames() )
{
formationCount = cellResultsData->activeFormationNames()->formationNames().size();
}
const RigConnectionContainer& nncConnections = mainGrid->nncData()->allConnections();
std::map<std::pair<int, int>, int> formationCombinationToCategory;
for ( size_t i = 0; i < nncConnections.size(); i++ )
{
const auto& c = nncConnections[i];
size_t globCellIdx1 = c.c1GlobIdx();
size_t globCellIdx2 = c.c2GlobIdx();
int formation1 = (int)( fnData[globCellIdx1] );
int formation2 = (int)( fnData[globCellIdx2] );
int category = -1;
if ( formation1 != formation2 )
{
if ( formation1 < formation2 )
{
std::swap( formation1, formation2 );
}
auto formationCombination = std::make_pair( formation1, formation2 );
auto existingCategory = formationCombinationToCategory.find( formationCombination );
if ( existingCategory != formationCombinationToCategory.end() )
{
category = existingCategory->second;
}
else
{
category = static_cast<int>( formationCombinationToCategory.size() + formationCount );
formationCombinationToCategory[formationCombination] = category;
}
fnBinAllanNncResults[i] = 1.0;
}
else
{
category = formation1;
fnBinAllanNncResults[i] = 0.0;
}
fnAllanNncResults[i] = category;
}
cellResultsData->allanDiagramData()->setFormationCombinationToCategorymap( formationCombinationToCategory );
}
else
{
#if 0
for ( size_t i = 0; i < mainGrid->nncData()->connections().size(); i++ )
{
const auto& c = mainGrid->nncData()->connections()[i];
size_t globCellIdx1 = c.m_c1GlobIdx;
size_t globCellIdx2 = c.m_c2GlobIdx;
size_t i1, j1, k1;
mainGrid->ijkFromCellIndex( globCellIdx1, &i1, &j1, &k1 );
size_t i2, j2, k2;
mainGrid->ijkFromCellIndex( globCellIdx2, &i2, &j2, &k2 );
double binaryValue = 0.0;
if ( k1 != k2 )
{
binaryValue = 1.0;
}
fnAllanNncResults[i] = k1;
allAllanFormationResults[i] = k1;
fnBinAllanNncResults[i] = binaryValue;
}
#endif
}
}

View File

@ -0,0 +1,31 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023- Equinor ASA
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
class RigCaseCellResultsData;
class RigMainGrid;
//==================================================================================================
///
//==================================================================================================
class RigAllanUtil
{
public:
static void computeAllanResults( RigCaseCellResultsData* cellResultsData, RigMainGrid* mainGrid, bool includeInactiveCells );
};

View File

@ -27,6 +27,7 @@
#include "RiaResultNames.h"
#include "RigAllanDiagramData.h"
#include "RigAllanUtil.h"
#include "RigCaseCellResultCalculator.h"
#include "RigCellVolumeResultCalculator.h"
#include "RigEclipseAllanFaultsStatCalc.h"
@ -1258,7 +1259,7 @@ size_t RigCaseCellResultsData::findOrLoadKnownScalarResult( const RigEclipseResu
{
includeInactiveCells = m_readerInterface->includeInactiveCellsInFaultGeometry();
}
computeAllanResults( this, m_ownerMainGrid, includeInactiveCells );
RigAllanUtil::computeAllanResults( this, m_ownerMainGrid, includeInactiveCells );
}
else if ( resultName == RiaResultNames::indexIResultName() || resultName == RiaResultNames::indexJResultName() ||
resultName == RiaResultNames::indexKResultName() )
@ -1417,7 +1418,7 @@ size_t RigCaseCellResultsData::findOrLoadKnownScalarResult( const RigEclipseResu
includeInactiveCells = m_readerInterface->includeInactiveCellsInFaultGeometry();
}
computeAllanResults( this, m_ownerMainGrid, includeInactiveCells );
RigAllanUtil::computeAllanResults( this, m_ownerMainGrid, includeInactiveCells );
}
// Handle SourSimRL reading
@ -2846,141 +2847,6 @@ RigStatisticsDataCache* RigCaseCellResultsData::statistics( const RigEclipseResu
return m_statisticsDataCache[scalarResultIndex].p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigCaseCellResultsData::computeAllanResults( RigCaseCellResultsData* cellResultsData, RigMainGrid* mainGrid, bool includeInactiveCells )
{
CVF_ASSERT( mainGrid );
CVF_ASSERT( cellResultsData );
if ( cellResultsData && cellResultsData->activeFormationNames() && !cellResultsData->activeFormationNames()->formationNames().empty() )
{
auto fnNamesResAddr =
RigEclipseResultAddress( RiaDefines::ResultCatType::FORMATION_NAMES, RiaResultNames::activeFormationNamesResultName() );
auto fnAllanResultResAddr =
RigEclipseResultAddress( RiaDefines::ResultCatType::ALLAN_DIAGRAMS, RiaResultNames::formationAllanResultName() );
auto fnBinAllanResAddr =
RigEclipseResultAddress( RiaDefines::ResultCatType::ALLAN_DIAGRAMS, RiaResultNames::formationBinaryAllanResultName() );
// Create and retrieve nnc result arrays
std::vector<double>& fnAllanNncResults =
mainGrid->nncData()->makeStaticConnectionScalarResult( RiaResultNames::formationAllanResultName() );
std::vector<double>& fnBinAllanNncResults =
mainGrid->nncData()->makeStaticConnectionScalarResult( RiaResultNames::formationBinaryAllanResultName() );
// Associate them with eclipse result address
mainGrid->nncData()->setEclResultAddress( RiaResultNames::formationAllanResultName(), fnAllanResultResAddr );
mainGrid->nncData()->setEclResultAddress( RiaResultNames::formationBinaryAllanResultName(), fnBinAllanResAddr );
const std::vector<double>& fnData = cellResultsData->cellScalarResults( fnNamesResAddr, 0 );
// Add a result entry for the special Allan grid data (used only for the grid cells without nnc coverage)
cellResultsData->addStaticScalarResult( RiaDefines::ResultCatType::ALLAN_DIAGRAMS,
RiaResultNames::formationAllanResultName(),
false,
fnData.size() );
cellResultsData->addStaticScalarResult( RiaDefines::ResultCatType::ALLAN_DIAGRAMS,
RiaResultNames::formationBinaryAllanResultName(),
false,
fnData.size() );
std::vector<double>* alData = cellResultsData->modifiableCellScalarResult( fnAllanResultResAddr, 0 );
std::vector<double>* binAlData = cellResultsData->modifiableCellScalarResult( fnBinAllanResAddr, 0 );
( *alData ) = fnData;
for ( double& val : ( *binAlData ) )
{
val = 0.0;
}
size_t formationCount = 0;
if ( cellResultsData->activeFormationNames() )
{
formationCount = cellResultsData->activeFormationNames()->formationNames().size();
}
const RigConnectionContainer& nncConnections = mainGrid->nncData()->allConnections();
std::map<std::pair<int, int>, int> formationCombinationToCategory;
for ( size_t i = 0; i < nncConnections.size(); i++ )
{
const auto& c = nncConnections[i];
size_t globCellIdx1 = c.c1GlobIdx();
size_t globCellIdx2 = c.c2GlobIdx();
int formation1 = (int)( fnData[globCellIdx1] );
int formation2 = (int)( fnData[globCellIdx2] );
int category = -1;
if ( formation1 != formation2 )
{
if ( formation1 < formation2 )
{
std::swap( formation1, formation2 );
}
auto formationCombination = std::make_pair( formation1, formation2 );
auto existingCategory = formationCombinationToCategory.find( formationCombination );
if ( existingCategory != formationCombinationToCategory.end() )
{
category = existingCategory->second;
}
else
{
category = static_cast<int>( formationCombinationToCategory.size() + formationCount );
formationCombinationToCategory[formationCombination] = category;
}
fnBinAllanNncResults[i] = 1.0;
}
else
{
category = formation1;
fnBinAllanNncResults[i] = 0.0;
}
fnAllanNncResults[i] = category;
}
cellResultsData->allanDiagramData()->setFormationCombinationToCategorymap( formationCombinationToCategory );
}
else
{
#if 0
for ( size_t i = 0; i < mainGrid->nncData()->connections().size(); i++ )
{
const auto& c = mainGrid->nncData()->connections()[i];
size_t globCellIdx1 = c.m_c1GlobIdx;
size_t globCellIdx2 = c.m_c2GlobIdx;
size_t i1, j1, k1;
mainGrid->ijkFromCellIndex( globCellIdx1, &i1, &j1, &k1 );
size_t i2, j2, k2;
mainGrid->ijkFromCellIndex( globCellIdx2, &i2, &j2, &k2 );
double binaryValue = 0.0;
if ( k1 != k2 )
{
binaryValue = 1.0;
}
fnAllanNncResults[i] = k1;
allAllanFormationResults[i] = k1;
fnBinAllanNncResults[i] = binaryValue;
}
#endif
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -145,6 +145,8 @@ public:
void setStatisticsDataCacheNumBins( const RigEclipseResultAddress& resultAddress, size_t numBins );
size_t addStaticScalarResult( RiaDefines::ResultCatType type, const QString& resultName, bool needsToBeStored, size_t resultValueCount );
private:
size_t findOrLoadKnownScalarResult( const RigEclipseResultAddress& resVarAddr );
size_t findOrLoadKnownScalarResultByResultTypeOrder( const RigEclipseResultAddress& resVarAddr,
@ -165,8 +167,6 @@ private:
size_t findScalarResultIndexFromAddress( const RigEclipseResultAddress& resVarAddr ) const;
size_t addStaticScalarResult( RiaDefines::ResultCatType type, const QString& resultName, bool needsToBeStored, size_t resultValueCount );
const std::vector<RigEclipseResultInfo>& infoForEachResultIndex() const;
size_t resultCount() const;
@ -201,8 +201,6 @@ private:
RigStatisticsDataCache* statistics( const RigEclipseResultAddress& resVarAddr );
static void computeAllanResults( RigCaseCellResultsData* cellResultsData, RigMainGrid* mainGrid, bool includeInactiveCells );
private:
cvf::ref<RifReaderInterface> m_readerInterface;
cvf::cref<RigFormationNames> m_activeFormationNamesData;