#13425 Fix ICD/AICD valve output in schedule generation

ICD valves now produce WSEGVALV and AICD valves now produce WSEGAICD
in the generated schedule. Three root causes were fixed:

- Create per-event valve templates with proper parameters instead of
  reusing default templates that lack orifice diameter and AICD fields
- Use perforation interval range for ICD/AICD valve positioning so
  valveLocations() returns non-empty results for the accumulator
- Add 5 AICD parameter fields to the Python API and event classes
This commit is contained in:
Kristian Bendiksen committed 2026-02-12 08:15:22 +01:00
1 parent 82e2dbc434
commit 1ec53cc3f2
7 files changed
+286 -15

No files matched your search

@@ -36,17 +36,22 @@
#include "RimProject.h"
#include "RimTools.h"
#include "RimValveTemplate.h"
#include "RimValveTemplateCollection.h"
#include "RimWellPath.h"
#include "RimWellPathAicdParameters.h"
#include "RimWellPathCollection.h"
#include "RimWellPathValve.h"
#include "Riu3DMainWindowTools.h"
#include "cvfMath.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiTreeOrdering.h"
#include <algorithm>
#include <cmath>
#include <set>
CAF_PDM_SOURCE_INIT( RimWellEventTimeline, "WellEventTimeline" );
@@ -530,7 +535,18 @@ bool RimWellEventTimeline::applyValveEvent( const RimWellEventValve& event, RimW
targetPerf->addValve( valve );
valve->setMeasuredDepthAndCount( valveMD, 0, 1 );
// For ICD/AICD valves, the valve range must cover the perforation interval so that
// valveLocations() returns a non-empty list and the accumulator can validate the valve.
// For ICV, a single point at the valve MD is sufficient.
if ( event.valveType() == RimWellEventValve::ValveType::ICV )
{
valve->setMeasuredDepthAndCount( valveMD, 0, 1 );
}
else
{
double perfRange = targetPerf->endMD() - targetPerf->startMD();
valve->setMeasuredDepthAndCount( targetPerf->startMD(), perfRange, 1 );
}
// Set the custom start date based on the event date
valve->enableCustomStartDate( true );
@@ -553,16 +569,31 @@ bool RimWellEventTimeline::applyValveEvent( const RimWellEventValve& event, RimW
// Map the event valve type to the RiaDefines type and find a matching template
RiaDefines::WellPathComponentType valveComponentType = convertToValveType( event.valveType() );
// Try to find a matching valve template
// Create a new valve template with the event's specific parameters
if ( RimProject* project = RimProject::current() )
{
for ( auto* tmpl : project->allValveTemplates() )
auto collections = project->allValveTemplateCollections();
if ( !collections.empty() )
{
if ( tmpl->type() == valveComponentType )
auto* tmpl = new RimValveTemplate;
tmpl->setType( valveComponentType );
tmpl->setFlowCoefficient( event.flowCoefficient() );
double orifice_mm = 2000.0 * std::sqrt( event.area() / cvf::PI_D );
tmpl->setOrificeDiameter( orifice_mm );
if ( valveComponentType == RiaDefines::WellPathComponentType::AICD )
{
valve->setValveTemplate( tmpl );
break;
tmpl->setAicdParameter( AICD_STRENGTH, event.aicdStrength() );
tmpl->setAicdParameter( AICD_DENSITY_CALIB_FLUID, event.aicdDensityCalibFluid() );
tmpl->setAicdParameter( AICD_VISCOSITY_CALIB_FLUID, event.aicdViscosityCalibFluid() );
tmpl->setAicdParameter( AICD_VOL_FLOW_EXP, event.aicdVolFlowExp() );
tmpl->setAicdParameter( AICD_VISOSITY_FUNC_EXP, event.aicdViscFuncExp() );
}
tmpl->setUserLabel( QString( "Event Valve %1" ).arg( event.measuredDepth() ) );
collections.front()->addItem( tmpl );
valve->setValveTemplate( tmpl );
}
}
@@ -60,6 +60,12 @@ RimWellEventValve::RimWellEventValve()
CAF_PDM_InitScriptableField( &m_area, "Area", 0.0001, "Area [m2]" );
CAF_PDM_InitScriptableFieldNoDefault( &m_valveTemplate, "ValveTemplate", "Valve Template" );
CAF_PDM_InitScriptableField( &m_aicdStrength, "AicdStrength", 0.00021, "AICD Strength" );
CAF_PDM_InitScriptableField( &m_aicdDensityCalibFluid, "AicdDensityCalibFluid", 1000.0, "AICD Density of Calibration Fluid [kg/m3]" );
CAF_PDM_InitScriptableField( &m_aicdViscosityCalibFluid, "AicdViscosityCalibFluid", 1.0, "AICD Viscosity of Calibration Fluid [cP]" );
CAF_PDM_InitScriptableField( &m_aicdVolFlowExp, "AicdVolFlowExp", 2.1, "AICD Volume Flow Rate Exponent" );
CAF_PDM_InitScriptableField( &m_aicdViscFuncExp, "AicdViscFuncExp", 0.5, "AICD Viscosity Function Exponent" );
setDeletable( true );
}
@@ -170,6 +176,86 @@ void RimWellEventValve::setValveTemplate( RimValveTemplate* valveTemplate )
m_valveTemplate = valveTemplate;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellEventValve::aicdStrength() const
{
return m_aicdStrength();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellEventValve::aicdDensityCalibFluid() const
{
return m_aicdDensityCalibFluid();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellEventValve::aicdViscosityCalibFluid() const
{
return m_aicdViscosityCalibFluid();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellEventValve::aicdVolFlowExp() const
{
return m_aicdVolFlowExp();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellEventValve::aicdViscFuncExp() const
{
return m_aicdViscFuncExp();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellEventValve::setAicdStrength( double value )
{
m_aicdStrength = value;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellEventValve::setAicdDensityCalibFluid( double value )
{
m_aicdDensityCalibFluid = value;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellEventValve::setAicdViscosityCalibFluid( double value )
{
m_aicdViscosityCalibFluid = value;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellEventValve::setAicdVolFlowExp( double value )
{
m_aicdVolFlowExp = value;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellEventValve::setAicdViscFuncExp( double value )
{
m_aicdViscFuncExp = value;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -60,6 +60,12 @@ public:
double area() const;
RimValveTemplate* valveTemplate() const;
double aicdStrength() const;
double aicdDensityCalibFluid() const;
double aicdViscosityCalibFluid() const;
double aicdVolFlowExp() const;
double aicdViscFuncExp() const;
// Setters
void setMeasuredDepth( double md );
void setValveType( ValveType type );
@@ -68,6 +74,12 @@ public:
void setArea( double area );
void setValveTemplate( RimValveTemplate* valveTemplate );
void setAicdStrength( double value );
void setAicdDensityCalibFluid( double value );
void setAicdViscosityCalibFluid( double value );
void setAicdVolFlowExp( double value );
void setAicdViscFuncExp( double value );
// Override from RimWellEvent
EventType eventType() const override;
QString generateScheduleKeyword( const QString& wellName ) const override;
@@ -84,6 +96,12 @@ private:
caf::PdmField<double> m_flowCoefficient;
caf::PdmField<double> m_area;
caf::PdmPtrField<RimValveTemplate*> m_valveTemplate;
caf::PdmField<double> m_aicdStrength;
caf::PdmField<double> m_aicdDensityCalibFluid;
caf::PdmField<double> m_aicdViscosityCalibFluid;
caf::PdmField<double> m_aicdVolFlowExp;
caf::PdmField<double> m_aicdViscFuncExp;
};
namespace caf