mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-01 03:37:15 -06:00
228 lines
9.6 KiB
C++
228 lines
9.6 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2017- Statoil 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 "RiuSummaryQuantityNameInfoProvider.h"
|
|
|
|
#include "RifEclipseSummaryAddress.h"
|
|
|
|
#include "cafAppEnum.h"
|
|
|
|
#include <regex>
|
|
#include <sstream>
|
|
|
|
// The region_to_region helper functions are taken from
|
|
// https://github.com/OPM/opm-common/blob/e1e0edba7da2d3b30f1f009511a62be073c27eb0/src/opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp#L317-L342
|
|
|
|
namespace ParseHelpers
|
|
{
|
|
bool is_supported_region_to_region( const std::string& keyword )
|
|
{
|
|
static const auto supported_kw = std::regex{ R"~~(R[OGW]F[RT][-+GL_]?([A-Z0-9_]{3})?)~~" };
|
|
|
|
// R[OGW]F[RT][-+GL]? (e.g., "ROFTG", "RGFR+", or "RWFT")
|
|
return std::regex_match( keyword, supported_kw );
|
|
}
|
|
|
|
bool is_unsupported_region_to_region( const std::string& keyword )
|
|
{
|
|
static const auto unsupported_kw = std::regex{ R"~~(R([EK]|NL)F[RT][-+_]?([A-Z0-9_]{3})?)~~" };
|
|
|
|
// R[EK]F[RT][-+]? (e.g., "REFT" or "RKFR+")
|
|
// RNLF[RT][-+]? (e.g., "RNLFR-" or "RNLFT")
|
|
return std::regex_match( keyword, unsupported_kw );
|
|
}
|
|
|
|
bool is_region_to_region( const std::string& keyword )
|
|
{
|
|
return is_supported_region_to_region( keyword ) || is_unsupported_region_to_region( keyword );
|
|
}
|
|
} // namespace ParseHelpers
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiuSummaryQuantityNameInfoProvider* RiuSummaryQuantityNameInfoProvider::instance()
|
|
{
|
|
static RiuSummaryQuantityNameInfoProvider theInstance;
|
|
|
|
return &theInstance;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RifEclipseSummaryAddressDefines::SummaryCategory RiuSummaryQuantityNameInfoProvider::identifyCategory( const std::string& vectorName )
|
|
{
|
|
// Try to an exact match on the vector name first in the vector table.
|
|
bool exactMatch = true;
|
|
auto exactCategory = categoryFromVectorName( vectorName, exactMatch );
|
|
if ( exactCategory != RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_INVALID ) return exactCategory;
|
|
|
|
if ( ( vectorName.size() < 3 || vectorName.size() > 8 ) && !vectorName.ends_with( RifEclipseSummaryAddressDefines::differenceIdentifier() ) )
|
|
return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_INVALID;
|
|
|
|
// Try to match the base vector name with more heuristics
|
|
auto strippedQuantityName = RifEclipseSummaryAddress::baseVectorName( vectorName );
|
|
|
|
// First, try to lookup vector in vector table
|
|
auto category = categoryFromVectorName( strippedQuantityName );
|
|
if ( category != RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_INVALID ) return category;
|
|
|
|
switch ( strippedQuantityName[0] )
|
|
{
|
|
case 'A':
|
|
return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_AQUIFER;
|
|
case 'B':
|
|
return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_BLOCK;
|
|
case 'F':
|
|
return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_FIELD;
|
|
case 'N':
|
|
return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_NETWORK;
|
|
case 'S':
|
|
return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_WELL_SEGMENT;
|
|
case 'W':
|
|
return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_WELL;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if ( strippedQuantityName[0] == 'R' )
|
|
{
|
|
if ( ParseHelpers::is_region_to_region( strippedQuantityName ) )
|
|
return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_REGION_2_REGION;
|
|
|
|
return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_REGION;
|
|
}
|
|
|
|
// Then check LGR categories
|
|
std::string firstTwoLetters = strippedQuantityName.substr( 0, 2 );
|
|
|
|
if ( firstTwoLetters == "LB" ) return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_BLOCK_LGR;
|
|
if ( firstTwoLetters == "LC" ) return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_WELL_COMPLETION_LGR;
|
|
if ( firstTwoLetters == "LW" ) return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_WELL_LGR;
|
|
|
|
return RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_INVALID;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RifEclipseSummaryAddressDefines::SummaryCategory RiuSummaryQuantityNameInfoProvider::categoryFromVectorName( const std::string& vectorName,
|
|
bool exactMatch ) const
|
|
{
|
|
auto info = quantityInfo( vectorName, exactMatch );
|
|
|
|
return info.category;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiuSummaryQuantityNameInfoProvider::RiuSummaryQuantityInfo RiuSummaryQuantityNameInfoProvider::quantityInfo( const std::string& vectorName,
|
|
bool exactMatch ) const
|
|
{
|
|
auto it = m_summaryToDescMap.find( vectorName );
|
|
if ( it != m_summaryToDescMap.end() )
|
|
{
|
|
return it->second;
|
|
}
|
|
|
|
// Stop searching if not found in lookup table and exact match was requested.
|
|
if ( exactMatch ) return RiuSummaryQuantityInfo();
|
|
|
|
if ( vectorName.size() > 1 && vectorName[1] == 'U' )
|
|
{
|
|
// User defined vector name
|
|
// The summary type is given by the first letter, and U defines user-defined
|
|
// FU : field user defined name
|
|
// WU : well user defined name
|
|
// .....
|
|
|
|
return RiuSummaryQuantityInfo();
|
|
}
|
|
|
|
if ( vectorName.size() > 5 )
|
|
{
|
|
// Check for custom vector naming
|
|
|
|
std::string postfix = vectorName.substr( vectorName.size() - 5, 5 );
|
|
std::string baseName = vectorName.substr( 0, 5 );
|
|
while ( baseName.back() == '_' )
|
|
baseName.pop_back();
|
|
|
|
bool isDifference = ( postfix == "_DIFF" );
|
|
|
|
it = m_summaryToDescMap.find( baseName );
|
|
|
|
if ( it != m_summaryToDescMap.end() )
|
|
{
|
|
if ( isDifference )
|
|
{
|
|
return RiuSummaryQuantityInfo( it->second.category, it->second.longName + " Difference" );
|
|
}
|
|
return it->second;
|
|
}
|
|
}
|
|
|
|
return RiuSummaryQuantityInfo();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::string RiuSummaryQuantityNameInfoProvider::longNameFromVectorName( const std::string& vectorName, bool returnVectorNameIfNotFound ) const
|
|
{
|
|
auto info = quantityInfo( vectorName );
|
|
return info.category != RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_INVALID || !returnVectorNameIfNotFound ? info.longName
|
|
: vectorName;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RiuSummaryQuantityNameInfoProvider::setQuantityInfos( const std::unordered_map<std::string, std::pair<std::string, std::string>>& infos )
|
|
{
|
|
for ( const auto& [key, content] : infos )
|
|
{
|
|
m_summaryToDescMap.insert( { key, { enumFromString( content.first ), content.second } } );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiuSummaryQuantityNameInfoProvider::RiuSummaryQuantityNameInfoProvider()
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::string RiuSummaryQuantityNameInfoProvider::stringFromEnum( RifEclipseSummaryAddressDefines::SummaryCategory category )
|
|
{
|
|
return caf::AppEnum<RifEclipseSummaryAddressDefines::SummaryCategory>::text( category ).toStdString();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RifEclipseSummaryAddressDefines::SummaryCategory RiuSummaryQuantityNameInfoProvider::enumFromString( const std::string& category )
|
|
{
|
|
return caf::AppEnum<RifEclipseSummaryAddressDefines::SummaryCategory>::fromText( QString::fromStdString( category ) );
|
|
}
|