mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-25 06:38:13 -05:00
Update OPM Flow Job Preferences (#13172)
* Add job settings, with default settings in preferences. * Move opm flow settings to separate preferences tab * Add warning/error detection add display count next to progress * Adjust size of preference window
This commit is contained in:
15 files changed
+472
-52
No files matched your search
@@ -1,6 +1,7 @@
|
||||
set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGenericJob.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimOpmFlowJob.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimOpmFlowJobSettings.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimJobCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimDeckPositionDlg.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimKeywordFactory.h
|
||||
@@ -13,6 +14,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimGenericJob.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimOpmFlowJob.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimOpmFlowJobSettings.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimJobCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimDeckPositionDlg.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimKeywordFactory.cpp
|
||||
|
||||
@@ -42,6 +42,8 @@ RimGenericJob::RimGenericJob()
|
||||
, m_lastRunFailed( false )
|
||||
, m_isRunning( false )
|
||||
, m_process( nullptr )
|
||||
, m_errorsDetected( 0 )
|
||||
, m_warningsDetected( 0 )
|
||||
{
|
||||
CAF_PDM_InitObject( "Generic Job" );
|
||||
}
|
||||
@@ -115,8 +117,10 @@ bool RimGenericJob::execute()
|
||||
{
|
||||
if ( isRunning() ) return false;
|
||||
|
||||
m_process = nullptr;
|
||||
m_percentageDone = 0.0;
|
||||
m_errorsDetected = 0;
|
||||
m_warningsDetected = 0;
|
||||
m_process = nullptr;
|
||||
m_percentageDone = 0.0;
|
||||
|
||||
// job preparations
|
||||
{
|
||||
@@ -195,13 +199,17 @@ bool RimGenericJob::setFinished( bool runOk )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGenericJob::defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
|
||||
{
|
||||
static auto warnColor = QColor( RiaColorTools::toQColor( cvf::Color3f( cvf::Color3f::DARK_YELLOW ) ) );
|
||||
static auto contrastWarnColor =
|
||||
QColor( RiaColorTools::toQColor( RiaColorTools::contrastColor( cvf::Color3f( cvf::Color3f::DARK_YELLOW ) ) ) );
|
||||
|
||||
if ( auto* treeItemAttribute = dynamic_cast<caf::PdmUiTreeViewItemAttribute*>( attribute ) )
|
||||
{
|
||||
if ( m_lastRunFailed )
|
||||
{
|
||||
auto tag = caf::PdmUiTreeViewItemAttribute::createTag( QColor( Qt::red ),
|
||||
RiuGuiTheme::getColorByVariableName( "backgroundColor1" ),
|
||||
"!!!" );
|
||||
auto txt = m_errorsDetected > 0 ? QString( "[%1]" ).arg( m_errorsDetected ) : "!!!";
|
||||
auto tag =
|
||||
caf::PdmUiTreeViewItemAttribute::createTag( QColor( Qt::red ), RiuGuiTheme::getColorByVariableName( "backgroundColor1" ), txt );
|
||||
treeItemAttribute->tags.push_back( std::move( tag ) );
|
||||
}
|
||||
else
|
||||
@@ -228,6 +236,16 @@ void RimGenericJob::defineObjectEditorAttribute( QString uiConfigName, caf::PdmU
|
||||
tag->fgColor = QColor( RiaColorTools::toQColor( viewTextColor ) );
|
||||
treeItemAttribute->tags.push_back( std::move( tag ) );
|
||||
}
|
||||
if ( m_warningsDetected > 0 )
|
||||
{
|
||||
auto warnTxt = QString( "[%1]" ).arg( m_warningsDetected );
|
||||
|
||||
auto warnTag = caf::PdmUiTreeViewItemAttribute::createTag( warnColor, contrastWarnColor, warnTxt );
|
||||
treeItemAttribute->tags.push_back( std::move( warnTag ) );
|
||||
auto iconTag = caf::PdmUiTreeViewItemAttribute::createTag();
|
||||
iconTag->icon = caf::IconProvider( ":/warning.png" );
|
||||
treeItemAttribute->tags.push_back( std::move( iconTag ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
double percentageDone() const;
|
||||
const QStringList jobLog() const;
|
||||
|
||||
virtual void decodeProgress( const QString& logLine ) = 0;
|
||||
virtual void processLogOutput( const QString& logLine ) = 0;
|
||||
|
||||
protected:
|
||||
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;
|
||||
@@ -66,6 +66,8 @@ protected:
|
||||
|
||||
protected:
|
||||
double m_percentageDone;
|
||||
int m_warningsDetected;
|
||||
int m_errorsDetected;
|
||||
|
||||
private:
|
||||
bool m_lastRunFailed;
|
||||
|
||||
@@ -50,7 +50,7 @@ void RimJobMonitor::readyReadStandardOutput()
|
||||
line = line.trimmed();
|
||||
if ( line.size() == 0 ) continue;
|
||||
|
||||
m_job->decodeProgress( line );
|
||||
m_job->processLogOutput( line );
|
||||
m_stdOut.append( line );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "RimKeywordWconinje.h"
|
||||
#include "RimKeywordWconprod.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimOpmFlowJobSettings.h"
|
||||
#include "RimPerforationInterval.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimReloadCaseTools.h"
|
||||
@@ -111,7 +112,7 @@ RimOpmFlowJob::RimOpmFlowJob()
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_workDir, "WorkDirectory", "Working Folder" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_wellPath, "WellPath", "Well Path for New Well" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_eclipseCase, "EclipseCase", "Eclipse Case" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_eclipseCase, "EclipseCase", "Eclipse Case for Well Data", "", "Eclipse Case to use for Well Data" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_gridEnsemble, "GridEnsemble", "Grid Ensemble" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_summaryEnsemble, "SummaryEnsemble", "Summary Ensemble" );
|
||||
|
||||
@@ -121,7 +122,8 @@ RimOpmFlowJob::RimOpmFlowJob()
|
||||
CAF_PDM_InitField( &m_includeMSWData, "IncludeMswData", false, "Include MSW Data (experimental)" );
|
||||
CAF_PDM_InitField( &m_addToEnsemble, "AddToEnsemble", false, "Add Runs to Ensemble" );
|
||||
CAF_PDM_InitField( &m_useRestart, "UseRestart", false, "Restart Simulation at Well Open Date" );
|
||||
CAF_PDM_InitField( &m_currentRunId, "CurrentRunID", 0, "Current Run ID" );
|
||||
CAF_PDM_InitField( &m_currentRunId, "CurrentRunID", 0, "Current Ensemble Run ID" );
|
||||
m_currentRunId.uiCapability()->setUiReadOnly( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_wellGroupName, "WellGroupName", "Well Group Name" );
|
||||
m_wellGroupName.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
|
||||
@@ -139,6 +141,10 @@ RimOpmFlowJob::RimOpmFlowJob()
|
||||
m_wconinjeKeyword = new RimKeywordWconinje();
|
||||
m_wconinjeKeyword.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_jobSettings, "JobSettings", "Opm Flow Settings" );
|
||||
m_jobSettings = RiaPreferencesOpm::current()->createDefaultJobSettings();
|
||||
m_jobSettings.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
|
||||
CAF_PDM_InitField( &m_openTimeStep, "OpenTimeStep", 0, " " );
|
||||
CAF_PDM_InitField( &m_endTimeStep, "EndTimeStep", 0, " " );
|
||||
CAF_PDM_InitField( &m_endTimeStepEnabled, "EndTimeStepEnabled", false, "Stop Simulation at Date" );
|
||||
@@ -177,8 +183,9 @@ void RimOpmFlowJob::initAfterRead()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimOpmFlowJob::decodeProgress( const QString& logLine )
|
||||
void RimOpmFlowJob::processLogOutput( const QString& logLine )
|
||||
{
|
||||
// progress output parsing
|
||||
// Example log lines:
|
||||
// Report step 757/773 at day 9466/10958, date = 01-Dec-2025
|
||||
// Report step 758/773 at day 9497/10958, date = 01-Jan-2026
|
||||
@@ -214,6 +221,18 @@ void RimOpmFlowJob::decodeProgress( const QString& logLine )
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( logLine.startsWith( "Warning" ) )
|
||||
{
|
||||
m_warningsDetected++;
|
||||
}
|
||||
else if ( logLine.startsWith( "Problem" ) )
|
||||
{
|
||||
m_warningsDetected++;
|
||||
}
|
||||
else if ( logLine.startsWith( "Error" ) )
|
||||
{
|
||||
m_errorsDetected++;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -263,7 +282,7 @@ void RimOpmFlowJob::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
|
||||
genGrp->add( nameField() );
|
||||
genGrp->add( &m_deckFileName );
|
||||
genGrp->add( &m_workDir );
|
||||
genGrp->add( &m_eclipseCase );
|
||||
genGrp->add( &m_addToEnsemble );
|
||||
|
||||
if ( m_eclipseCase() == nullptr )
|
||||
{
|
||||
@@ -273,6 +292,7 @@ void RimOpmFlowJob::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
|
||||
{
|
||||
auto wellGrp = uiOrdering.addNewGroup( "New Well Settings" );
|
||||
wellGrp->add( &m_addNewWell );
|
||||
wellGrp->add( &m_eclipseCase );
|
||||
|
||||
if ( m_addNewWell() )
|
||||
{
|
||||
@@ -337,6 +357,13 @@ void RimOpmFlowJob::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
|
||||
{
|
||||
auto dateGrp = uiOrdering.addNewGroup( "Date Settings" );
|
||||
dateGrp->setCollapsedByDefault();
|
||||
|
||||
dateGrp->add( &m_endTimeStepEnabled );
|
||||
if ( m_endTimeStepEnabled() )
|
||||
{
|
||||
dateGrp->add( &m_endTimeStep );
|
||||
}
|
||||
|
||||
dateGrp->add( &m_appendNewDates );
|
||||
if ( m_appendNewDates() )
|
||||
{
|
||||
@@ -353,23 +380,14 @@ void RimOpmFlowJob::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
|
||||
runButton->setAlignment( Qt::AlignCenter );
|
||||
|
||||
opmGrp->add( &m_pauseBeforeRun );
|
||||
if ( m_fileDeckHasDates )
|
||||
{
|
||||
opmGrp->add( &m_endTimeStepEnabled );
|
||||
if ( m_endTimeStepEnabled() )
|
||||
{
|
||||
opmGrp->add( &m_endTimeStep );
|
||||
}
|
||||
}
|
||||
opmGrp->add( &m_addToEnsemble );
|
||||
if ( m_addToEnsemble() )
|
||||
{
|
||||
auto advOpmGrp = opmGrp->addNewGroup( "Advanced" );
|
||||
advOpmGrp->setCollapsedByDefault();
|
||||
|
||||
auto resetRunIdButton = advOpmGrp->addNewButton( "Reset Ensemble Run Id", [this]() { resetEnsembleRunId(); } );
|
||||
resetRunIdButton->setAlignment( Qt::AlignRight );
|
||||
}
|
||||
m_jobSettings->uiOrdering( opmGrp, false /* expand by default */ );
|
||||
|
||||
auto advGrp = uiOrdering.addNewGroup( "Advanced" );
|
||||
advGrp->setCollapsedByDefault();
|
||||
advGrp->add( &m_currentRunId );
|
||||
auto resetRunIdButton = advGrp->addNewButton( "Reset Ensemble Run Id", [this]() { resetEnsembleRunId(); } );
|
||||
resetRunIdButton->setAlignment( Qt::AlignRight );
|
||||
|
||||
uiOrdering.skipRemainingFields();
|
||||
}
|
||||
@@ -687,13 +705,14 @@ QStringList RimOpmFlowJob::command()
|
||||
{
|
||||
cmd.append( opmPref->mpirunCommand() );
|
||||
cmd.append( QString( "-np" ) );
|
||||
cmd.append( QString( "%1" ).arg( opmPref->mpiProcesses() ) );
|
||||
cmd.append( QString( "%1" ).arg( m_jobSettings->mpiProcesses() ) );
|
||||
}
|
||||
|
||||
cmd.append( opmPref->opmFlowCommand() );
|
||||
cmd.append( QString( "--output-dir=%1" ).arg( workDir ) );
|
||||
cmd.append( QString( "--ecl-deck-file-name=%1" ).arg( dataFile ) );
|
||||
cmd.append( QString( "--enable-esmry=true" ) );
|
||||
|
||||
cmd.append( m_jobSettings->commandLineOptions() );
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ class RimEclipseCaseEnsemble;
|
||||
class RimSummaryEnsemble;
|
||||
class RimKeywordWconprod;
|
||||
class RimKeywordWconinje;
|
||||
class RimOpmFlowJobSettings;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@@ -72,7 +73,7 @@ protected:
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
|
||||
void initAfterRead() override;
|
||||
|
||||
void decodeProgress( const QString& logLine ) override;
|
||||
void processLogOutput( const QString& logLine ) override;
|
||||
|
||||
QStringList command() override;
|
||||
std::map<QString, QString> environment() override;
|
||||
@@ -132,8 +133,9 @@ private:
|
||||
caf::PdmField<int> m_numberOfNewDates;
|
||||
caf::PdmField<caf::AppEnum<DateAppendType>> m_dateAppendType;
|
||||
|
||||
caf::PdmChildField<RimKeywordWconprod*> m_wconprodKeyword;
|
||||
caf::PdmChildField<RimKeywordWconinje*> m_wconinjeKeyword;
|
||||
caf::PdmChildField<RimKeywordWconprod*> m_wconprodKeyword;
|
||||
caf::PdmChildField<RimKeywordWconinje*> m_wconinjeKeyword;
|
||||
caf::PdmChildField<RimOpmFlowJobSettings*> m_jobSettings;
|
||||
|
||||
caf::PdmField<QString> m_wellOpenKeyword;
|
||||
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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 "RimOpmFlowJobSettings.h"
|
||||
|
||||
#include "cafPdmFieldCapability.h"
|
||||
#include "cafPdmUiCheckBoxAndTextEditor.h"
|
||||
#include "cafPdmUiCheckBoxEditor.h"
|
||||
#include "cafPdmUiListEditor.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimOpmFlowJobSettings, "OpmFlowJobSettings" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimOpmFlowJobSettings::RimOpmFlowJobSettings()
|
||||
{
|
||||
CAF_PDM_InitObject( "Opm Flow Job Settings" );
|
||||
|
||||
CAF_PDM_InitField( &m_mpiProcesses, "mpiProcesses", 2, "Number of MPI Processes" );
|
||||
CAF_PDM_InitField( &m_threadsPerProcess,
|
||||
"threadsPerProcess",
|
||||
2,
|
||||
"Threads Per Process",
|
||||
"",
|
||||
"The maximum number of threads to be instantiated per process ('-1' means 'automatic')." );
|
||||
|
||||
CAF_PDM_InitField( &m_enableEsmry, "enableEsmry", true, "Enable ESMRY Output", "", "Write ESMRY file for fast loading of summary data." );
|
||||
caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_enableEsmry );
|
||||
CAF_PDM_InitField( &m_enableTerminalOutput,
|
||||
"enableTerminalOutput",
|
||||
true,
|
||||
"Enable Terminal Output",
|
||||
"",
|
||||
"Print high-level information about the simulation's progress to the terminal." );
|
||||
caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_enableTerminalOutput );
|
||||
CAF_PDM_InitField( &m_enableTuning, "enableTuning", false, "Enable Tuning", "", "Honor some aspects of the TUNING keyword." );
|
||||
caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_enableTuning );
|
||||
|
||||
CAF_PDM_InitField( &m_ignoreKeywords,
|
||||
"ignoreKeywords",
|
||||
std::vector<QString>{},
|
||||
"Ignore Keywords",
|
||||
"",
|
||||
"List of Eclipse keywords which should be ignored." );
|
||||
m_ignoreKeywords.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitField( &m_newtonMaxIterations,
|
||||
"newtonMaxIterations",
|
||||
std::make_pair( false, 20 ),
|
||||
"Newton Max Iterations",
|
||||
"",
|
||||
"The maximum number of Newton iterations per time step." );
|
||||
m_newtonMaxIterations.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxAndTextEditor::uiEditorTypeName() );
|
||||
CAF_PDM_InitField( &m_parsingStrictness,
|
||||
"parsingStrictness",
|
||||
QString( "normal" ),
|
||||
"Parsing Strictness",
|
||||
"",
|
||||
"Set strictness of parsing process. Normal = stop for critical errors, High = stop for all "
|
||||
"errors, Low = Do not stop due to unsupported keywords even if marked critical." );
|
||||
CAF_PDM_InitField( &m_relaxedMaxPvFraction,
|
||||
"relaxedMaxPvFraction",
|
||||
std::make_pair( false, 0.03 ),
|
||||
"Relaxed Max PV Fraction",
|
||||
"",
|
||||
"The fraction of the pore volume of the reservoir where the volumetric error (CNV) may be "
|
||||
"violated during strict Newton iterations." );
|
||||
CAF_PDM_InitField( &m_solverMaxTimeStepInDays,
|
||||
"solverMaxTimeStepInDays",
|
||||
std::make_pair( false, 365.0 ),
|
||||
"Solver Max Time Step In Days",
|
||||
"",
|
||||
"The maximum size of a time step in days." );
|
||||
CAF_PDM_InitField( &m_solverMinTimeStepInDays,
|
||||
"solverMinTimeStepInDays",
|
||||
std::make_pair( false, 1e-12 ),
|
||||
"Solver Min Time Step In Days",
|
||||
"",
|
||||
"The minimum size of a time step in days for field and metric and hours for lab. If a step "
|
||||
"cannot converge without getting cut below this step size the simulator will stop." );
|
||||
CAF_PDM_InitField( &m_minStrictCnvIter,
|
||||
"minStrictCnvIter",
|
||||
std::make_pair( false, -1 ),
|
||||
"Min Strict CNV Iter",
|
||||
"",
|
||||
"Minimum number of Newton iterations before relaxed tolerances can be used for the CNV "
|
||||
"convergence criterion." );
|
||||
m_minStrictCnvIter.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxAndTextEditor::uiEditorTypeName() );
|
||||
CAF_PDM_InitField( &m_minStrictMbIter,
|
||||
"minStrictMbIter",
|
||||
std::make_pair( false, -1 ),
|
||||
"Min Strict MB Iter",
|
||||
"",
|
||||
"Minimum number of Newton iterations before relaxed tolerances can be used for the MB "
|
||||
"convergence criterion." );
|
||||
m_minStrictMbIter.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxAndTextEditor::uiEditorTypeName() );
|
||||
CAF_PDM_InitField( &m_minTimeStepBasedOnNewtonIterations,
|
||||
"minTimeStepBasedOnNewtonIterations",
|
||||
std::make_pair( false, 0.0 ),
|
||||
"Min Time Step Based On Newton Iterations",
|
||||
"",
|
||||
"The minimum time step size (in days for field and metric unit and hours for lab unit) "
|
||||
"can be reduced to based on newton iteration counts." );
|
||||
CAF_PDM_InitField( &m_minTimeStepBeforeShuttingProblematicWellsInDays,
|
||||
"minTimeStepBeforeShuttingProblematicWellsInDays",
|
||||
std::make_pair( false, 0.01 ),
|
||||
"Min Time Step Before Shutting Problematic Wells In Days",
|
||||
"",
|
||||
"The minimum time step size in days for which problematic wells are not shut." );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimOpmFlowJobSettings::~RimOpmFlowJobSettings()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimOpmFlowJobSettings* RimOpmFlowJobSettings::clone()
|
||||
{
|
||||
return copyObject<RimOpmFlowJobSettings>();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimOpmFlowJobSettings::uiOrdering( caf::PdmUiGroup* uiGroup, bool expandByDefault )
|
||||
{
|
||||
caf::PdmUiGroup* generalGroup = uiGroup->addNewGroup( "Process Control" );
|
||||
if ( !expandByDefault ) generalGroup->setCollapsedByDefault();
|
||||
generalGroup->add( &m_mpiProcesses );
|
||||
generalGroup->add( &m_threadsPerProcess );
|
||||
|
||||
caf::PdmUiGroup* optionsGroup = uiGroup->addNewGroup( "Simulator Options" );
|
||||
if ( !expandByDefault ) optionsGroup->setCollapsedByDefault();
|
||||
optionsGroup->add( &m_enableEsmry );
|
||||
optionsGroup->add( &m_enableTerminalOutput );
|
||||
optionsGroup->add( &m_enableTuning );
|
||||
optionsGroup->add( &m_ignoreKeywords );
|
||||
optionsGroup->add( &m_parsingStrictness );
|
||||
|
||||
caf::PdmUiGroup* solverGroup = uiGroup->addNewGroup( "Solver Settings" );
|
||||
solverGroup->setCollapsedByDefault();
|
||||
solverGroup->add( &m_newtonMaxIterations );
|
||||
solverGroup->add( &m_relaxedMaxPvFraction );
|
||||
solverGroup->add( &m_solverMaxTimeStepInDays );
|
||||
solverGroup->add( &m_solverMinTimeStepInDays );
|
||||
solverGroup->add( &m_minStrictCnvIter );
|
||||
solverGroup->add( &m_minStrictMbIter );
|
||||
solverGroup->add( &m_minTimeStepBasedOnNewtonIterations );
|
||||
solverGroup->add( &m_minTimeStepBeforeShuttingProblematicWellsInDays );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimOpmFlowJobSettings::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
|
||||
if ( fieldNeedingOptions == &m_parsingStrictness )
|
||||
{
|
||||
for ( QString name : { "Low", "Normal", "High" } )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( name, QVariant::fromValue( name.toLower() ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimOpmFlowJobSettings::mpiProcesses() const
|
||||
{
|
||||
return m_mpiProcesses;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList RimOpmFlowJobSettings::commandLineOptions() const
|
||||
{
|
||||
QStringList options;
|
||||
|
||||
options << QString( "--threads-per-process=%1" ).arg( m_threadsPerProcess );
|
||||
|
||||
QString trueOrFalse = m_enableEsmry ? "true" : "false";
|
||||
options << "--enable-esmry=" + trueOrFalse;
|
||||
|
||||
trueOrFalse = m_enableTerminalOutput ? "true" : "false";
|
||||
options << "--enable-terminal-output=" + trueOrFalse;
|
||||
|
||||
trueOrFalse = m_enableTuning ? "true" : "false";
|
||||
options << "--enable-tuning=" + trueOrFalse;
|
||||
|
||||
if ( !m_ignoreKeywords().empty() )
|
||||
{
|
||||
QStringList kws;
|
||||
for ( const QString& kw : m_ignoreKeywords() )
|
||||
{
|
||||
kws << kw;
|
||||
}
|
||||
options << QString( "--ignore-keywords=%1" ).arg( kws.join( ":" ) );
|
||||
}
|
||||
|
||||
options << QString( "--parsing-strictness=%1" ).arg( m_parsingStrictness() );
|
||||
|
||||
if ( m_newtonMaxIterations().first )
|
||||
{
|
||||
options << QString( "--newton-max-iterations=%1" ).arg( m_newtonMaxIterations().second );
|
||||
}
|
||||
if ( m_relaxedMaxPvFraction().first )
|
||||
{
|
||||
options << QString( "--relaxed-max-pv-fraction=%1" ).arg( m_relaxedMaxPvFraction().second );
|
||||
}
|
||||
if ( m_solverMaxTimeStepInDays().first )
|
||||
{
|
||||
options << QString( "--solver-max-time-step=%1d" ).arg( m_solverMaxTimeStepInDays().second );
|
||||
}
|
||||
if ( m_solverMinTimeStepInDays().first )
|
||||
{
|
||||
options << QString( "--solver-min-time-step=%1d" ).arg( m_solverMinTimeStepInDays().second );
|
||||
}
|
||||
if ( m_minStrictCnvIter().first )
|
||||
{
|
||||
options << QString( "--min-strict-cnv-iter=%1" ).arg( m_minStrictCnvIter().second );
|
||||
}
|
||||
if ( m_minStrictMbIter().first )
|
||||
{
|
||||
options << QString( "--min-strict-mb-iter=%1" ).arg( m_minStrictMbIter().second );
|
||||
}
|
||||
if ( m_minTimeStepBasedOnNewtonIterations().first )
|
||||
{
|
||||
options << QString( "--min-time-step-based-on-newton-iterations=%1d" ).arg( m_minTimeStepBasedOnNewtonIterations().second );
|
||||
}
|
||||
if ( m_minTimeStepBeforeShuttingProblematicWellsInDays().first )
|
||||
{
|
||||
options
|
||||
<< QString( "--min-time-step-before-shutting-problematic-wells=%1d" ).arg( m_minTimeStepBeforeShuttingProblematicWellsInDays().second );
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimOpmFlowJobSettings::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
|
||||
{
|
||||
if ( field == &m_ignoreKeywords )
|
||||
{
|
||||
auto attrib = dynamic_cast<caf::PdmUiListEditorAttribute*>( attribute );
|
||||
if ( attrib )
|
||||
{
|
||||
attrib->heightHint = 40;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimOpmFlowJobSettings : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimOpmFlowJobSettings();
|
||||
~RimOpmFlowJobSettings() override;
|
||||
|
||||
RimOpmFlowJobSettings* clone();
|
||||
|
||||
void uiOrdering( caf::PdmUiGroup* uiGroup, bool expandByDefault = true );
|
||||
|
||||
int mpiProcesses() const;
|
||||
|
||||
QStringList commandLineOptions() const;
|
||||
|
||||
protected:
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
|
||||
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
|
||||
|
||||
private:
|
||||
caf::PdmField<int> m_mpiProcesses;
|
||||
caf::PdmField<int> m_threadsPerProcess;
|
||||
|
||||
caf::PdmField<bool> m_enableEsmry;
|
||||
caf::PdmField<bool> m_enableTuning;
|
||||
caf::PdmField<bool> m_enableTerminalOutput;
|
||||
caf::PdmField<std::vector<QString>> m_ignoreKeywords;
|
||||
caf::PdmField<QString> m_parsingStrictness;
|
||||
|
||||
caf::PdmField<std::pair<bool, int>> m_newtonMaxIterations;
|
||||
caf::PdmField<std::pair<bool, double>> m_relaxedMaxPvFraction;
|
||||
caf::PdmField<std::pair<bool, double>> m_solverMaxTimeStepInDays;
|
||||
caf::PdmField<std::pair<bool, double>> m_solverMinTimeStepInDays;
|
||||
caf::PdmField<std::pair<bool, int>> m_minStrictCnvIter;
|
||||
caf::PdmField<std::pair<bool, int>> m_minStrictMbIter;
|
||||
caf::PdmField<std::pair<bool, double>> m_minTimeStepBasedOnNewtonIterations;
|
||||
caf::PdmField<std::pair<bool, double>> m_minTimeStepBeforeShuttingProblematicWellsInDays;
|
||||
};
|
||||
Reference in new issue
Block a user