#14772 Python: Add Reservoir.export_completions as object method and forward exportWellPathCompletions to it

RimEclipseCase_exportCompletions takes WellPath objects (empty list
means all visible well paths) and an explicit export folder, and
exposes all completion export settings. The existing enums
ExportSplit, CompdatExport and PressureDepletionWBHPSource are
registered as Python StrEnums CompletionExportSplit,
CompdatExportType and TransScalingWbhpSource.

RicfExportWellPathCompletions resolves well path names to objects and
the export folder from the command file executor, then forwards to the
object method. Case.export_well_path_completions() in Python is kept
and emits a DeprecationWarning.
This commit is contained in:
Kristian Bendiksen committed 2026-09-22 14:19:23 +02:00
1 parent 001a515c68
commit afe8f39f6b
6 files changed
+437 -70

No files matched your search

@@ -18,21 +18,18 @@
#include "RicfExportWellPathCompletions.h"
#include "RicfApplicationTools.h"
#include "RicfCommandFileExecutor.h"
#include "RicfCommandForwarding.h"
#include "RiaApplication.h"
#include "RiaLogging.h"
#include "RimDialogData.h"
#include "RimEclipseCase.h"
#include "RimEclipseCaseCollection.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimWellPath.h"
#include "RimWellPathCollection.h"
#include "CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h"
#include "RimcEclipseCase.h"
#include "cafPdmFieldScriptingCapability.h"
@@ -83,38 +80,20 @@ RicfExportWellPathCompletions::RicfExportWellPathCompletions()
//--------------------------------------------------------------------------------------------------
caf::PdmScriptResponse RicfExportWellPathCompletions::execute()
{
using TOOLS = RicfApplicationTools;
const QString commandName = classKeyword();
RicExportCompletionDataSettingsUi exportSettings;
auto rimCase = RicfForwarding::findCase( m_caseId() );
if ( !rimCase ) return RicfForwarding::errorResponse( rimCase.error(), commandName );
if ( m_timeStep < 0 )
auto* eclipseCase = dynamic_cast<RimEclipseCase*>( rimCase.value() );
if ( !eclipseCase )
{
exportSettings.timeStep = 0;
}
else
{
exportSettings.timeStep = m_timeStep;
return RicfForwarding::errorResponse( QString( "Case with ID %1 is not an Eclipse case" ).arg( m_caseId() ), commandName );
}
exportSettings.fileSplit = m_fileSplit;
exportSettings.compdatExport = m_compdatExport;
exportSettings.performTransScaling = m_performTransScaling;
exportSettings.transScalingTimeStep = m_transScalingTimeStep;
exportSettings.transScalingWBHPSource = m_transScalingInitialWBHP;
exportSettings.transScalingWBHP = m_transScalingWBHP;
exportSettings.includeMsw = m_includeMsw;
exportSettings.useLateralNTG = m_useLateralNTG;
exportSettings.includePerforations = m_includePerforations;
exportSettings.includeFishbones = m_includeFishbones;
exportSettings.excludeMainBoreForFishbones = m_excludeMainBoreForFishbones;
exportSettings.includeFractures = m_includeFractures;
exportSettings.setExportDataSourceAsComment( m_exportDataSourceAsComments );
exportSettings.setExportWelspec( m_exportWelspec );
// Resolve the export folder and custom file name. The Rimc method requires an explicit folder.
QString exportFolderPath;
QString customFileName;
if ( m_customFileNameIncludingPath().isEmpty() )
{
exportFolderPath = RicfCommandFileExecutor::instance()->getExportPath( RicfCommandFileExecutor::ExportType::COMPLETIONS );
@@ -125,10 +104,8 @@ caf::PdmScriptResponse RicfExportWellPathCompletions::execute()
}
else
{
QFileInfo fi( m_customFileNameIncludingPath );
auto fileName = fi.fileName();
exportSettings.setCustomFileName( fileName );
QFileInfo fi( m_customFileNameIncludingPath() );
customFileName = fi.fileName();
auto pathCandidate = fi.path();
if ( pathCandidate.size() > 2 )
@@ -137,51 +114,50 @@ caf::PdmScriptResponse RicfExportWellPathCompletions::execute()
}
}
exportSettings.folder = exportFolderPath;
{
auto eclipseCase = TOOLS::caseFromId( m_caseId() );
if ( !eclipseCase )
{
QString error = QString( "exportWellPathCompletions: Could not find case with ID %1" ).arg( m_caseId() );
RiaLogging::error( error.toStdString() );
return caf::PdmScriptResponse( caf::PdmScriptResponse::COMMAND_ERROR, error );
}
exportSettings.caseToApply = eclipseCase;
}
caf::PdmScriptResponse response;
// Resolve well path names to objects. Unknown names are warnings, matching the legacy behavior.
std::vector<RimWellPath*> wellPaths;
if ( m_wellPathNames().empty() )
for ( const QString& wellPathName : m_wellPathNames() )
{
for ( auto wellPath : RimProject::current()->activeOilField()->wellPathCollection->allWellPaths() )
RimWellPath* wellPath = RimProject::current()->activeOilField()->wellPathCollection->wellPathByName( wellPathName );
if ( wellPath )
{
if ( wellPath->showWellPath() )
{
wellPaths.push_back( wellPath );
}
wellPaths.push_back( wellPath );
}
}
else
{
for ( const QString& wellPathName : m_wellPathNames() )
else
{
RimWellPath* wellPath = RimProject::current()->activeOilField()->wellPathCollection->wellPathByName( wellPathName );
if ( wellPath )
{
wellPaths.push_back( wellPath );
}
else
{
QString warning = QString( "exportWellPathCompletions: Could not find well path with name %1" ).arg( wellPathName );
RiaLogging::warning( warning.toStdString() );
response.updateStatus( caf::PdmScriptResponse::COMMAND_WARNING, warning );
}
QString warning = QString( "%1: Could not find well path with name %2" ).arg( commandName ).arg( wellPathName );
RiaLogging::warning( warning.toStdString() );
response.updateStatus( caf::PdmScriptResponse::COMMAND_WARNING, warning );
}
}
RicWellPathExportCompletionDataFeatureImpl::exportCompletions( wellPaths, exportSettings );
// Legacy behavior: if names were given but none resolved, nothing is exported (not all visible wells)
if ( !m_wellPathNames().empty() && wellPaths.empty() ) return response;
RimEclipseCase_exportCompletions method( eclipseCase );
method.setWellPaths( wellPaths );
method.setTimeStep( m_timeStep() );
method.setExportFolder( exportFolderPath );
method.setCustomFileName( customFileName );
method.setFileSplit( m_fileSplit() );
method.setCompdatExport( m_compdatExport() );
method.setIncludeMsw( m_includeMsw() );
method.setUseNtgHorizontally( m_useLateralNTG() );
method.setIncludePerforations( m_includePerforations() );
method.setIncludeFishbones( m_includeFishbones() );
method.setIncludeFractures( m_includeFractures() );
method.setExcludeMainBoreForFishbones( m_excludeMainBoreForFishbones() );
method.setPerformTransScaling( m_performTransScaling() );
method.setTransScalingTimeStep( m_transScalingTimeStep() );
method.setTransScalingWbhpSource( m_transScalingInitialWBHP() );
method.setTransScalingWbhp( m_transScalingWBHP() );
method.setExportComments( m_exportDataSourceAsComments() );
method.setExportWelspec( m_exportWelspec() );
auto result = method.execute();
if ( !result ) return RicfForwarding::errorResponse( result.error(), commandName );
return response;
}
@@ -26,6 +26,8 @@
#include "RimWellPath.h"
#include "RimWellPathCompletions.h"
#include "cafPdmScriptEnumNameRegistry.h"
namespace caf
{
template <>
@@ -56,6 +58,22 @@ void RicExportCompletionDataSettingsUi::TransScalingWBHPSource::setUp()
}
} // namespace caf
namespace
{
// Pin the Python StrEnum class names for the export settings used by RimEclipseCase_exportCompletions
struct RegisterScriptEnumNames
{
RegisterScriptEnumNames()
{
caf::PdmScriptEnumNameRegistry::registerName<RicExportCompletionDataSettingsUi::ExportSplit>( "CompletionExportSplit" );
caf::PdmScriptEnumNameRegistry::registerName<RicExportCompletionDataSettingsUi::CompdatExport>( "CompdatExportType" );
caf::PdmScriptEnumNameRegistry::registerName<RicExportFractureCompletionsImpl::PressureDepletionWBHPSource>(
"TransScalingWbhpSource" );
}
};
const RegisterScriptEnumNames s_registerScriptEnumNames;
} // namespace
CAF_PDM_SOURCE_INIT( RicExportCompletionDataSettingsUi, "RicExportCompletionDataSettingsUi" );
//--------------------------------------------------------------------------------------------------
@@ -22,6 +22,7 @@
#include "RiaGuiApplication.h"
#include "RiaKeyValueStoreUtil.h"
#include "CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h"
#include "ExportCommands/RicEclipseCellResultToFileImpl.h"
#include "RifInputPropertyLoader.h"
@@ -42,8 +43,11 @@
#include "RimCellFilter.h"
#include "RimEclipseCase.h"
#include "RimEclipseResultCase.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimRoffCase.h"
#include "RimWellPath.h"
#include "RimWellPathCollection.h"
#include "RimcDataContainerString.h"
@@ -559,3 +563,268 @@ std::expected<caf::PdmObjectHandle*, QString> RimEclipseCase_exportProperty::exe
return nullptr;
}
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimEclipseCase, RimEclipseCase_exportCompletions, "exportCompletions" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEclipseCase_exportCompletions::RimEclipseCase_exportCompletions( caf::PdmObjectHandle* self )
: caf::PdmVoidObjectMethod( self )
{
CAF_PDM_InitObject( "Export Completions", "", "", "Export completion data (COMPDAT, WELSPECS, MSW keywords etc.) for well paths in this case" );
CAF_PDM_InitScriptableFieldNoDefault( &m_wellPaths,
"WellPaths",
"Well Paths",
"",
"",
"Well paths to export. Empty list exports all visible well paths." );
CAF_PDM_InitScriptableField( &m_timeStep, "TimeStep", 0, "Time Step", "", "", "Zero-based time step index" );
CAF_PDM_InitScriptableField( &m_exportFolder, "ExportFolder", QString(), "Export Folder", "", "", "Folder to write the export files to" );
CAF_PDM_InitScriptableField( &m_customFileName,
"CustomFileName",
QString(),
"Custom File Name",
"",
"",
"Optional file name (without folder) used when FileSplit is UNIFIED_FILE" );
CAF_PDM_InitScriptableField( &m_fileSplit,
"FileSplit",
RicExportCompletionDataSettingsUi::ExportSplitType(),
"File Split",
"",
"",
"Controls how export data is split into files" );
CAF_PDM_InitScriptableField( &m_compdatExport,
"CompdatExport",
RicExportCompletionDataSettingsUi::CompdatExportType(),
"Compdat Export",
"",
"",
"Compdat export type" );
CAF_PDM_InitScriptableField( &m_includeMsw, "IncludeMsw", true, "Include MSW", "", "", "Export Multi Segment Well model" );
CAF_PDM_InitScriptableField( &m_useNtgHorizontally, "UseNtgHorizontally", false, "Use NTG Horizontally" );
CAF_PDM_InitScriptableField( &m_includePerforations, "IncludePerforations", true, "Include Perforations" );
CAF_PDM_InitScriptableField( &m_includeFishbones, "IncludeFishbones", true, "Include Fishbones" );
CAF_PDM_InitScriptableField( &m_includeFractures, "IncludeFractures", true, "Include Fractures" );
CAF_PDM_InitScriptableField( &m_excludeMainBoreForFishbones, "ExcludeMainBoreForFishbones", false, "Exclude Main Bore for Fishbones" );
CAF_PDM_InitScriptableField( &m_performTransScaling, "PerformTransScaling", false, "Perform Transmissibility Scaling" );
CAF_PDM_InitScriptableField( &m_transScalingTimeStep, "TransScalingTimeStep", 0, "Transmissibility Scaling Pressure Time Step" );
CAF_PDM_InitScriptableField( &m_transScalingWbhpSource,
"TransScalingWbhpSource",
RicExportCompletionDataSettingsUi::TransScalingWBHPSource(),
"Transmissibility Scaling WBHP Source" );
CAF_PDM_InitScriptableField( &m_transScalingWbhp, "TransScalingWbhp", 200.0, "Transmissibility Scaling Constant WBHP Value" );
CAF_PDM_InitScriptableField( &m_exportComments, "ExportComments", true, "Export Comments", "", "", "Export data source as comments" );
CAF_PDM_InitScriptableField( &m_exportWelspec, "ExportWelspec", true, "Export WELSPEC", "", "", "Export WELSPEC keyword" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setWellPaths( const std::vector<RimWellPath*>& wellPaths )
{
m_wellPaths.setValue( wellPaths );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setTimeStep( int timeStep )
{
m_timeStep = timeStep;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setExportFolder( const QString& exportFolder )
{
m_exportFolder = exportFolder;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setCustomFileName( const QString& customFileName )
{
m_customFileName = customFileName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setFileSplit( RicExportCompletionDataSettingsUi::ExportSplit fileSplit )
{
m_fileSplit = fileSplit;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setCompdatExport( RicExportCompletionDataSettingsUi::CompdatExport compdatExport )
{
m_compdatExport = compdatExport;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setIncludeMsw( bool enable )
{
m_includeMsw = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setUseNtgHorizontally( bool enable )
{
m_useNtgHorizontally = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setIncludePerforations( bool enable )
{
m_includePerforations = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setIncludeFishbones( bool enable )
{
m_includeFishbones = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setIncludeFractures( bool enable )
{
m_includeFractures = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setExcludeMainBoreForFishbones( bool enable )
{
m_excludeMainBoreForFishbones = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setPerformTransScaling( bool enable )
{
m_performTransScaling = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setTransScalingTimeStep( int timeStep )
{
m_transScalingTimeStep = timeStep;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setTransScalingWbhpSource( RicExportFractureCompletionsImpl::PressureDepletionWBHPSource source )
{
m_transScalingWbhpSource = source;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setTransScalingWbhp( double wbhp )
{
m_transScalingWbhp = wbhp;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setExportComments( bool enable )
{
m_exportComments = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase_exportCompletions::setExportWelspec( bool enable )
{
m_exportWelspec = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::expected<caf::PdmObjectHandle*, QString> RimEclipseCase_exportCompletions::execute()
{
auto* eclipseCase = self<RimEclipseCase>();
if ( !eclipseCase ) return std::unexpected( "No case is available." );
if ( m_exportFolder().isEmpty() ) return std::unexpected( "No export folder specified." );
QDir folder( m_exportFolder() );
if ( !folder.exists() ) return std::unexpected( QString( "The export folder '%1' does not exist." ).arg( m_exportFolder() ) );
eclipseCase->ensureReservoirCaseIsOpen();
if ( !eclipseCase->eclipseCaseData() )
{
return std::unexpected( QString( "No data available for case '%1'" ).arg( eclipseCase->caseUserDescription() ) );
}
std::vector<RimWellPath*> wellPaths = m_wellPaths.ptrReferencedObjectsByType();
if ( wellPaths.empty() )
{
RimProject* project = RimProject::current();
for ( RimWellPath* wellPath : project->activeOilField()->wellPathCollection->allWellPaths() )
{
if ( wellPath->showWellPath() ) wellPaths.push_back( wellPath );
}
}
if ( wellPaths.empty() ) return std::unexpected( "No well paths to export." );
RicExportCompletionDataSettingsUi exportSettings;
exportSettings.caseToApply = eclipseCase;
exportSettings.folder = m_exportFolder();
exportSettings.timeStep = std::max( 0, m_timeStep() );
exportSettings.fileSplit = m_fileSplit();
exportSettings.compdatExport = m_compdatExport();
exportSettings.performTransScaling = m_performTransScaling();
exportSettings.transScalingTimeStep = m_transScalingTimeStep();
exportSettings.transScalingWBHPSource = m_transScalingWbhpSource();
exportSettings.transScalingWBHP = m_transScalingWbhp();
exportSettings.includeMsw = m_includeMsw();
exportSettings.useLateralNTG = m_useNtgHorizontally();
exportSettings.includePerforations = m_includePerforations();
exportSettings.includeFishbones = m_includeFishbones();
exportSettings.excludeMainBoreForFishbones = m_excludeMainBoreForFishbones();
exportSettings.includeFractures = m_includeFractures();
exportSettings.setExportDataSourceAsComment( m_exportComments() );
exportSettings.setExportWelspec( m_exportWelspec() );
if ( !m_customFileName().isEmpty() ) exportSettings.setCustomFileName( m_customFileName() );
RicWellPathExportCompletionDataFeatureImpl::exportCompletions( wellPaths, exportSettings );
return nullptr;
}
@@ -21,15 +21,19 @@
#include "RiaDefines.h"
#include "RiaPorosityModel.h"
#include "CompletionExportCommands/RicExportCompletionDataSettingsUi.h"
#include "cafAppEnum.h"
#include "cafPdmField.h"
#include "cafPdmObjectHandle.h"
#include "cafPdmObjectMethod.h"
#include "cafPdmPtrArrayField.h"
#include "cafPdmPtrField.h"
#include <QString>
class RimCellFilter;
class RimWellPath;
//==================================================================================================
///
@@ -187,3 +191,59 @@ private:
caf::PdmField<double> m_undefinedValue;
caf::PdmField<QString> m_exportFile;
};
//==================================================================================================
/// Export completion data (COMPDAT, WELSPECS, MSW keywords etc.) for well paths in this case.
//==================================================================================================
class RimEclipseCase_exportCompletions : public caf::PdmVoidObjectMethod
{
CAF_PDM_HEADER_INIT;
public:
RimEclipseCase_exportCompletions( caf::PdmObjectHandle* self );
void setWellPaths( const std::vector<RimWellPath*>& wellPaths );
void setTimeStep( int timeStep );
void setExportFolder( const QString& exportFolder );
void setCustomFileName( const QString& customFileName );
void setFileSplit( RicExportCompletionDataSettingsUi::ExportSplit fileSplit );
void setCompdatExport( RicExportCompletionDataSettingsUi::CompdatExport compdatExport );
void setIncludeMsw( bool enable );
void setUseNtgHorizontally( bool enable );
void setIncludePerforations( bool enable );
void setIncludeFishbones( bool enable );
void setIncludeFractures( bool enable );
void setExcludeMainBoreForFishbones( bool enable );
void setPerformTransScaling( bool enable );
void setTransScalingTimeStep( int timeStep );
void setTransScalingWbhpSource( RicExportFractureCompletionsImpl::PressureDepletionWBHPSource source );
void setTransScalingWbhp( double wbhp );
void setExportComments( bool enable );
void setExportWelspec( bool enable );
std::expected<caf::PdmObjectHandle*, QString> execute() override;
private:
caf::PdmPtrArrayField<RimWellPath*> m_wellPaths;
caf::PdmField<int> m_timeStep;
caf::PdmField<QString> m_exportFolder;
caf::PdmField<QString> m_customFileName;
caf::PdmField<RicExportCompletionDataSettingsUi::ExportSplitType> m_fileSplit;
caf::PdmField<RicExportCompletionDataSettingsUi::CompdatExportType> m_compdatExport;
caf::PdmField<bool> m_includeMsw;
caf::PdmField<bool> m_useNtgHorizontally;
caf::PdmField<bool> m_includePerforations;
caf::PdmField<bool> m_includeFishbones;
caf::PdmField<bool> m_includeFractures;
caf::PdmField<bool> m_excludeMainBoreForFishbones;
caf::PdmField<bool> m_performTransScaling;
caf::PdmField<int> m_transScalingTimeStep;
caf::PdmField<RicExportCompletionDataSettingsUi::TransScalingWBHPSource> m_transScalingWbhpSource;
caf::PdmField<double> m_transScalingWbhp;
caf::PdmField<bool> m_exportComments;
caf::PdmField<bool> m_exportWelspec;
};
+7
View File
@@ -458,7 +458,14 @@ def export_well_path_completions(
"TRANSMISSIBILITIES" | Direct export of transmissibilities
"WPIMULT_AND_DEFAULT_CONNECTION_FACTORS" | Include WPIMULT in addition to transmissibilities
Deprecated: use Reservoir.export_completions(well_paths=[...], export_folder=...) instead,
which takes WellPath objects and an explicit export folder.
"""
warnings.warn(
"Case.export_well_path_completions() is deprecated, use Reservoir.export_completions() instead",
DeprecationWarning,
stacklevel=3,
)
if isinstance(well_path_names, str):
well_path_names = [well_path_names]
return self._execute_command(
@@ -1,5 +1,6 @@
import sys
import os
import pytest
import tempfile
sys.path.insert(1, os.path.join(sys.path[0], "../../"))
@@ -25,6 +26,42 @@ def test_10k(rips_instance, initialize_test):
)
def test_export_completions(rips_instance, initialize_test):
case_root_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC"
project_path = case_root_path + "/well_completions_pytest.rsp"
project = rips_instance.project.open(path=project_path)
case = project.cases()[0]
well_path = project.well_path_by_name("Well-1")
assert well_path is not None
with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname:
case.export_completions(
well_paths=[well_path],
time_step=1,
export_folder=tmpdirname,
file_split=rips.CompletionExportSplit.UNIFIED_FILE,
custom_file_name="my_completions.sch",
)
files = os.listdir(tmpdirname)
assert "my_completions.sch" in files
with open(os.path.join(tmpdirname, "my_completions.sch")) as f:
content = f.read()
assert "COMPDAT" in content
assert "WELSPECS" in content
with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname:
# Empty list exports all visible well paths, split on well
case.export_completions(time_step=1, export_folder=tmpdirname)
files = os.listdir(tmpdirname)
assert len(files) >= 1
with pytest.raises(rips.RipsError):
case.export_completions(well_paths=[well_path])
with pytest.raises(rips.RipsError):
case.export_completions(well_paths=[well_path], export_folder="/does/not/exist")
def test_add_well_path_completions(rips_instance, initialize_test):
well_path_coll = rips_instance.project.well_path_collection()