diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimCompletionTemplateCollection.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimCompletionTemplateCollection.cpp index a504454ba7..46f8919f2b 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimCompletionTemplateCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimCompletionTemplateCollection.cpp @@ -23,6 +23,8 @@ #include "RimStimPlanModelTemplateCollection.h" #include "RimValveTemplateCollection.h" +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmObjectScriptingCapability.h" #include "cafPdmUiTreeOrdering.h" #include "cvfAssert.h" @@ -34,7 +36,7 @@ CAF_PDM_SOURCE_INIT( RimCompletionTemplateCollection, "CompletionTemplateCollect //-------------------------------------------------------------------------------------------------- RimCompletionTemplateCollection::RimCompletionTemplateCollection() { - CAF_PDM_InitObject( "Completion Templates", ":/CompletionsSymbol16x16.png" ); + CAF_PDM_InitScriptableObject( "Completion Templates", ":/CompletionsSymbol16x16.png" ); CAF_PDM_InitFieldNoDefault( &m_fractureTemplates, "FractureTemplates", "" ); m_fractureTemplates = new RimFractureTemplateCollection; @@ -43,7 +45,7 @@ RimCompletionTemplateCollection::RimCompletionTemplateCollection() CAF_PDM_InitFieldNoDefault( &m_stimPlanModelTemplates, "StimPlanModelTemplates", "" ); m_stimPlanModelTemplates = new RimStimPlanModelTemplateCollection; - CAF_PDM_InitFieldNoDefault( &m_valveTemplates, "ValveTemplates", "" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_valveTemplates, "ValveTemplates", "" ); m_valveTemplates = new RimValveTemplateCollection; CAF_PDM_InitFieldNoDefault( &m_fractureGroupStatisticsCollection, "FractureGroupStatisticsCollection", "" ); diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimPerforationInterval.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimPerforationInterval.cpp index e10a4e76af..aa55feb12a 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimPerforationInterval.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimPerforationInterval.cpp @@ -60,7 +60,7 @@ RimPerforationInterval::RimPerforationInterval() CAF_PDM_InitField( &m_useCustomEndDate, "UseCustomEndDate", false, "Custom End Date" ); CAF_PDM_InitField( &m_endDate, "EndDate", QDateTime::currentDateTime(), "End Date" ); - CAF_PDM_InitFieldNoDefault( &m_valves, "Valves", "Valves" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_valves, "Valves", "Valves" ); nameField()->uiCapability()->setUiReadOnly( true ); diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.cpp index c765cff764..3712c481d2 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplate.cpp @@ -21,6 +21,8 @@ #include "RimWellPathAicdParameters.h" #include "RimWellPathValve.h" +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmObjectScriptingCapability.h" #include "cafPdmUiTreeOrdering.h" #include "opm/input/eclipse/Parser/ParserKeywords/W.hpp" @@ -32,7 +34,7 @@ CAF_PDM_SOURCE_INIT( RimValveTemplate, "ValveTemplate" ); //-------------------------------------------------------------------------------------------------- RimValveTemplate::RimValveTemplate() { - CAF_PDM_InitObject( "Valve Template", ":/ICDValve16x16.png" ); + CAF_PDM_InitScriptableObject( "Valve Template", ":/ICDValve16x16.png" ); CAF_PDM_InitField( &m_valveTemplateUnit, "UnitSystem", @@ -46,10 +48,10 @@ RimValveTemplate::RimValveTemplate() setName( fullLabel() ); - CAF_PDM_InitField( &m_orificeDiameter, "OrificeDiameter", 8.0, "Orifice Diameter [mm]" ); - CAF_PDM_InitField( &m_flowCoefficient, "FlowCoefficient", 0.7, "Flow Coefficient" ); + CAF_PDM_InitScriptableField( &m_orificeDiameter, "OrificeDiameter", 8.0, "Orifice Diameter [mm]" ); + CAF_PDM_InitScriptableField( &m_flowCoefficient, "FlowCoefficient", 0.7, "Flow Coefficient" ); - CAF_PDM_InitFieldNoDefault( &m_aicdParameters, "AICDParameters", "AICD Parameters" ); + CAF_PDM_InitScriptableFieldWithScriptKeywordNoDefault( &m_aicdParameters, "AICDParameters", "AicdParameters", "AICD Parameters" ); m_aicdParameters = new RimWellPathAicdParameters; m_aicdParameters.uiCapability()->setUiTreeChildrenHidden( true ); } diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplateCollection.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplateCollection.cpp index 226244cc63..df77919458 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplateCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimValveTemplateCollection.cpp @@ -21,6 +21,9 @@ #include "RimProject.h" #include "RimValveTemplate.h" +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmObjectScriptingCapability.h" + CAF_PDM_SOURCE_INIT( RimValveTemplateCollection, "ValveTemplateCollection" ); //-------------------------------------------------------------------------------------------------- @@ -28,9 +31,9 @@ CAF_PDM_SOURCE_INIT( RimValveTemplateCollection, "ValveTemplateCollection" ); //-------------------------------------------------------------------------------------------------- RimValveTemplateCollection::RimValveTemplateCollection() { - CAF_PDM_InitObject( "Valve Templates", ":/ICDValve16x16.png" ); - CAF_PDM_InitFieldNoDefault( &m_valveDefinitions, "ValveDefinitions", "" ); - CAF_PDM_InitFieldNoDefault( &m_defaultUnitsForValveTemplates, "ValveUnits", "Default unit system for valve templates" ); + CAF_PDM_InitScriptableObject( "Valve Templates", ":/ICDValve16x16.png" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_valveDefinitions, "ValveDefinitions", "" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_defaultUnitsForValveTemplates, "ValveUnits", "Default unit system for valve templates" ); m_defaultUnitsForValveTemplates = RiaDefines::EclipseUnitSystem::UNITS_METRIC; addDefaultValveTemplates(); } diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathAicdParameters.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathAicdParameters.cpp index f46c0972c3..cf5e64f1c7 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathAicdParameters.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathAicdParameters.cpp @@ -22,6 +22,8 @@ #include "RimWellPathValve.h" #include "cafPdmDoubleStringValidator.h" +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmObjectScriptingCapability.h" #include "cafPdmUiDoubleValueEditor.h" #include "cafPdmUiGroup.h" #include "cafPdmUiLineEditor.h" @@ -35,51 +37,65 @@ CAF_PDM_SOURCE_INIT( RimWellPathAicdParameters, "WellPathAicdParameters" ); //-------------------------------------------------------------------------------------------------- RimWellPathAicdParameters::RimWellPathAicdParameters() { - CAF_PDM_InitObject( "RimWellPathAicdParameters" ); + CAF_PDM_InitScriptableObject( "RimWellPathAicdParameters" ); - CAF_PDM_InitField( &m_deviceOpen, "DeviceOpen", true, "Device Open?" ); + CAF_PDM_InitScriptableField( &m_deviceOpen, "DeviceOpen", true, "Device Open?" ); - CAF_PDM_InitFieldNoDefault( &m_aicdParameterFields[AICD_STRENGTH], "StrengthAICD", "Strength of AICD" ); - CAF_PDM_InitFieldNoDefault( &m_aicdParameterFields[AICD_DENSITY_CALIB_FLUID], - "DensityCalibrationFluid", - "Calibration Fluid Density (kg/m^3)" ); - CAF_PDM_InitFieldNoDefault( &m_aicdParameterFields[AICD_VISCOSITY_CALIB_FLUID], - "ViscosityCalibrationFluid", - "Calibration Fluid Viscosity (cP)" ); - CAF_PDM_InitFieldNoDefault( &m_aicdParameterFields[AICD_VOL_FLOW_EXP], "VolumeFlowRateExponent", "Volume Flow Rate Exponent" ); - CAF_PDM_InitFieldNoDefault( &m_aicdParameterFields[AICD_VISOSITY_FUNC_EXP], "ViscosityFunctionExponent", "Viscosity Function Exponent" ); + CAF_PDM_InitScriptableFieldWithScriptKeywordNoDefault( &m_aicdParameterFields[AICD_STRENGTH], + "StrengthAICD", + "StrengthAicd", + "Strength of AICD" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_aicdParameterFields[AICD_DENSITY_CALIB_FLUID], + "DensityCalibrationFluid", + "Calibration Fluid Density (kg/m^3)" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_aicdParameterFields[AICD_VISCOSITY_CALIB_FLUID], + "ViscosityCalibrationFluid", + "Calibration Fluid Viscosity (cP)" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_aicdParameterFields[AICD_VOL_FLOW_EXP], "VolumeFlowRateExponent", "Volume Flow Rate Exponent" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_aicdParameterFields[AICD_VISOSITY_FUNC_EXP], + "ViscosityFunctionExponent", + "Viscosity Function Exponent" ); - CAF_PDM_InitField( &m_aicdParameterFields[AICD_CRITICAL_WATER_IN_LIQUID_FRAC], - "CriticalWaterLiquidFractionEmul", - QString( "1*" ), - "Critical Water in Liquid Fraction for emulsions" ); - CAF_PDM_InitField( &m_aicdParameterFields[AICD_EMULSION_VISC_TRANS_REGION], - "ViscosityTransitionRegionEmul", - QString( "1*" ), - "Emulsion Viscosity Transition Region" ); - CAF_PDM_InitField( &m_aicdParameterFields[AICD_MAX_RATIO_EMULSION_VISC], - "MaxRatioOfEmulsionVisc", - QString( "1*" ), - "Max Ratio of Emulsion to Continuous Viscosity" ); - CAF_PDM_InitField( &m_aicdParameterFields[AICD_MAX_FLOW_RATE], "MaxFlowRate", QString( "1*" ), "Max Flow Rate for AICD Device (m^3 / day)" ); - CAF_PDM_InitField( &m_aicdParameterFields[AICD_EXP_OIL_FRAC_DENSITY], "ExponentOilDensity", QString( "1*" ), "Density Exponent of Oil Fraction" ); - CAF_PDM_InitField( &m_aicdParameterFields[AICD_EXP_WATER_FRAC_DENSITY], - "ExponentWaterDensity", - QString( "1*" ), - "Density Exponent of Water Fraction" ); - CAF_PDM_InitField( &m_aicdParameterFields[AICD_EXP_GAS_FRAC_DENSITY], "ExponentGasDensity", QString( "1*" ), "Density Exponent of Gas Fraction" ); - CAF_PDM_InitField( &m_aicdParameterFields[AICD_EXP_OIL_FRAC_VISCOSITY], - "ExponentOilViscosity", - QString( "1*" ), - "Viscosity Exponent of Oil Fraction" ); - CAF_PDM_InitField( &m_aicdParameterFields[AICD_EXP_WATER_FRAC_VISCOSITY], - "ExponentWaterViscosity", - QString( "1*" ), - "Viscosity Exponent of Water Fraction" ); - CAF_PDM_InitField( &m_aicdParameterFields[AICD_EXP_GAS_FRAC_VISCOSITY], - "ExponentGasViscosity", - QString( "1*" ), - "Viscosity Exponent of Gas Fraction" ); + CAF_PDM_InitScriptableField( &m_aicdParameterFields[AICD_CRITICAL_WATER_IN_LIQUID_FRAC], + "CriticalWaterLiquidFractionEmul", + QString( "1*" ), + "Critical Water in Liquid Fraction for emulsions" ); + CAF_PDM_InitScriptableField( &m_aicdParameterFields[AICD_EMULSION_VISC_TRANS_REGION], + "ViscosityTransitionRegionEmul", + QString( "1*" ), + "Emulsion Viscosity Transition Region" ); + CAF_PDM_InitScriptableField( &m_aicdParameterFields[AICD_MAX_RATIO_EMULSION_VISC], + "MaxRatioOfEmulsionVisc", + QString( "1*" ), + "Max Ratio of Emulsion to Continuous Viscosity" ); + CAF_PDM_InitScriptableField( &m_aicdParameterFields[AICD_MAX_FLOW_RATE], + "MaxFlowRate", + QString( "1*" ), + "Max Flow Rate for AICD Device (m^3 / day)" ); + CAF_PDM_InitScriptableField( &m_aicdParameterFields[AICD_EXP_OIL_FRAC_DENSITY], + "ExponentOilDensity", + QString( "1*" ), + "Density Exponent of Oil Fraction" ); + CAF_PDM_InitScriptableField( &m_aicdParameterFields[AICD_EXP_WATER_FRAC_DENSITY], + "ExponentWaterDensity", + QString( "1*" ), + "Density Exponent of Water Fraction" ); + CAF_PDM_InitScriptableField( &m_aicdParameterFields[AICD_EXP_GAS_FRAC_DENSITY], + "ExponentGasDensity", + QString( "1*" ), + "Density Exponent of Gas Fraction" ); + CAF_PDM_InitScriptableField( &m_aicdParameterFields[AICD_EXP_OIL_FRAC_VISCOSITY], + "ExponentOilViscosity", + QString( "1*" ), + "Viscosity Exponent of Oil Fraction" ); + CAF_PDM_InitScriptableField( &m_aicdParameterFields[AICD_EXP_WATER_FRAC_VISCOSITY], + "ExponentWaterViscosity", + QString( "1*" ), + "Viscosity Exponent of Water Fraction" ); + CAF_PDM_InitScriptableField( &m_aicdParameterFields[AICD_EXP_GAS_FRAC_VISCOSITY], + "ExponentGasViscosity", + QString( "1*" ), + "Viscosity Exponent of Gas Fraction" ); std::vector allFields = fields(); for ( caf::PdmFieldHandle* field : allFields ) diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathValve.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathValve.cpp index a660054522..e356e13ae2 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathValve.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathValve.cpp @@ -34,6 +34,8 @@ #include "CompletionCommands/RicNewValveTemplateFeature.h" +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmObjectScriptingCapability.h" #include "cafPdmUiDoubleSliderEditor.h" #include "cafPdmUiToolButtonEditor.h" @@ -44,10 +46,10 @@ CAF_PDM_SOURCE_INIT( RimWellPathValve, "WellPathValve" ); //-------------------------------------------------------------------------------------------------- RimWellPathValve::RimWellPathValve() { - CAF_PDM_InitObject( "WellPathValve", ":/ICDValve16x16.png" ); + CAF_PDM_InitScriptableObject( "WellPathValve", ":/ICDValve16x16.png" ); CAF_PDM_InitFieldNoDefault( &m_valveTemplate, "ValveTemplate", "Valve Template" ); - CAF_PDM_InitField( &m_measuredDepth, "StartMeasuredDepth", 0.0, "Start MD" ); + CAF_PDM_InitScriptableField( &m_measuredDepth, "StartMeasuredDepth", 0.0, "Start MD" ); CAF_PDM_InitFieldNoDefault( &m_multipleValveLocations, "ValveLocations", "Valve Locations" ); CAF_PDM_InitField( &m_editValveTemplate, "EditTemplate", false, "Edit" ); CAF_PDM_InitField( &m_createValveTemplate, "CreateTemplate", false, "Create" ); diff --git a/ApplicationLibCode/ProjectDataModel/RimTools.cpp b/ApplicationLibCode/ProjectDataModel/RimTools.cpp index 24f9d54c58..9fe2a60f03 100644 --- a/ApplicationLibCode/ProjectDataModel/RimTools.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimTools.cpp @@ -30,6 +30,7 @@ #include "RimCase.h" #include "RimColorLegend.h" #include "RimColorLegendCollection.h" +#include "RimCompletionTemplateCollection.h" #include "RimEclipseCase.h" #include "RimFaultInView.h" #include "RimFaultInViewCollection.h" @@ -40,6 +41,7 @@ #include "RimSeismicDataCollection.h" #include "RimSeismicDifferenceData.h" #include "RimSurfaceCollection.h" +#include "RimValveTemplateCollection.h" #include "RimViewWindow.h" #include "RimWellLogLasFile.h" #include "RimWellPath.h" @@ -574,6 +576,20 @@ RimWellPath* RimTools::firstWellPath() return nullptr; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimValveTemplateCollection* RimTools::valveTemplateCollection() +{ + auto proj = RimProject::current(); + if ( !proj ) return nullptr; + + auto oilField = proj->activeOilField(); + if ( !oilField ) return nullptr; + + auto compColl = oilField->completionTemplateCollection(); + return compColl ? compColl->valveTemplateCollection() : nullptr; +} //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationLibCode/ProjectDataModel/RimTools.h b/ApplicationLibCode/ProjectDataModel/RimTools.h index 3efc5340cf..6f63369b1b 100644 --- a/ApplicationLibCode/ProjectDataModel/RimTools.h +++ b/ApplicationLibCode/ProjectDataModel/RimTools.h @@ -38,6 +38,7 @@ class PdmObjectHandle; class RimGeoMechCase; class RimEclipseCase; class RimWellPathCollection; +class RimValveTemplateCollection; class RimCase; class RimWellPath; class RimSurfaceCollection; @@ -77,6 +78,8 @@ public: static RimWellPathCollection* wellPathCollection(); static RimWellPath* firstWellPath(); + static RimValveTemplateCollection* valveTemplateCollection(); + static RimSurfaceCollection* surfaceCollection(); static RimPolygonCollection* polygonCollection(); static RimAutomationSettings* automationSettings(); diff --git a/ApplicationLibCode/ProjectDataModelCommands/CMakeLists_files.cmake b/ApplicationLibCode/ProjectDataModelCommands/CMakeLists_files.cmake index badf6c31a8..4dc08c174d 100644 --- a/ApplicationLibCode/ProjectDataModelCommands/CMakeLists_files.cmake +++ b/ApplicationLibCode/ProjectDataModelCommands/CMakeLists_files.cmake @@ -31,6 +31,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RimcFishbonesCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimcPolygonCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimcRegularSurface.h + ${CMAKE_CURRENT_LIST_DIR}/RimcPerforationInterval.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -66,6 +67,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RimcFishbonesCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimcPolygonCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimcRegularSurface.cpp + ${CMAKE_CURRENT_LIST_DIR}/RimcPerforationInterval.cpp ) list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/ProjectDataModelCommands/RimcPerforationInterval.cpp b/ApplicationLibCode/ProjectDataModelCommands/RimcPerforationInterval.cpp new file mode 100644 index 0000000000..0d796642de --- /dev/null +++ b/ApplicationLibCode/ProjectDataModelCommands/RimcPerforationInterval.cpp @@ -0,0 +1,83 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimcPerforationInterval.h" + +#include "RimEclipseCase.h" +#include "RimPerforationCollection.h" +#include "RimPerforationInterval.h" +#include "RimTools.h" +#include "RimWellPathCollection.h" +#include "RimWellPathValve.h" + +#include "cafPdmAbstractFieldScriptingCapability.h" +#include "cafPdmFieldScriptingCapability.h" + +#include + +CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimPerforationInterval, RimcPerforationInterval_addValve, "AddValve" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimcPerforationInterval_addValve::RimcPerforationInterval_addValve( caf::PdmObjectHandle* self ) + : caf::PdmObjectCreationMethod( self ) +{ + CAF_PDM_InitObject( "Add StimPlan Fracture", "", "", "Add StimPlan Fracture" ); + + CAF_PDM_InitScriptableField( &m_startMd, "StartMd", 0.0, "Start Measured Depth" ); + CAF_PDM_InitScriptableField( &m_endMd, "EndMd", 0.0, "End Measured Depth" ); + CAF_PDM_InitScriptableField( &m_valveCount, "ValveCount", 1, "Valve Count" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_template, "Template", "", "", "", "Valve Template" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::expected RimcPerforationInterval_addValve::execute() +{ + auto perfInterval = self(); + + if ( m_startMd() > m_endMd() ) return std::unexpected( "Start MD must be smaller that end MD." ); + if ( m_valveCount() < 1 ) return std::unexpected( "Valve count must be larger than zero" ); + + RimWellPathValve* valve = new RimWellPathValve; + + valve->setValveTemplate( m_template() ); + perfInterval->addValve( valve ); + + double spacing = std::abs( m_startMd() - m_endMd() ) / m_valveCount(); + + valve->setMeasuredDepthAndCount( m_startMd(), spacing, m_valveCount() ); + valve->applyValveLabelAndIcon(); + + RimWellPathCollection* wellPathCollection = RimTools::wellPathCollection(); + + wellPathCollection->uiCapability()->updateConnectedEditors(); + wellPathCollection->scheduleRedrawAffectedViews(); + + return valve; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimcPerforationInterval_addValve::classKeywordReturnedType() const +{ + return RimWellPathValve::classKeywordStatic(); +} diff --git a/ApplicationLibCode/ProjectDataModelCommands/RimcPerforationInterval.h b/ApplicationLibCode/ProjectDataModelCommands/RimcPerforationInterval.h new file mode 100644 index 0000000000..872221094c --- /dev/null +++ b/ApplicationLibCode/ProjectDataModelCommands/RimcPerforationInterval.h @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObjectHandle.h" +#include "cafPdmObjectMethod.h" +#include "cafPdmPtrField.h" + +#include + +class RimValveTemplate; + +//================================================================================================== +/// +//================================================================================================== +class RimcPerforationInterval_addValve : public caf::PdmObjectCreationMethod +{ + CAF_PDM_HEADER_INIT; + +public: + RimcPerforationInterval_addValve( caf::PdmObjectHandle* self ); + + std::expected execute() override; + QString classKeywordReturnedType() const override; + +private: + caf::PdmPtrField m_template; + caf::PdmField m_startMd; + caf::PdmField m_endMd; + caf::PdmField m_valveCount; +}; diff --git a/ApplicationLibCode/ProjectDataModelCommands/RimcProject.cpp b/ApplicationLibCode/ProjectDataModelCommands/RimcProject.cpp index 3709436e35..387cd54baf 100644 --- a/ApplicationLibCode/ProjectDataModelCommands/RimcProject.cpp +++ b/ApplicationLibCode/ProjectDataModelCommands/RimcProject.cpp @@ -37,6 +37,7 @@ #include "RimSummaryCase.h" #include "RimSurfaceCollection.h" #include "RimTools.h" +#include "RimValveTemplateCollection.h" #include "RimWellPathCollection.h" #include "RiuMainWindow.h" @@ -319,3 +320,36 @@ QString RimProject_wellPathCollection::classKeywordReturnedType() const { return RimWellPathCollection::classKeywordStatic(); } + +CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimProject, RimProject_valveTemplates, "valveTemplates" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimProject_valveTemplates::RimProject_valveTemplates( caf::PdmObjectHandle* self ) + : PdmObjectMethod( self, PdmObjectMethod::NullPointerType::NULL_IS_INVALID, PdmObjectMethod::ResultType::PERSISTENT_TRUE ) +{ + CAF_PDM_InitObject( "Get Valve Template Collection", "", "", "Get Valve Template Collection" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::expected RimProject_valveTemplates::execute() +{ + auto valveTemplateCollection = RimTools::valveTemplateCollection(); + if ( !valveTemplateCollection ) + { + return std::unexpected( "No valve template collection found." ); + } + + return valveTemplateCollection; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimProject_valveTemplates::classKeywordReturnedType() const +{ + return RimValveTemplateCollection::classKeywordStatic(); +} diff --git a/ApplicationLibCode/ProjectDataModelCommands/RimcProject.h b/ApplicationLibCode/ProjectDataModelCommands/RimcProject.h index 54580394cf..1ccdf3240f 100644 --- a/ApplicationLibCode/ProjectDataModelCommands/RimcProject.h +++ b/ApplicationLibCode/ProjectDataModelCommands/RimcProject.h @@ -113,3 +113,17 @@ public: std::expected execute() override; QString classKeywordReturnedType() const override; }; + +//================================================================================================== +/// +//================================================================================================== +class RimProject_valveTemplates : public caf::PdmObjectMethod +{ + CAF_PDM_HEADER_INIT; + +public: + RimProject_valveTemplates( caf::PdmObjectHandle* self ); + + std::expected execute() override; + QString classKeywordReturnedType() const override; +}; diff --git a/GrpcInterface/Python/rips/PythonExamples/wells_and_fractures/modeled_well_path.py b/GrpcInterface/Python/rips/PythonExamples/wells_and_fractures/modeled_well_path.py index 32cf81405d..1a67be9e25 100644 --- a/GrpcInterface/Python/rips/PythonExamples/wells_and_fractures/modeled_well_path.py +++ b/GrpcInterface/Python/rips/PythonExamples/wells_and_fractures/modeled_well_path.py @@ -31,7 +31,20 @@ target = geometry.append_well_target(coord) coord = [1054.28, 250, -50] target = geometry.append_well_target(coord) -well_path.append_perforation_interval(3300, 3350, 0.2, 0.76) +perforation = well_path.append_perforation_interval(3300, 3350, 0.2, 0.76) + +# Make some changes to the AICD parameters of the valve template +valve_templates = resinsight.project.valve_templates() +aicd_template = valve_templates.valve_definitions()[0] +aicd_parameters = aicd_template.aicd_parameters() +aicd_parameters.max_flow_rate = "899.43" +aicd_parameters.density_calibration_fluid = "45.5" +aicd_parameters.update() + +# Add a valve to the perforation interval +valve = perforation.add_valve( + template=aicd_template, start_md=3310, end_md=3340, valve_count=2 +) # Update skin factor of the perforation diff --git a/GrpcInterface/Python/rips/tests/test_wells.py b/GrpcInterface/Python/rips/tests/test_wells.py index 04cf7f3f1d..fde3c1f342 100644 --- a/GrpcInterface/Python/rips/tests/test_wells.py +++ b/GrpcInterface/Python/rips/tests/test_wells.py @@ -116,3 +116,108 @@ def test_10k_intersection_trajectory_properties(rips_instance, initialize_test): assert "azimuth" in result assert "inclination" in result assert "dogleg" in result + + +def test_10k_intersection_add_well_perforation_interval_with_valves( + rips_instance, initialize_test +): + case_root_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC" + case_path = case_root_path + "/TEST10K_FLT_LGR_NNC.EGRID" + case = rips_instance.project.load_case(path=case_path) + assert len(case.grids()) == 2 + well_path_files = [ + case_root_path + "/wellpath_a.dev", + ] + + well_path_names = rips_instance.project.import_well_paths(well_path_files) + assert len(well_path_names) == 1 + wells = rips_instance.project.well_paths() + well_path = wells[0] + + result = well_path.trajectory_properties(resampling_interval=10.0) + + measured_depths = result["measured_depth"] + + start_md = measured_depths[len(measured_depths) - 3] + end_md = measured_depths[len(measured_depths) - 2] + diameter = 0.25 + skin_factor = 0.1 + + perf_interval = well_path.append_perforation_interval( + start_md, end_md, diameter, skin_factor + ) + + assert perf_interval.start_measured_depth == start_md + assert perf_interval.end_measured_depth == end_md + assert perf_interval.diameter == diameter + assert perf_interval.skin_factor == skin_factor + + valve_templates = rips_instance.project.valve_templates() + assert len(valve_templates.valve_definitions()) == 3 + + assert len(perf_interval.valves()) == 0 + + valve_start_md = start_md + 1 + valve_end_md = end_md - 1 + valve_count = 1 + valve = perf_interval.add_valve( + template=valve_templates.valve_definitions()[0], + start_md=valve_start_md, + end_md=valve_end_md, + valve_count=valve_count, + ) + + assert valve + assert valve.name == "1 AICD: 2451 - 2459" + + assert len(perf_interval.valves()) == 1 + + +def test_10k_intersection_add_well_perforation_interval_with_invalid_valves( + rips_instance, initialize_test +): + case_root_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC" + case_path = case_root_path + "/TEST10K_FLT_LGR_NNC.EGRID" + case = rips_instance.project.load_case(path=case_path) + assert len(case.grids()) == 2 + well_path_files = [ + case_root_path + "/wellpath_a.dev", + ] + + well_path_names = rips_instance.project.import_well_paths(well_path_files) + assert len(well_path_names) == 1 + wells = rips_instance.project.well_paths() + well_path = wells[0] + + result = well_path.trajectory_properties(resampling_interval=10.0) + + measured_depths = result["measured_depth"] + + start_md = measured_depths[len(measured_depths) - 3] + end_md = measured_depths[len(measured_depths) - 2] + diameter = 0.25 + skin_factor = 0.1 + + perf_interval = well_path.append_perforation_interval( + start_md, end_md, diameter, skin_factor + ) + + valve_templates = rips_instance.project.valve_templates() + + with pytest.raises(rips.RipsError): + # end_md < start_md + valve = perf_interval.add_valve( + template=valve_templates.valve_definitions()[0], + start_md=1000, + end_md=800, + valve_count=1, + ) + + with pytest.raises(rips.RipsError): + # zero valves + valve = perf_interval.add_valve( + template=valve_templates.valve_definitions()[0], + start_md=400, + end_md=800, + valve_count=0, + )