mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Add result type and create and use custom legend if possible
* Update submodule * Use postfix functions and add custom color legend * Add type to RigEclipseResultAddress Read types from ROFF and create default legend based on type or custom created legend. * Use caseId to connect legend configuration to result in a case
This commit is contained in:
@@ -176,7 +176,10 @@ bool RifEclipseInputPropertyLoader::appendNewInputPropertyResult( RigEclipseCase
|
||||
return false;
|
||||
}
|
||||
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::INPUT_PROPERTY, resultName );
|
||||
bool endsWithNum = eclipseKeyword.ends_with( "NUM" );
|
||||
auto dataType = endsWithNum ? RiaDefines::ResultDataType::INTEGER : RiaDefines::ResultDataType::FLOAT;
|
||||
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::INPUT_PROPERTY, dataType, resultName );
|
||||
caseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->createResultEntry( resAddr, false );
|
||||
|
||||
auto newPropertyData = caseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->modifiableCellScalarResultTimesteps( resAddr );
|
||||
|
||||
@@ -56,58 +56,18 @@ RifEclipseOutputFileTools::~RifEclipseOutputFileTools()
|
||||
{
|
||||
}
|
||||
|
||||
struct KeywordItemCounter
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RifKeywordValueCount> RifEclipseOutputFileTools::keywordValueCounts( const std::vector<ecl_file_type*>& ecl_files )
|
||||
{
|
||||
KeywordItemCounter( const std::string& keyword, size_t aggregatedItemCount )
|
||||
: m_keyword( keyword )
|
||||
, m_aggregatedItemCount( aggregatedItemCount )
|
||||
, m_reportStepCount( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==( const std::string& rhs ) const { return this->m_keyword == rhs; }
|
||||
|
||||
std::string m_keyword;
|
||||
size_t m_aggregatedItemCount;
|
||||
size_t m_reportStepCount;
|
||||
};
|
||||
auto reportstepMetaData = RifEclipseOutputFileTools::createReportStepsMetaData( ecl_files );
|
||||
return reportstepMetaData.keywordValueCounts();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseOutputFileTools::findKeywordsAndItemCount( std::vector<ecl_file_type*> ecl_files,
|
||||
QStringList* resultNames,
|
||||
std::vector<size_t>* resultDataItemCounts )
|
||||
{
|
||||
std::vector<RifRestartReportStep> reportSteps;
|
||||
RifEclipseOutputFileTools::createReportStepsMetaData( ecl_files, &reportSteps );
|
||||
|
||||
std::vector<KeywordItemCounter> foundKeywords;
|
||||
|
||||
for ( auto reportStep : reportSteps )
|
||||
{
|
||||
for ( auto keywordItemCount : reportStep.m_keywords.keywordsWithAggregatedItemCount() )
|
||||
{
|
||||
auto it = std::find( foundKeywords.begin(), foundKeywords.end(), keywordItemCount.first );
|
||||
if ( it == foundKeywords.end() )
|
||||
{
|
||||
foundKeywords.push_back( KeywordItemCounter( keywordItemCount.first, keywordItemCount.second ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
it->m_aggregatedItemCount += keywordItemCount.second;
|
||||
it->m_reportStepCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto stdKeyword : foundKeywords )
|
||||
{
|
||||
resultNames->push_back( QString::fromStdString( stdKeyword.m_keyword ) );
|
||||
resultDataItemCounts->push_back( stdKeyword.m_aggregatedItemCount );
|
||||
}
|
||||
}
|
||||
|
||||
void getDayMonthYear( const ecl_kw_type* intehead_kw, int* day, int* month, int* year )
|
||||
{
|
||||
assert( day && month && year );
|
||||
@@ -636,9 +596,9 @@ FILE* RifEclipseOutputFileTools::fopen( const QString& filePath, const QString&
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseOutputFileTools::createReportStepsMetaData( std::vector<ecl_file_type*> ecl_files, std::vector<RifRestartReportStep>* reportSteps )
|
||||
RifRestartReportKeywords RifEclipseOutputFileTools::createReportStepsMetaData( const std::vector<ecl_file_type*>& ecl_files )
|
||||
{
|
||||
if ( !reportSteps ) return;
|
||||
RifRestartReportKeywords reportSteps;
|
||||
|
||||
for ( auto ecl_file : ecl_files )
|
||||
{
|
||||
@@ -658,15 +618,6 @@ void RifEclipseOutputFileTools::createReportStepsMetaData( std::vector<ecl_file_
|
||||
{
|
||||
ecl_file_select_block( ecl_file, INTEHEAD_KW, reportStepIndex );
|
||||
|
||||
RifRestartReportStep reportStep;
|
||||
|
||||
// Set Date
|
||||
{
|
||||
QDateTime reportDateTime =
|
||||
RiaQDateTimeTools::createDateTime( QDate( restart_header->year, restart_header->month, restart_header->day ) );
|
||||
reportStep.dateTime = reportDateTime;
|
||||
}
|
||||
|
||||
// Find number of keywords within this report step
|
||||
int numKeywords = ecl_file_get_num_distinct_kw( ecl_file );
|
||||
for ( int iKey = 0; iKey < numKeywords; iKey++ )
|
||||
@@ -676,19 +627,32 @@ void RifEclipseOutputFileTools::createReportStepsMetaData( std::vector<ecl_file_
|
||||
int namedKeywordCount = ecl_file_get_num_named_kw( ecl_file, kw );
|
||||
for ( int iOcc = 0; iOcc < namedKeywordCount; iOcc++ )
|
||||
{
|
||||
ecl_data_type dataType = ecl_file_iget_named_data_type( ecl_file, kw, iOcc );
|
||||
ecl_type_enum dataTypeEmum = ecl_type_get_type( dataType );
|
||||
if ( dataTypeEmum != ECL_DOUBLE_TYPE && dataTypeEmum != ECL_FLOAT_TYPE && dataTypeEmum != ECL_INT_TYPE )
|
||||
ecl_data_type dataTypeOnFile = ecl_file_iget_named_data_type( ecl_file, kw, iOcc );
|
||||
ecl_type_enum dataTypeEnumOnFile = ecl_type_get_type( dataTypeOnFile );
|
||||
if ( dataTypeEnumOnFile != ECL_DOUBLE_TYPE && dataTypeEnumOnFile != ECL_FLOAT_TYPE &&
|
||||
dataTypeEnumOnFile != ECL_INT_TYPE )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
RifKeywordValueCount::KeywordDataType dataType = RifKeywordValueCount::KeywordDataType::UNKNOWN;
|
||||
if ( dataTypeEnumOnFile == ECL_DOUBLE_TYPE )
|
||||
{
|
||||
dataType = RifKeywordValueCount::KeywordDataType::DOUBLE;
|
||||
}
|
||||
else if ( dataTypeEnumOnFile == ECL_FLOAT_TYPE )
|
||||
{
|
||||
dataType = RifKeywordValueCount::KeywordDataType::FLOAT;
|
||||
}
|
||||
else if ( dataTypeEnumOnFile == ECL_INT_TYPE )
|
||||
{
|
||||
dataType = RifKeywordValueCount::KeywordDataType::INTEGER;
|
||||
}
|
||||
|
||||
int itemCount = ecl_file_iget_named_size( ecl_file, kw, iOcc );
|
||||
reportStep.m_keywords.appendKeyword( kw, itemCount, iOcc );
|
||||
reportSteps.appendKeywordCount( kw, itemCount, dataType );
|
||||
}
|
||||
}
|
||||
|
||||
reportSteps->push_back( reportStep );
|
||||
}
|
||||
|
||||
ecl_file_pop_block( ecl_file );
|
||||
@@ -697,4 +661,6 @@ void RifEclipseOutputFileTools::createReportStepsMetaData( std::vector<ecl_file_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return reportSteps;
|
||||
}
|
||||
|
||||
@@ -48,8 +48,7 @@ public:
|
||||
RifEclipseOutputFileTools();
|
||||
virtual ~RifEclipseOutputFileTools();
|
||||
|
||||
static void
|
||||
findKeywordsAndItemCount( std::vector<ecl_file_type*> ecl_files, QStringList* resultNames, std::vector<size_t>* resultDataItemCounts );
|
||||
static std::vector<RifKeywordValueCount> keywordValueCounts( const std::vector<ecl_file_type*>& ecl_files );
|
||||
|
||||
static bool keywordData( const ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector<double>* values );
|
||||
static bool keywordData( const ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector<int>* values );
|
||||
@@ -87,5 +86,5 @@ public:
|
||||
static FILE* fopen( const QString& filePath, const QString& mode );
|
||||
|
||||
private:
|
||||
static void createReportStepsMetaData( std::vector<ecl_file_type*> ecl_files, std::vector<RifRestartReportStep>* reportSteps );
|
||||
static RifRestartReportKeywords createReportStepsMetaData( const std::vector<ecl_file_type*>& ecl_files );
|
||||
};
|
||||
|
||||
@@ -35,68 +35,40 @@ RifEclipseRestartDataAccess::~RifEclipseRestartDataAccess()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifRestartReportKeywords::RifRestartReportKeywords()
|
||||
void RifRestartReportKeywords::appendKeywordCount( const std::string& keyword, size_t valueCount, RifKeywordValueCount::KeywordDataType dataType )
|
||||
{
|
||||
}
|
||||
auto it = m_keywordValueCounts.find( keyword );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifRestartReportKeywords::appendKeyword( const std::string& keyword, size_t itemCount, int globalIndex )
|
||||
{
|
||||
m_keywordNameAndItemCount.push_back( RifKeywordLocation( keyword, itemCount, globalIndex ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<std::pair<std::string, size_t>> RifRestartReportKeywords::keywordsWithAggregatedItemCount()
|
||||
{
|
||||
std::vector<std::pair<std::string, size_t>> tmp;
|
||||
|
||||
for ( auto uni : uniqueKeywords() )
|
||||
if ( it == m_keywordValueCounts.end() )
|
||||
{
|
||||
size_t sum = 0;
|
||||
for ( auto loc : objectsForKeyword( uni ) )
|
||||
{
|
||||
sum += loc.itemCount();
|
||||
}
|
||||
|
||||
tmp.push_back( std::make_pair( uni, sum ) );
|
||||
m_keywordValueCounts[keyword] = RifKeywordValueCount( keyword, valueCount, dataType );
|
||||
}
|
||||
else
|
||||
{
|
||||
it->second.addValueCount( valueCount );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifRestartReportKeywords::appendKeywordCount( const RifRestartReportKeywords& other )
|
||||
{
|
||||
for ( const auto& [keyword, keywordInfo] : other.m_keywordValueCounts )
|
||||
{
|
||||
appendKeywordCount( keyword, keywordInfo.valueCount(), keywordInfo.dataType() );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RifKeywordValueCount> RifRestartReportKeywords::keywordValueCounts() const
|
||||
{
|
||||
std::vector<RifKeywordValueCount> tmp;
|
||||
for ( const auto& [keyword, info] : m_keywordValueCounts )
|
||||
{
|
||||
tmp.push_back( info );
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RifKeywordLocation> RifRestartReportKeywords::objectsForKeyword( const std::string& keyword )
|
||||
{
|
||||
std::vector<RifKeywordLocation> tmp;
|
||||
|
||||
for ( auto a : m_keywordNameAndItemCount )
|
||||
{
|
||||
if ( a.keyword() == keyword )
|
||||
{
|
||||
tmp.push_back( a );
|
||||
}
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<std::string> RifRestartReportKeywords::uniqueKeywords()
|
||||
{
|
||||
std::set<std::string> unique;
|
||||
|
||||
for ( auto a : m_keywordNameAndItemCount )
|
||||
{
|
||||
unique.insert( a.keyword() );
|
||||
}
|
||||
|
||||
return unique;
|
||||
}
|
||||
|
||||
@@ -31,50 +31,74 @@
|
||||
|
||||
#include "RifReaderInterface.h"
|
||||
|
||||
class RifKeywordLocation
|
||||
//==================================================================================================
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifKeywordValueCount
|
||||
{
|
||||
public:
|
||||
RifKeywordLocation( const std::string& keyword, size_t itemCount, int indexWithinReportStep )
|
||||
enum class KeywordDataType
|
||||
{
|
||||
UNKNOWN,
|
||||
FLOAT,
|
||||
DOUBLE,
|
||||
INTEGER,
|
||||
};
|
||||
|
||||
public:
|
||||
RifKeywordValueCount( const std::string& keyword, size_t itemCount, KeywordDataType dataType )
|
||||
: m_keyword( keyword )
|
||||
, m_itemCount( itemCount )
|
||||
, m_indexWithinReportStep( indexWithinReportStep )
|
||||
, m_valueCount( itemCount )
|
||||
, m_dataType( dataType )
|
||||
{
|
||||
}
|
||||
|
||||
std::string keyword() const { return m_keyword; }
|
||||
size_t itemCount() const { return m_itemCount; }
|
||||
int indexWithinReportStep() const { return m_indexWithinReportStep; }
|
||||
RifKeywordValueCount()
|
||||
: m_valueCount( 0 )
|
||||
, m_dataType( KeywordDataType::UNKNOWN )
|
||||
{
|
||||
}
|
||||
|
||||
void addValueCount( size_t valueCount ) { m_valueCount += valueCount; }
|
||||
|
||||
std::string keyword() const { return m_keyword; }
|
||||
size_t valueCount() const { return m_valueCount; }
|
||||
KeywordDataType dataType() const { return m_dataType; }
|
||||
|
||||
static RiaDefines::ResultDataType mapType( RifKeywordValueCount::KeywordDataType dataType )
|
||||
{
|
||||
switch ( dataType )
|
||||
{
|
||||
case RifKeywordValueCount::KeywordDataType::FLOAT:
|
||||
return RiaDefines::ResultDataType::FLOAT;
|
||||
case RifKeywordValueCount::KeywordDataType::DOUBLE:
|
||||
return RiaDefines::ResultDataType::DOUBLE;
|
||||
case RifKeywordValueCount::KeywordDataType::INTEGER:
|
||||
return RiaDefines::ResultDataType::INTEGER;
|
||||
}
|
||||
|
||||
return RiaDefines::ResultDataType::UNKNOWN;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_keyword;
|
||||
size_t m_itemCount;
|
||||
int m_indexWithinReportStep;
|
||||
std::string m_keyword;
|
||||
size_t m_valueCount;
|
||||
KeywordDataType m_dataType;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifRestartReportKeywords
|
||||
{
|
||||
public:
|
||||
RifRestartReportKeywords();
|
||||
void appendKeywordCount( const RifRestartReportKeywords& other );
|
||||
void appendKeywordCount( const std::string& keyword, size_t valueCount, RifKeywordValueCount::KeywordDataType dataType );
|
||||
|
||||
void appendKeyword( const std::string& keyword, size_t itemCount, int globalIndex );
|
||||
|
||||
std::vector<std::pair<std::string, size_t>> keywordsWithAggregatedItemCount();
|
||||
std::vector<RifKeywordValueCount> keywordValueCounts() const;
|
||||
|
||||
private:
|
||||
std::vector<RifKeywordLocation> objectsForKeyword( const std::string& keyword );
|
||||
std::set<std::string> uniqueKeywords();
|
||||
|
||||
private:
|
||||
std::vector<RifKeywordLocation> m_keywordNameAndItemCount;
|
||||
};
|
||||
|
||||
class RifRestartReportStep
|
||||
{
|
||||
public:
|
||||
// int globalIndex;
|
||||
QDateTime dateTime;
|
||||
|
||||
RifRestartReportKeywords m_keywords;
|
||||
std::map<std::string, RifKeywordValueCount> m_keywordValueCounts;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
@@ -97,7 +121,7 @@ public:
|
||||
virtual void timeSteps( std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart ) = 0;
|
||||
virtual std::vector<int> reportNumbers() = 0;
|
||||
|
||||
virtual void resultNames( QStringList* resultNames, std::vector<size_t>* resultDataItemCounts ) = 0;
|
||||
virtual std::vector<RifKeywordValueCount> keywordValueCounts() = 0;
|
||||
virtual bool results( const QString& resultName, size_t timeStep, size_t gridCount, std::vector<double>* values ) = 0;
|
||||
|
||||
virtual bool dynamicNNCResults( const ecl_grid_type* grid,
|
||||
|
||||
@@ -158,7 +158,7 @@ void RifEclipseRestartFilesetAccess::timeSteps( std::vector<QDateTime>* timeStep
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get list of result names
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseRestartFilesetAccess::resultNames( QStringList* resultNames, std::vector<size_t>* resultDataItemCounts )
|
||||
std::vector<RifKeywordValueCount> RifEclipseRestartFilesetAccess::keywordValueCounts()
|
||||
{
|
||||
CVF_ASSERT( timeStepCount() > 0 );
|
||||
|
||||
@@ -167,7 +167,7 @@ void RifEclipseRestartFilesetAccess::resultNames( QStringList* resultNames, std:
|
||||
openTimeStep( i );
|
||||
}
|
||||
|
||||
RifEclipseOutputFileTools::findKeywordsAndItemCount( m_ecl_files, resultNames, resultDataItemCounts );
|
||||
return RifEclipseOutputFileTools::keywordValueCounts( m_ecl_files );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
void timeSteps( std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart ) override;
|
||||
std::vector<int> reportNumbers() override;
|
||||
|
||||
void resultNames( QStringList* resultNames, std::vector<size_t>* resultDataItemCounts ) override;
|
||||
std::vector<RifKeywordValueCount> keywordValueCounts() override;
|
||||
bool results( const QString& resultName, size_t timeStep, size_t gridCount, std::vector<double>* values ) override;
|
||||
|
||||
bool dynamicNNCResults( const ecl_grid_type* grid,
|
||||
|
||||
@@ -223,15 +223,17 @@ void RifEclipseUnifiedRestartFileAccess::timeSteps( std::vector<QDateTime>* time
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get list of result names
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseUnifiedRestartFileAccess::resultNames( QStringList* resultNames, std::vector<size_t>* resultDataItemCounts )
|
||||
std::vector<RifKeywordValueCount> RifEclipseUnifiedRestartFileAccess::keywordValueCounts()
|
||||
{
|
||||
if ( openFile() )
|
||||
{
|
||||
std::vector<ecl_file_type*> filesUsedToFindAvailableKeywords;
|
||||
filesUsedToFindAvailableKeywords.push_back( m_ecl_file );
|
||||
|
||||
RifEclipseOutputFileTools::findKeywordsAndItemCount( filesUsedToFindAvailableKeywords, resultNames, resultDataItemCounts );
|
||||
return RifEclipseOutputFileTools::keywordValueCounts( filesUsedToFindAvailableKeywords );
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
void timeSteps( std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart ) override;
|
||||
std::vector<int> reportNumbers() override;
|
||||
|
||||
void resultNames( QStringList* resultNames, std::vector<size_t>* resultDataItemCounts ) override;
|
||||
std::vector<RifKeywordValueCount> keywordValueCounts() override;
|
||||
bool results( const QString& resultName, size_t timeStep, size_t gridCount, std::vector<double>* values ) override;
|
||||
|
||||
bool dynamicNNCResults( const ecl_grid_type* grid,
|
||||
|
||||
@@ -922,39 +922,37 @@ void RifReaderEclipseOutput::buildMetaData( ecl_grid_type* grid )
|
||||
|
||||
timeStepInfos = createFilteredTimeStepInfos();
|
||||
|
||||
QStringList resultNames;
|
||||
std::vector<size_t> resultNamesDataItemCounts;
|
||||
m_dynamicResultsAccess->resultNames( &resultNames, &resultNamesDataItemCounts );
|
||||
auto keywordValueCounts = m_dynamicResultsAccess->keywordValueCounts();
|
||||
|
||||
{
|
||||
QStringList matrixResultNames =
|
||||
validKeywordsForPorosityModel( resultNames,
|
||||
resultNamesDataItemCounts,
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
||||
RiaDefines::PorosityModelType::MATRIX_MODEL,
|
||||
m_dynamicResultsAccess->timeStepCount() );
|
||||
auto validKeywords = validKeywordsForPorosityModel( keywordValueCounts,
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
||||
RiaDefines::PorosityModelType::MATRIX_MODEL,
|
||||
m_dynamicResultsAccess->timeStepCount() );
|
||||
|
||||
for ( int i = 0; i < matrixResultNames.size(); ++i )
|
||||
for ( const auto& keywordData : validKeywords )
|
||||
{
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::DYNAMIC_NATIVE, matrixResultNames[i] );
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::DYNAMIC_NATIVE,
|
||||
RifKeywordValueCount::mapType( keywordData.dataType() ),
|
||||
QString::fromStdString( keywordData.keyword() ) );
|
||||
matrixModelResults->createResultEntry( resAddr, false );
|
||||
matrixModelResults->setTimeStepInfos( resAddr, timeStepInfos );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
QStringList fractureResultNames =
|
||||
validKeywordsForPorosityModel( resultNames,
|
||||
resultNamesDataItemCounts,
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
||||
RiaDefines::PorosityModelType::FRACTURE_MODEL,
|
||||
m_dynamicResultsAccess->timeStepCount() );
|
||||
auto validKeywords = validKeywordsForPorosityModel( keywordValueCounts,
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
||||
RiaDefines::PorosityModelType::FRACTURE_MODEL,
|
||||
m_dynamicResultsAccess->timeStepCount() );
|
||||
|
||||
for ( int i = 0; i < fractureResultNames.size(); ++i )
|
||||
for ( const auto& keywordData : validKeywords )
|
||||
{
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::DYNAMIC_NATIVE, fractureResultNames[i] );
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::DYNAMIC_NATIVE,
|
||||
RifKeywordValueCount::mapType( keywordData.dataType() ),
|
||||
QString::fromStdString( keywordData.keyword() ) );
|
||||
fractureModelResults->createResultEntry( resAddr, false );
|
||||
fractureModelResults->setTimeStepInfos( resAddr, timeStepInfos );
|
||||
}
|
||||
@@ -1002,12 +1000,10 @@ void RifReaderEclipseOutput::buildMetaData( ecl_grid_type* grid )
|
||||
|
||||
if ( m_ecl_init_file )
|
||||
{
|
||||
QStringList resultNames;
|
||||
std::vector<size_t> resultNamesDataItemCounts;
|
||||
std::vector<ecl_file_type*> filesUsedToFindAvailableKeywords;
|
||||
filesUsedToFindAvailableKeywords.push_back( m_ecl_init_file );
|
||||
|
||||
RifEclipseOutputFileTools::findKeywordsAndItemCount( filesUsedToFindAvailableKeywords, &resultNames, &resultNamesDataItemCounts );
|
||||
auto keywordInfo = RifEclipseOutputFileTools::keywordValueCounts( filesUsedToFindAvailableKeywords );
|
||||
|
||||
std::vector<RigEclipseTimeStepInfo> staticTimeStepInfo;
|
||||
if ( !timeStepInfos.empty() )
|
||||
@@ -1016,39 +1012,37 @@ void RifReaderEclipseOutput::buildMetaData( ecl_grid_type* grid )
|
||||
}
|
||||
|
||||
{
|
||||
QStringList matrixResultNames =
|
||||
validKeywordsForPorosityModel( resultNames,
|
||||
resultNamesDataItemCounts,
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
||||
RiaDefines::PorosityModelType::MATRIX_MODEL,
|
||||
1 );
|
||||
auto validKeywords = validKeywordsForPorosityModel( keywordInfo,
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
||||
RiaDefines::PorosityModelType::MATRIX_MODEL,
|
||||
1 );
|
||||
|
||||
// Add ACTNUM
|
||||
matrixResultNames += "ACTNUM";
|
||||
validKeywords.push_back( RifKeywordValueCount( "ACTNUM", 0, RifKeywordValueCount::KeywordDataType::INTEGER ) );
|
||||
|
||||
for ( int i = 0; i < matrixResultNames.size(); ++i )
|
||||
for ( const auto& keywordData : validKeywords )
|
||||
{
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::STATIC_NATIVE, matrixResultNames[i] );
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::STATIC_NATIVE,
|
||||
RifKeywordValueCount::mapType( keywordData.dataType() ),
|
||||
QString::fromStdString( keywordData.keyword() ) );
|
||||
matrixModelResults->createResultEntry( resAddr, false );
|
||||
matrixModelResults->setTimeStepInfos( resAddr, staticTimeStepInfo );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
QStringList fractureResultNames =
|
||||
validKeywordsForPorosityModel( resultNames,
|
||||
resultNamesDataItemCounts,
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
||||
RiaDefines::PorosityModelType::FRACTURE_MODEL,
|
||||
1 );
|
||||
// Add ACTNUM
|
||||
fractureResultNames += "ACTNUM";
|
||||
auto validKeywords = validKeywordsForPorosityModel( keywordInfo,
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ),
|
||||
m_eclipseCase->activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ),
|
||||
RiaDefines::PorosityModelType::FRACTURE_MODEL,
|
||||
1 );
|
||||
validKeywords.push_back( RifKeywordValueCount( "ACTNUM", 0, RifKeywordValueCount::KeywordDataType::INTEGER ) );
|
||||
|
||||
for ( int i = 0; i < fractureResultNames.size(); ++i )
|
||||
for ( const auto& keywordData : validKeywords )
|
||||
{
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::STATIC_NATIVE, fractureResultNames[i] );
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::STATIC_NATIVE,
|
||||
RifKeywordValueCount::mapType( keywordData.dataType() ),
|
||||
QString::fromStdString( keywordData.keyword() ) );
|
||||
fractureModelResults->createResultEntry( resAddr, false );
|
||||
fractureModelResults->setTimeStepInfos( resAddr, staticTimeStepInfo );
|
||||
}
|
||||
@@ -2110,60 +2104,55 @@ void RifReaderEclipseOutput::readWellCells( const ecl_grid_type* mainEclGrid, bo
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel( const QStringList& keywords,
|
||||
const std::vector<size_t>& keywordDataItemCounts,
|
||||
const RigActiveCellInfo* matrixActiveCellInfo,
|
||||
const RigActiveCellInfo* fractureActiveCellInfo,
|
||||
RiaDefines::PorosityModelType porosityModel,
|
||||
size_t timeStepCount ) const
|
||||
std::vector<RifKeywordValueCount>
|
||||
RifReaderEclipseOutput::validKeywordsForPorosityModel( const std::vector<RifKeywordValueCount>& keywordItemCounts,
|
||||
const RigActiveCellInfo* matrixActiveCellInfo,
|
||||
const RigActiveCellInfo* fractureActiveCellInfo,
|
||||
RiaDefines::PorosityModelType porosityModel,
|
||||
size_t timeStepCount ) const
|
||||
{
|
||||
CVF_ASSERT( matrixActiveCellInfo );
|
||||
|
||||
if ( keywords.size() != static_cast<int>( keywordDataItemCounts.size() ) )
|
||||
{
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
if ( porosityModel == RiaDefines::PorosityModelType::FRACTURE_MODEL )
|
||||
{
|
||||
if ( fractureActiveCellInfo->reservoirActiveCellCount() == 0 )
|
||||
{
|
||||
return QStringList();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
QStringList keywordsWithCorrectNumberOfDataItems;
|
||||
std::vector<RifKeywordValueCount> keywordsWithCorrectNumberOfDataItems;
|
||||
|
||||
for ( int i = 0; i < keywords.size(); i++ )
|
||||
for ( const auto& keywordValueCount : keywordItemCounts )
|
||||
{
|
||||
QString keyword = keywords[i];
|
||||
size_t keywordDataItemCount = keywordDataItemCounts[i];
|
||||
QString keyword = QString::fromStdString( keywordValueCount.keyword() );
|
||||
size_t valueCount = keywordValueCount.valueCount();
|
||||
|
||||
bool validKeyword = false;
|
||||
|
||||
size_t timeStepsAllCellsRest = keywordDataItemCount % matrixActiveCellInfo->reservoirCellCount();
|
||||
if ( timeStepsAllCellsRest == 0 && keywordDataItemCount <= timeStepCount * matrixActiveCellInfo->reservoirCellCount() )
|
||||
size_t timeStepsAllCellsRest = valueCount % matrixActiveCellInfo->reservoirCellCount();
|
||||
if ( timeStepsAllCellsRest == 0 && valueCount <= timeStepCount * matrixActiveCellInfo->reservoirCellCount() )
|
||||
{
|
||||
// Found result for all cells for N time steps, usually a static dataset for one time step
|
||||
validKeyword = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t timeStepsMatrixRest = keywordDataItemCount % matrixActiveCellInfo->reservoirActiveCellCount();
|
||||
size_t timeStepsMatrixRest = valueCount % matrixActiveCellInfo->reservoirActiveCellCount();
|
||||
|
||||
size_t timeStepsFractureRest = 0;
|
||||
if ( fractureActiveCellInfo->reservoirActiveCellCount() > 0 )
|
||||
{
|
||||
timeStepsFractureRest = keywordDataItemCount % fractureActiveCellInfo->reservoirActiveCellCount();
|
||||
timeStepsFractureRest = valueCount % fractureActiveCellInfo->reservoirActiveCellCount();
|
||||
}
|
||||
|
||||
size_t sumFractureMatrixActiveCellCount = matrixActiveCellInfo->reservoirActiveCellCount() +
|
||||
fractureActiveCellInfo->reservoirActiveCellCount();
|
||||
size_t timeStepsMatrixAndFractureRest = keywordDataItemCount % sumFractureMatrixActiveCellCount;
|
||||
size_t timeStepsMatrixAndFractureRest = valueCount % sumFractureMatrixActiveCellCount;
|
||||
|
||||
if ( porosityModel == RiaDefines::PorosityModelType::MATRIX_MODEL && timeStepsMatrixRest == 0 )
|
||||
{
|
||||
if ( keywordDataItemCount <=
|
||||
if ( valueCount <=
|
||||
timeStepCount * std::max( matrixActiveCellInfo->reservoirActiveCellCount(), sumFractureMatrixActiveCellCount ) )
|
||||
{
|
||||
validKeyword = true;
|
||||
@@ -2172,7 +2161,7 @@ QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel( const QString
|
||||
else if ( porosityModel == RiaDefines::PorosityModelType::FRACTURE_MODEL &&
|
||||
fractureActiveCellInfo->reservoirActiveCellCount() > 0 && timeStepsFractureRest == 0 )
|
||||
{
|
||||
if ( keywordDataItemCount <=
|
||||
if ( valueCount <=
|
||||
timeStepCount * std::max( fractureActiveCellInfo->reservoirActiveCellCount(), sumFractureMatrixActiveCellCount ) )
|
||||
{
|
||||
validKeyword = true;
|
||||
@@ -2180,7 +2169,7 @@ QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel( const QString
|
||||
}
|
||||
else if ( timeStepsMatrixAndFractureRest == 0 )
|
||||
{
|
||||
if ( keywordDataItemCount <= timeStepCount * sumFractureMatrixActiveCellCount )
|
||||
if ( valueCount <= timeStepCount * sumFractureMatrixActiveCellCount )
|
||||
{
|
||||
validKeyword = true;
|
||||
}
|
||||
@@ -2195,8 +2184,8 @@ QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel( const QString
|
||||
size_t mainGridMatrixActiveCellCount = matrixActiveCellInfo->gridActiveCellCounts( 0 );
|
||||
size_t mainGridFractureActiveCellCount = fractureActiveCellInfo->gridActiveCellCounts( 0 );
|
||||
|
||||
if ( keywordDataItemCount == mainGridMatrixActiveCellCount || keywordDataItemCount == mainGridFractureActiveCellCount ||
|
||||
keywordDataItemCount == mainGridMatrixActiveCellCount + mainGridFractureActiveCellCount )
|
||||
if ( valueCount == mainGridMatrixActiveCellCount || valueCount == mainGridFractureActiveCellCount ||
|
||||
valueCount == mainGridMatrixActiveCellCount + mainGridFractureActiveCellCount )
|
||||
{
|
||||
validKeyword = true;
|
||||
}
|
||||
@@ -2205,7 +2194,7 @@ QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel( const QString
|
||||
|
||||
if ( validKeyword )
|
||||
{
|
||||
keywordsWithCorrectNumberOfDataItems.push_back( keyword );
|
||||
keywordsWithCorrectNumberOfDataItems.push_back( keywordValueCount );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ class RigEclipseTimeStepInfo;
|
||||
class RigGridBase;
|
||||
class RigMainGrid;
|
||||
class QDateTime;
|
||||
class RifKeywordValueCount;
|
||||
|
||||
struct RigWellResultPoint;
|
||||
|
||||
@@ -113,12 +114,11 @@ private:
|
||||
|
||||
void ensureDynamicResultAccessIsPresent();
|
||||
|
||||
QStringList validKeywordsForPorosityModel( const QStringList& keywords,
|
||||
const std::vector<size_t>& keywordDataItemCounts,
|
||||
const RigActiveCellInfo* activeCellInfo,
|
||||
const RigActiveCellInfo* fractureActiveCellInfo,
|
||||
RiaDefines::PorosityModelType matrixOrFracture,
|
||||
size_t timeStepCount ) const;
|
||||
std::vector<RifKeywordValueCount> validKeywordsForPorosityModel( const std::vector<RifKeywordValueCount>& keywordItemCounts,
|
||||
const RigActiveCellInfo* activeCellInfo,
|
||||
const RigActiveCellInfo* fractureActiveCellInfo,
|
||||
RiaDefines::PorosityModelType matrixOrFracture,
|
||||
size_t timeStepCount ) const;
|
||||
|
||||
std::vector<RigEclipseTimeStepInfo> createFilteredTimeStepInfos();
|
||||
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "RimColorLegendCollection.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
#include "cafProgressInfo.h"
|
||||
|
||||
#include <chrono>
|
||||
@@ -147,10 +151,10 @@ bool RifRoffFileTools::openGridFile( const QString& fileName, RigEclipseCaseData
|
||||
RiaLogging::info( QString( "Scale: %1 %2 %3" ).arg( xScale ).arg( yScale ).arg( zScale ) );
|
||||
}
|
||||
|
||||
std::vector<float> cornerLines = reader.getFloatArray( "cornerLines.data" );
|
||||
std::vector<float> zValues = reader.getFloatArray( "zvalues.data" );
|
||||
std::vector<float> cornerLines = reader.getFloatArray( "cornerLines" + roff::Parser::postFixData() );
|
||||
std::vector<float> zValues = reader.getFloatArray( "zvalues" + roff::Parser::postFixData() );
|
||||
std::vector<char> splitEnz = reader.getByteArray( "zvalues.splitEnz" );
|
||||
std::vector<char> active = reader.getByteArray( "active.data" );
|
||||
std::vector<char> active = reader.getByteArray( "active" + roff::Parser::postFixData() );
|
||||
|
||||
const auto parsingDone = high_resolution_clock::now();
|
||||
|
||||
@@ -521,7 +525,7 @@ std::pair<bool, std::map<QString, QString>> RifRoffFileTools::createInputPropert
|
||||
QString newResultName = eclipseCaseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL )
|
||||
->makeResultNameUnique( QString::fromStdString( keyword ) );
|
||||
// Special handling for active.data ==> ACTNUM
|
||||
if ( newResultName == "active.data" )
|
||||
if ( newResultName == QString( "active" ) + QString::fromStdString( roff::Parser::postFixData() ) )
|
||||
{
|
||||
newResultName = "ACTNUM";
|
||||
}
|
||||
@@ -533,6 +537,59 @@ std::pair<bool, std::map<QString, QString>> RifRoffFileTools::createInputPropert
|
||||
return std::make_pair( false, keywordMapping );
|
||||
}
|
||||
|
||||
// Create color legend
|
||||
{
|
||||
const std::string codeNamesKeyword = keyword + roff::Parser::postFixCodeNames();
|
||||
const std::string codeValuesKeyword = keyword + roff::Parser::postFixCodeValues();
|
||||
|
||||
auto codeNamesSize = reader.getArrayLength( codeNamesKeyword );
|
||||
auto codeValuesSize = reader.getArrayLength( codeValuesKeyword );
|
||||
|
||||
if ( codeNamesSize != 0 && codeNamesSize == codeValuesSize )
|
||||
{
|
||||
const auto fileCodeNames = reader.getStringArray( codeNamesKeyword );
|
||||
const auto fileCodeValues = reader.getIntArray( codeValuesKeyword );
|
||||
|
||||
QStringList trimmedCodeNames;
|
||||
bool anyValidName = false;
|
||||
for ( const std::string& codeName : fileCodeNames )
|
||||
{
|
||||
QString trimmedCodeName = QString::fromStdString( codeName ).trimmed();
|
||||
trimmedCodeNames.push_back( trimmedCodeName );
|
||||
|
||||
if ( !trimmedCodeName.isEmpty() )
|
||||
{
|
||||
anyValidName = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( anyValidName )
|
||||
{
|
||||
std::vector<std::pair<int, QString>> valuesAndNames;
|
||||
|
||||
for ( int i = 0; i < static_cast<int>( trimmedCodeNames.size() ); i++ )
|
||||
{
|
||||
const auto& codeName = trimmedCodeNames[i];
|
||||
valuesAndNames.emplace_back( fileCodeValues[i], codeName );
|
||||
}
|
||||
|
||||
RimColorLegendCollection* colorLegendCollection = RimProject::current()->colorLegendCollection;
|
||||
|
||||
int caseId = 0;
|
||||
auto rimCase = eclipseCaseData->ownerCase();
|
||||
if ( rimCase ) caseId = rimCase->caseId();
|
||||
|
||||
// Delete existing color legend, as new legend will be populated by values from file
|
||||
colorLegendCollection->deleteColorLegend( caseId, newResultName );
|
||||
|
||||
auto colorLegend = colorLegendCollection->createColorLegend( newResultName, valuesAndNames );
|
||||
|
||||
colorLegendCollection->setDefaultColorLegendForResult( caseId, newResultName, colorLegend );
|
||||
colorLegendCollection->updateAllRequiredEditors();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keywordMapping[QString::fromStdString( keyword )] = newResultName;
|
||||
}
|
||||
}
|
||||
@@ -568,7 +625,7 @@ bool RifRoffFileTools::hasGridData( const QString& filename )
|
||||
|
||||
const std::vector<std::pair<std::string, roff::Token::Kind>> arrayTypes = reader.getNamedArrayTypes();
|
||||
|
||||
const std::string cornerLinesDataKeyword = "cornerLines.data";
|
||||
const std::string cornerLinesDataKeyword = "cornerLines" + roff::Parser::postFixData();
|
||||
auto cornerLinesDataItr = std::find_if( arrayTypes.begin(),
|
||||
arrayTypes.end(),
|
||||
[&cornerLinesDataKeyword]( const auto& arrayType )
|
||||
@@ -640,7 +697,7 @@ bool RifRoffFileTools::appendNewInputPropertyResult( RigEclipseCaseData* caseDat
|
||||
}
|
||||
}
|
||||
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::INPUT_PROPERTY, resultName );
|
||||
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::INPUT_PROPERTY, RifRoffFileTools::mapFromType( kind ), resultName );
|
||||
caseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->createResultEntry( resAddr, false );
|
||||
|
||||
auto newPropertyData = caseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->modifiableCellScalarResultTimesteps( resAddr );
|
||||
@@ -649,3 +706,19 @@ bool RifRoffFileTools::appendNewInputPropertyResult( RigEclipseCaseData* caseDat
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaDefines::ResultDataType RifRoffFileTools::mapFromType( roff::Token::Kind kind )
|
||||
{
|
||||
switch ( kind )
|
||||
{
|
||||
case roff::Token::Kind::BOOL:
|
||||
return RiaDefines::ResultDataType::INTEGER;
|
||||
case roff::Token::Kind::INT:
|
||||
return RiaDefines::ResultDataType::INTEGER;
|
||||
}
|
||||
|
||||
return RiaDefines::ResultDataType::FLOAT;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "Token.hpp"
|
||||
|
||||
class RigEclipseCaseData;
|
||||
@@ -83,4 +84,6 @@ private:
|
||||
const std::string& keyword,
|
||||
roff::Token::Kind token,
|
||||
roff::Reader& reader );
|
||||
|
||||
static RiaDefines::ResultDataType mapFromType( roff::Token::Kind kind );
|
||||
};
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "roffcpp/src/Parser.hpp"
|
||||
#include "roffcpp/src/Reader.hpp"
|
||||
|
||||
#include <fstream>
|
||||
@@ -41,8 +42,8 @@ void RifRoffReader::readCodeNames( const QString& filename, const QString& param
|
||||
std::vector<std::pair<std::string, roff::Token::Kind>> arrayTypes = reader.getNamedArrayTypes();
|
||||
|
||||
// Find array types by keywords
|
||||
const std::string codeNamesKeyword = parameterTagName.toStdString() + ".codeNames";
|
||||
const std::string codeValuesKeyword = parameterTagName.toStdString() + ".codeValues";
|
||||
const std::string codeNamesKeyword = parameterTagName.toStdString() + roff::Parser::postFixCodeNames();
|
||||
const std::string codeValuesKeyword = parameterTagName.toStdString() + roff::Parser::postFixCodeValues();
|
||||
auto codeNamesItr = std::find_if( arrayTypes.begin(),
|
||||
arrayTypes.end(),
|
||||
[&codeNamesKeyword]( const auto& arrayType ) { return arrayType.first == codeNamesKeyword; } );
|
||||
|
||||
Reference in New Issue
Block a user