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:
JJ authored and GitHub committed 2025-11-14 12:56:23 +01:00
1 parent 562ce12534
commit 7c8aadcd60
15 files changed
+472 -52

No files matched your search

@@ -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;
}
}
}