mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-24 22:27:55 -05:00
#14772 Python: Add Reservoir.create_multiple_fractures as object method and forward createMultipleFractures to it
RimEclipseCase_createMultipleFractures takes WellPath objects and a FractureTemplate object instead of names and ids. The MultipleFractures::Action enum is moved from the Ricf header to RicCreateMultipleFracturesFeature.h so the object method does not depend on CommandFileInterface, and is registered as the Python StrEnum MultipleFracturesAction. Add RicfForwarding::findFractureTemplate(). RicfCreateMultipleFractures resolves names/ids and forwards to the object method. The hand-written Case.create_multiple_fractures(template_id=..., well_path_names=...) Python wrapper is removed: the generated Reservoir method has the same name and shadows it. The test is updated to the object based signature.
This commit is contained in:
1 parent
afa816826b
commit
6e3e6e738f
10 files changed
+330
-194
No files matched your search
@@ -23,6 +23,7 @@
|
||||
#include "Rim3dView.h"
|
||||
#include "RimCase.h"
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "RimFractureTemplate.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
#include "cafPdmObjectHandle.h"
|
||||
@@ -85,6 +86,22 @@ std::expected<Rim3dView*, QString> RicfForwarding::findView( int viewId )
|
||||
return std::unexpected( QString( "Could not find view with ID %1" ).arg( viewId ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::expected<RimFractureTemplate*, QString> RicfForwarding::findFractureTemplate( int templateId )
|
||||
{
|
||||
RimProject* project = RimProject::current();
|
||||
if ( !project ) return std::unexpected( "No project is available." );
|
||||
|
||||
for ( RimFractureTemplate* fractureTemplate : project->allFractureTemplates() )
|
||||
{
|
||||
if ( fractureTemplate && fractureTemplate->id() == templateId ) return fractureTemplate;
|
||||
}
|
||||
|
||||
return std::unexpected( QString( "Could not find fracture template with ID %1" ).arg( templateId ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
class RimCase;
|
||||
class Rim3dView;
|
||||
class RimFractureTemplate;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
@@ -48,6 +49,9 @@ std::expected<Rim3dView*, QString> findView( RimCase* rimCase, int viewId );
|
||||
/// Find a 3D view by id anywhere in the project. A negative id is not accepted.
|
||||
std::expected<Rim3dView*, QString> findView( int viewId );
|
||||
|
||||
/// Find a fracture template by id.
|
||||
std::expected<RimFractureTemplate*, QString> findFractureTemplate( int templateId );
|
||||
|
||||
/// Convert the result of a Rimc method execution to a script response, logging errors with the command name.
|
||||
caf::PdmScriptResponse toScriptResponse( const std::expected<caf::PdmObjectHandle*, QString>& result, const QString& commandName );
|
||||
|
||||
|
||||
@@ -19,41 +19,17 @@
|
||||
#include "RicfCreateMultipleFractures.h"
|
||||
|
||||
#include "RicfApplicationTools.h"
|
||||
#include "RicfCommandFileExecutor.h"
|
||||
#include "RicfCommandForwarding.h"
|
||||
|
||||
#include "FractureCommands/RicCreateMultipleFracturesFeature.h"
|
||||
#include "FractureCommands/RicCreateMultipleFracturesOptionItemUi.h"
|
||||
#include "FractureCommands/RicCreateMultipleFracturesUi.h"
|
||||
|
||||
#include "RimDialogData.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseCaseCollection.h"
|
||||
#include "RimFractureTemplate.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimcEclipseCase.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaQStringFormatter.h"
|
||||
#include "RiaWellNameComparer.h"
|
||||
|
||||
#include "cafCmdFeatureManager.h"
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RicfCreateMultipleFractures, "createMultipleFractures" );
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
void AppEnum<MultipleFractures::Action>::setUp()
|
||||
{
|
||||
addItem( MultipleFractures::Action::APPEND_FRACTURES, "APPEND_FRACTURES", "Append Fractures" );
|
||||
addItem( MultipleFractures::Action::REPLACE_FRACTURES, "REPLACE_FRACTURES", "Replace Fractures" );
|
||||
|
||||
setDefault( MultipleFractures::Action::NONE );
|
||||
}
|
||||
} // namespace caf
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -78,110 +54,43 @@ RicfCreateMultipleFractures::RicfCreateMultipleFractures()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmScriptResponse RicfCreateMultipleFractures::execute()
|
||||
{
|
||||
using TOOLS = RicfApplicationTools;
|
||||
const QString commandName = classKeyword();
|
||||
|
||||
RimProject* project = RimProject::current();
|
||||
RiuCreateMultipleFractionsUi* settings = project->dialogData()->multipleFractionsData();
|
||||
|
||||
// Get case and fracture template
|
||||
auto gridCase = TOOLS::caseFromId( m_caseId );
|
||||
auto fractureTemplate = fractureTemplateFromId( m_templateId );
|
||||
std::vector<RimWellPath*> wellPaths;
|
||||
|
||||
// Find well paths
|
||||
if ( m_caseId() < 0 || m_templateId() < 0 )
|
||||
{
|
||||
QStringList wellsNotFound;
|
||||
wellPaths = TOOLS::wellPathsFromNames( TOOLS::toQStringList( m_wellPathNames ), &wellsNotFound );
|
||||
if ( !wellsNotFound.empty() )
|
||||
{
|
||||
QString error = QString( "createMultipleFractures: These well paths were not found: %1" ).arg( wellsNotFound.join( ", " ) );
|
||||
RiaLogging::error( error.toStdString() );
|
||||
return caf::PdmScriptResponse( caf::PdmScriptResponse::COMMAND_ERROR, error );
|
||||
}
|
||||
return RicfForwarding::errorResponse( "Mandatory argument(s) missing: caseId and templateId are required", commandName );
|
||||
}
|
||||
|
||||
if ( !gridCase )
|
||||
QStringList wellsNotFound;
|
||||
std::vector<RimWellPath*> wellPaths =
|
||||
RicfApplicationTools::wellPathsFromNames( RicfApplicationTools::toQStringList( m_wellPathNames ), &wellsNotFound );
|
||||
if ( !wellsNotFound.empty() )
|
||||
{
|
||||
QString error = QString( "createMultipleFractures: Could not find case with ID %1" ).arg( m_caseId() );
|
||||
RiaLogging::error( error.toStdString() );
|
||||
return caf::PdmScriptResponse( caf::PdmScriptResponse::COMMAND_ERROR, error );
|
||||
return RicfForwarding::errorResponse( "These well paths were not found: " + wellsNotFound.join( ", " ), commandName );
|
||||
}
|
||||
if ( wellPaths.empty() ) return RicfForwarding::errorResponse( "No wellpaths found", commandName );
|
||||
|
||||
auto rimCase = RicfForwarding::findCase( m_caseId() );
|
||||
if ( !rimCase ) return RicfForwarding::errorResponse( rimCase.error(), commandName );
|
||||
|
||||
auto* eclipseCase = dynamic_cast<RimEclipseCase*>( rimCase.value() );
|
||||
if ( !eclipseCase )
|
||||
{
|
||||
return RicfForwarding::errorResponse( QString( "Case with ID %1 is not an Eclipse case" ).arg( m_caseId() ), commandName );
|
||||
}
|
||||
|
||||
if ( !fractureTemplate )
|
||||
{
|
||||
QString error = QString( "createMultipleFractures: Could not find fracture template with ID %1" ).arg( m_templateId() );
|
||||
RiaLogging::error( error.toStdString() );
|
||||
return caf::PdmScriptResponse( caf::PdmScriptResponse::COMMAND_ERROR, error );
|
||||
}
|
||||
auto fractureTemplate = RicfForwarding::findFractureTemplate( m_templateId() );
|
||||
if ( !fractureTemplate ) return RicfForwarding::errorResponse( fractureTemplate.error(), commandName );
|
||||
|
||||
if ( wellPaths.empty() )
|
||||
{
|
||||
QString error( "createMultipleFractures: No wellpaths found" );
|
||||
RiaLogging::error( error.toStdString() );
|
||||
return caf::PdmScriptResponse( caf::PdmScriptResponse::COMMAND_ERROR, error );
|
||||
}
|
||||
RimEclipseCase_createMultipleFractures method( eclipseCase );
|
||||
method.setWellPaths( wellPaths );
|
||||
method.setFractureTemplate( fractureTemplate.value() );
|
||||
method.setMinDistFromWellTd( m_minDistFromWellTd() );
|
||||
method.setMaxFracturesPerWell( m_maxFracturesPerWell() );
|
||||
method.setTopLayer( m_topLayer() );
|
||||
method.setBaseLayer( m_baseLayer() );
|
||||
method.setSpacing( m_spacing() );
|
||||
method.setAction( m_action() );
|
||||
|
||||
if ( !validateArguments() )
|
||||
{
|
||||
QString error( "createMultipleFractures: Mandatory argument(s) missing" );
|
||||
RiaLogging::error( error.toStdString() );
|
||||
return caf::PdmScriptResponse( caf::PdmScriptResponse::COMMAND_ERROR, error );
|
||||
}
|
||||
|
||||
RicCreateMultipleFracturesOptionItemUi* options = new RicCreateMultipleFracturesOptionItemUi();
|
||||
caf::CmdFeatureManager* commandManager = caf::CmdFeatureManager::instance();
|
||||
auto feature =
|
||||
dynamic_cast<RicCreateMultipleFracturesFeature*>( commandManager->getCommandFeature( "RicCreateMultipleFracturesFeature" ) );
|
||||
|
||||
// Default layers
|
||||
int topLayer = m_topLayer;
|
||||
int baseLayer = m_baseLayer;
|
||||
if ( feature && ( topLayer < 0 || baseLayer < 0 ) )
|
||||
{
|
||||
auto ijkRange = feature->ijkRangeForGrid( gridCase );
|
||||
if ( topLayer < 0 ) topLayer = static_cast<int>( ijkRange.min().z() );
|
||||
if ( baseLayer < 0 ) baseLayer = static_cast<int>( ijkRange.max().z() );
|
||||
}
|
||||
options->setValues( topLayer, baseLayer, fractureTemplate, m_spacing );
|
||||
|
||||
settings->clearWellPaths();
|
||||
for ( auto wellPath : wellPaths )
|
||||
{
|
||||
settings->addWellPath( wellPath );
|
||||
}
|
||||
|
||||
settings->setValues( gridCase, m_minDistFromWellTd, m_maxFracturesPerWell );
|
||||
settings->clearOptions();
|
||||
settings->insertOptionItem( nullptr, options );
|
||||
|
||||
if ( feature )
|
||||
{
|
||||
if ( m_action == MultipleFractures::Action::APPEND_FRACTURES ) feature->appendFractures();
|
||||
if ( m_action == MultipleFractures::Action::REPLACE_FRACTURES ) feature->replaceFractures();
|
||||
}
|
||||
return caf::PdmScriptResponse();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicfCreateMultipleFractures::validateArguments() const
|
||||
{
|
||||
bool valid = m_caseId >= 0 && m_templateId >= 0;
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFractureTemplate* RicfCreateMultipleFractures::fractureTemplateFromId( int templateId ) const
|
||||
{
|
||||
for ( RimFractureTemplate* t : RimProject::current()->allFractureTemplates() )
|
||||
{
|
||||
if ( t->id() == templateId ) return t;
|
||||
}
|
||||
|
||||
RiaLogging::error( std::format( "createMultipleFractures: Could not find fracture template with ID {}", templateId ) );
|
||||
return nullptr;
|
||||
return RicfForwarding::toScriptResponse( method.execute(), commandName );
|
||||
}
|
||||
@@ -20,18 +20,10 @@
|
||||
|
||||
#include "RicfCommandObject.h"
|
||||
|
||||
#include "FractureCommands/RicCreateMultipleFracturesFeature.h"
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmField.h"
|
||||
|
||||
namespace MultipleFractures
|
||||
{
|
||||
enum class Action
|
||||
{
|
||||
NONE,
|
||||
APPEND_FRACTURES,
|
||||
REPLACE_FRACTURES
|
||||
};
|
||||
}
|
||||
#include "cafPdmField.h"
|
||||
|
||||
class RimEclipseCase;
|
||||
class RimFractureTemplate;
|
||||
@@ -52,9 +44,6 @@ public:
|
||||
caf::PdmScriptResponse execute() override;
|
||||
|
||||
private:
|
||||
bool validateArguments() const;
|
||||
RimFractureTemplate* fractureTemplateFromId( int templateId ) const;
|
||||
|
||||
caf::PdmField<int> m_caseId;
|
||||
caf::PdmField<std::vector<QString>> m_wellPathNames;
|
||||
caf::PdmField<double> m_minDistFromWellTd;
|
||||
|
||||
@@ -17,10 +17,14 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RicCreateMultipleFracturesFeature.h"
|
||||
|
||||
#include "RicFractureNameGenerator.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmScriptEnumNameRegistry.h"
|
||||
|
||||
#include "RicCreateMultipleFracturesUi.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
@@ -45,6 +49,28 @@
|
||||
#include <QAction>
|
||||
#include <QPushButton>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
void AppEnum<MultipleFractures::Action>::setUp()
|
||||
{
|
||||
addItem( MultipleFractures::Action::APPEND_FRACTURES, "APPEND_FRACTURES", "Append Fractures" );
|
||||
addItem( MultipleFractures::Action::REPLACE_FRACTURES, "REPLACE_FRACTURES", "Replace Fractures" );
|
||||
|
||||
setDefault( MultipleFractures::Action::NONE );
|
||||
}
|
||||
} // namespace caf
|
||||
|
||||
namespace
|
||||
{
|
||||
// Pin the Python StrEnum class name for the action used by RimEclipseCase_createMultipleFractures
|
||||
struct RegisterScriptEnumNames
|
||||
{
|
||||
RegisterScriptEnumNames() { caf::PdmScriptEnumNameRegistry::registerName<MultipleFractures::Action>( "MultipleFracturesAction" ); }
|
||||
};
|
||||
const RegisterScriptEnumNames s_registerScriptEnumNames;
|
||||
} // namespace
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicCreateMultipleFracturesFeature, "RicCreateMultipleFracturesFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -29,6 +29,16 @@
|
||||
class RiuCreateMultipleFractionsUi;
|
||||
class RimEclipseCase;
|
||||
|
||||
namespace MultipleFractures
|
||||
{
|
||||
enum class Action
|
||||
{
|
||||
NONE,
|
||||
APPEND_FRACTURES,
|
||||
REPLACE_FRACTURES
|
||||
};
|
||||
}
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class PdmUiPropertyViewDialog;
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "CompletionExportCommands/RicWellPathExportMswCompletionsImpl.h"
|
||||
#include "ExportCommands/RicEclipseCellResultToFileImpl.h"
|
||||
#include "ExportCommands/RicExportLgrFeature.h"
|
||||
#include "FractureCommands/RicCreateMultipleFracturesOptionItemUi.h"
|
||||
#include "FractureCommands/RicCreateMultipleFracturesUi.h"
|
||||
#include "RicCreateTemporaryLgrFeature.h"
|
||||
#include "RicDeleteTemporaryLgrsFeature.h"
|
||||
|
||||
@@ -47,8 +49,10 @@
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimCellFilter.h"
|
||||
#include "RimDialogData.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "RimFractureTemplate.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimRoffCase.h"
|
||||
@@ -1166,3 +1170,157 @@ std::expected<caf::PdmObjectHandle*, QString> RimEclipseCase_exportLgrForComplet
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimEclipseCase, RimEclipseCase_createMultipleFractures, "createMultipleFractures" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEclipseCase_createMultipleFractures::RimEclipseCase_createMultipleFractures( caf::PdmObjectHandle* self )
|
||||
: caf::PdmVoidObjectMethod( self )
|
||||
{
|
||||
CAF_PDM_InitObject( "Create Multiple Fractures", "", "", "Create multiple fractures along the given well paths using a fracture template" );
|
||||
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_wellPaths, "WellPaths", "Well Paths", "", "", "Well paths to create fractures for" );
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_fractureTemplate, "FractureTemplate", "Fracture Template", "", "", "Template used for the created fractures" );
|
||||
CAF_PDM_InitScriptableField( &m_minDistFromWellTd,
|
||||
"MinDistFromWellTd",
|
||||
100.0,
|
||||
"Min Distance From Well TD",
|
||||
"",
|
||||
"",
|
||||
"Minimum distance from the well total depth" );
|
||||
CAF_PDM_InitScriptableField( &m_maxFracturesPerWell, "MaxFracturesPerWell", 100, "Max Fractures per Well" );
|
||||
CAF_PDM_InitScriptableField( &m_topLayer, "TopLayer", -1, "Top Layer", "", "", "Zero-based K index of the top layer. -1 uses the top of the grid." );
|
||||
CAF_PDM_InitScriptableField( &m_baseLayer,
|
||||
"BaseLayer",
|
||||
-1,
|
||||
"Base Layer",
|
||||
"",
|
||||
"",
|
||||
"Zero-based K index of the base layer. -1 uses the bottom of the grid." );
|
||||
CAF_PDM_InitScriptableField( &m_spacing, "Spacing", 300.0, "Spacing", "", "", "Distance between fractures" );
|
||||
CAF_PDM_InitScriptableField( &m_action,
|
||||
"Action",
|
||||
caf::AppEnum<MultipleFractures::Action>( MultipleFractures::Action::APPEND_FRACTURES ),
|
||||
"Action",
|
||||
"",
|
||||
"",
|
||||
"Append to or replace the existing fractures on the well paths" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEclipseCase_createMultipleFractures::setWellPaths( const std::vector<RimWellPath*>& wellPaths )
|
||||
{
|
||||
m_wellPaths.setValue( wellPaths );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEclipseCase_createMultipleFractures::setFractureTemplate( RimFractureTemplate* fractureTemplate )
|
||||
{
|
||||
m_fractureTemplate = fractureTemplate;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEclipseCase_createMultipleFractures::setMinDistFromWellTd( double minDist )
|
||||
{
|
||||
m_minDistFromWellTd = minDist;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEclipseCase_createMultipleFractures::setMaxFracturesPerWell( int maxFractures )
|
||||
{
|
||||
m_maxFracturesPerWell = maxFractures;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEclipseCase_createMultipleFractures::setTopLayer( int topLayer )
|
||||
{
|
||||
m_topLayer = topLayer;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEclipseCase_createMultipleFractures::setBaseLayer( int baseLayer )
|
||||
{
|
||||
m_baseLayer = baseLayer;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEclipseCase_createMultipleFractures::setSpacing( double spacing )
|
||||
{
|
||||
m_spacing = spacing;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEclipseCase_createMultipleFractures::setAction( MultipleFractures::Action action )
|
||||
{
|
||||
m_action = action;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::expected<caf::PdmObjectHandle*, QString> RimEclipseCase_createMultipleFractures::execute()
|
||||
{
|
||||
auto* eclipseCase = self<RimEclipseCase>();
|
||||
if ( !eclipseCase ) return std::unexpected( "No case is available." );
|
||||
|
||||
std::vector<RimWellPath*> wellPaths = m_wellPaths.ptrReferencedObjectsByType();
|
||||
if ( wellPaths.empty() ) return std::unexpected( "No well paths specified." );
|
||||
|
||||
RimFractureTemplate* fractureTemplate = m_fractureTemplate();
|
||||
if ( !fractureTemplate ) return std::unexpected( "No fracture template specified." );
|
||||
|
||||
if ( m_action() == MultipleFractures::Action::NONE ) return std::unexpected( "Action must be APPEND_FRACTURES or REPLACE_FRACTURES." );
|
||||
|
||||
auto* feature = dynamic_cast<RicCreateMultipleFracturesFeature*>(
|
||||
caf::CmdFeatureManager::instance()->getCommandFeature( "RicCreateMultipleFracturesFeature" ) );
|
||||
if ( !feature ) return std::unexpected( "The create multiple fractures feature is not available." );
|
||||
|
||||
RimProject* project = RimProject::current();
|
||||
RiuCreateMultipleFractionsUi* settings = project->dialogData()->multipleFractionsData();
|
||||
|
||||
// Default layers
|
||||
int topLayer = m_topLayer();
|
||||
int baseLayer = m_baseLayer();
|
||||
if ( topLayer < 0 || baseLayer < 0 )
|
||||
{
|
||||
auto ijkRange = feature->ijkRangeForGrid( eclipseCase );
|
||||
if ( topLayer < 0 ) topLayer = static_cast<int>( ijkRange.min().z() );
|
||||
if ( baseLayer < 0 ) baseLayer = static_cast<int>( ijkRange.max().z() );
|
||||
}
|
||||
|
||||
auto* options = new RicCreateMultipleFracturesOptionItemUi();
|
||||
options->setValues( topLayer, baseLayer, fractureTemplate, m_spacing() );
|
||||
|
||||
settings->clearWellPaths();
|
||||
for ( RimWellPath* wellPath : wellPaths )
|
||||
{
|
||||
settings->addWellPath( wellPath );
|
||||
}
|
||||
|
||||
settings->setValues( eclipseCase, m_minDistFromWellTd(), m_maxFracturesPerWell() );
|
||||
settings->clearOptions();
|
||||
settings->insertOptionItem( nullptr, options );
|
||||
|
||||
if ( m_action() == MultipleFractures::Action::APPEND_FRACTURES ) feature->appendFractures();
|
||||
if ( m_action() == MultipleFractures::Action::REPLACE_FRACTURES ) feature->replaceFractures();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "CompletionExportCommands/RicExportCompletionDataSettingsUi.h"
|
||||
#include "ExportCommands/RicLgrSplitType.h"
|
||||
#include "FractureCommands/RicCreateMultipleFracturesFeature.h"
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmField.h"
|
||||
@@ -34,6 +35,7 @@
|
||||
#include <QString>
|
||||
|
||||
class RimCellFilter;
|
||||
class RimFractureTemplate;
|
||||
class RimWellPath;
|
||||
|
||||
//==================================================================================================
|
||||
@@ -341,3 +343,35 @@ private:
|
||||
|
||||
QStringList m_wellsIntersectingOtherLgrs;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Create multiple fractures along the given well paths using a fracture template.
|
||||
//==================================================================================================
|
||||
class RimEclipseCase_createMultipleFractures : public caf::PdmVoidObjectMethod
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimEclipseCase_createMultipleFractures( caf::PdmObjectHandle* self );
|
||||
|
||||
void setWellPaths( const std::vector<RimWellPath*>& wellPaths );
|
||||
void setFractureTemplate( RimFractureTemplate* fractureTemplate );
|
||||
void setMinDistFromWellTd( double minDist );
|
||||
void setMaxFracturesPerWell( int maxFractures );
|
||||
void setTopLayer( int topLayer );
|
||||
void setBaseLayer( int baseLayer );
|
||||
void setSpacing( double spacing );
|
||||
void setAction( MultipleFractures::Action action );
|
||||
|
||||
std::expected<caf::PdmObjectHandle*, QString> execute() override;
|
||||
|
||||
private:
|
||||
caf::PdmPtrArrayField<RimWellPath*> m_wellPaths;
|
||||
caf::PdmPtrField<RimFractureTemplate*> m_fractureTemplate;
|
||||
caf::PdmField<double> m_minDistFromWellTd;
|
||||
caf::PdmField<int> m_maxFracturesPerWell;
|
||||
caf::PdmField<int> m_topLayer;
|
||||
caf::PdmField<int> m_baseLayer;
|
||||
caf::PdmField<double> m_spacing;
|
||||
caf::PdmField<caf::AppEnum<MultipleFractures::Action>> m_action;
|
||||
};
|
||||
@@ -506,52 +506,6 @@ def export_msw(self, well_path: str) -> Any:
|
||||
)
|
||||
|
||||
|
||||
@add_method(Case)
|
||||
def create_multiple_fractures(
|
||||
self,
|
||||
template_id: int,
|
||||
well_path_names: Union[str, List[str]],
|
||||
min_dist_from_well_td: float,
|
||||
max_fractures_per_well: int,
|
||||
top_layer: int,
|
||||
base_layer: int,
|
||||
spacing: float,
|
||||
action: str,
|
||||
) -> Any:
|
||||
"""
|
||||
Create Multiple Fractures in one go
|
||||
|
||||
**Parameters**::
|
||||
|
||||
Parameter | Description | Type
|
||||
-----------------------| ----------------------------------------- | -----
|
||||
template_id | Id of the template | Integer
|
||||
well_path_names | List of well path names | List of Strings
|
||||
min_dist_from_well_td | Minimum distance from well TD | Double
|
||||
max_fractures_per_well | Max number of fractures per well | Integer
|
||||
top_layer | Top grid k-level for fractures | Integer
|
||||
base_layer | Base grid k-level for fractures | Integer
|
||||
spacing | Spacing between fractures | Double
|
||||
action | 'APPEND_FRACTURES' or 'REPLACE_FRACTURES' | String enum
|
||||
|
||||
"""
|
||||
if isinstance(well_path_names, str):
|
||||
well_path_names = [well_path_names]
|
||||
return self._execute_command(
|
||||
createMultipleFractures=Cmd.CreateMultipleFracRequest(
|
||||
caseId=self.id,
|
||||
templateId=template_id,
|
||||
wellPathNames=well_path_names,
|
||||
minDistFromWellTd=min_dist_from_well_td,
|
||||
maxFracturesPerWell=max_fractures_per_well,
|
||||
topLayer=top_layer,
|
||||
baseLayer=base_layer,
|
||||
spacing=spacing,
|
||||
action=action,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@add_method(Case)
|
||||
def create_lgr_for_completion(
|
||||
self,
|
||||
|
||||
@@ -75,26 +75,61 @@ def test_create_and_export_lgr_for_completions(rips_instance, initialize_test):
|
||||
|
||||
|
||||
def test_create_multiple_fractures(rips_instance, initialize_test):
|
||||
case = rips_instance.project.load_case(
|
||||
dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
|
||||
project = rips_instance.project.open(
|
||||
dataroot.PATH + "/TEST10K_FLT_LGR_NNC/small-completion-export-fractures.rsp"
|
||||
)
|
||||
|
||||
well_files = [dataroot.PATH + "/TEST10K_FLT_LGR_NNC/wellpath_a.dev"]
|
||||
rips_instance.project.import_well_paths(well_path_files=well_files)
|
||||
|
||||
fracture_instances = rips_instance.project.descendants(rips.WellPathFracture)
|
||||
assert len(fracture_instances) == 0
|
||||
case = project.cases()[0]
|
||||
template = project.descendants(rips.FractureTemplate)[0]
|
||||
well_path = project.well_paths()[0]
|
||||
|
||||
case.create_multiple_fractures(
|
||||
template_id=0,
|
||||
well_path_names="Well Path A",
|
||||
well_paths=[well_path],
|
||||
fracture_template=template,
|
||||
min_dist_from_well_td=100.0,
|
||||
max_fractures_per_well=5,
|
||||
top_layer=1,
|
||||
base_layer=30,
|
||||
spacing=100.0,
|
||||
action="REPLACE_FRACTURES",
|
||||
action=rips.MultipleFracturesAction.REPLACE_FRACTURES,
|
||||
)
|
||||
|
||||
fracture_instances = rips_instance.project.descendants(rips.WellPathFracture)
|
||||
fracture_instances = project.descendants(rips.WellPathFracture)
|
||||
assert len(fracture_instances) > 0
|
||||
|
||||
|
||||
def test_create_multiple_fractures_object_method(rips_instance, initialize_test):
|
||||
project = rips_instance.project.open(
|
||||
dataroot.PATH + "/TEST10K_FLT_LGR_NNC/small-completion-export-fractures.rsp"
|
||||
)
|
||||
case = project.cases()[0]
|
||||
template = project.descendants(rips.FractureTemplate)[0]
|
||||
well_paths = project.well_paths()
|
||||
assert len(well_paths) > 0
|
||||
|
||||
before = len(project.descendants(rips.WellPathFracture))
|
||||
|
||||
case.create_multiple_fractures(
|
||||
well_paths=well_paths[:1],
|
||||
fracture_template=template,
|
||||
min_dist_from_well_td=100.0,
|
||||
max_fractures_per_well=3,
|
||||
spacing=100.0,
|
||||
action=rips.MultipleFracturesAction.APPEND_FRACTURES,
|
||||
)
|
||||
after_append = len(project.descendants(rips.WellPathFracture))
|
||||
assert after_append > before
|
||||
|
||||
case.create_multiple_fractures(
|
||||
well_paths=well_paths[:1],
|
||||
fracture_template=template,
|
||||
max_fractures_per_well=1,
|
||||
spacing=100.0,
|
||||
action=rips.MultipleFracturesAction.REPLACE_FRACTURES,
|
||||
)
|
||||
after_replace = len(project.descendants(rips.WellPathFracture))
|
||||
assert after_replace < after_append
|
||||
|
||||
with pytest.raises(rips.RipsError):
|
||||
case.create_multiple_fractures(well_paths=well_paths[:1])
|
||||
with pytest.raises(rips.RipsError):
|
||||
case.create_multiple_fractures(fracture_template=template)
|
||||
Reference in new issue
Block a user