mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Major rewrite of MSW export model
This commit is contained in:
parent
9ecfefe094
commit
63690d5196
@ -10,7 +10,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewValveFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewValveTemplateFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewValveAtMeasuredDepthFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicDeleteValveTemplateFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathImportCompletionsFileFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathImportPerforationIntervalsFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewStimPlanModelPlotFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportEnsembleFractureStatisticsFeature.h
|
||||
@ -27,7 +26,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewValveFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewValveTemplateFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewValveAtMeasuredDepthFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicDeleteValveTemplateFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathImportCompletionsFileFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathImportPerforationIntervalsFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewStimPlanModelPlotFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportEnsembleFractureStatisticsFeature.cpp
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "Rim3dView.h"
|
||||
#include "RimFishbones.h"
|
||||
#include "RimFishbonesCollection.h"
|
||||
#include "RimImportedFishboneLateralsCollection.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPathCompletions.h"
|
||||
|
@ -1,128 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RicWellPathImportCompletionsFileFeature.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
|
||||
#include "RimFishbonesCollection.h"
|
||||
#include "RimImportedFishboneLateralsCollection.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPathCompletions.h"
|
||||
|
||||
#include "Riu3DMainWindowTools.h"
|
||||
#include "RiuFileDialogTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QFileInfo>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicWellPathImportCompletionsFileFeature, "RicWellPathImportCompletionsFileFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicWellPathImportCompletionsFileFeature::isCommandEnabled()
|
||||
{
|
||||
if ( RicWellPathImportCompletionsFileFeature::selectedWellPathCollection() != nullptr )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicWellPathImportCompletionsFileFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
RimImportedFishboneLateralsCollection* fishbonesWellPathCollection =
|
||||
RicWellPathImportCompletionsFileFeature::selectedWellPathCollection();
|
||||
CVF_ASSERT( fishbonesWellPathCollection );
|
||||
|
||||
// Open dialog box to select well path files
|
||||
RiaApplication* app = RiaApplication::instance();
|
||||
QString defaultDir = app->lastUsedDialogDirectory( "WELLPATH_DIR" );
|
||||
QStringList wellPathFilePaths = RiuFileDialogTools::getOpenFileNames( Riu3DMainWindowTools::mainWindowWidget(),
|
||||
"Import Fishbone Laterals",
|
||||
defaultDir,
|
||||
"Well Path Laterals (*.json *.asc *.asci "
|
||||
"*.ascii *.dev);;All Files (*.*)" );
|
||||
|
||||
if ( wellPathFilePaths.size() < 1 ) return;
|
||||
|
||||
// Remember the path to next time
|
||||
app->setLastUsedDialogDirectory( "WELLPATH_DIR", QFileInfo( wellPathFilePaths.last() ).absolutePath() );
|
||||
|
||||
fishbonesWellPathCollection->importCompletionsFromFile( wellPathFilePaths );
|
||||
|
||||
RimWellPathCollection* wellPathCollection;
|
||||
fishbonesWellPathCollection->firstAncestorOrThisOfType( wellPathCollection );
|
||||
if ( wellPathCollection )
|
||||
{
|
||||
wellPathCollection->updateConnectedEditors();
|
||||
}
|
||||
|
||||
if ( app->project() )
|
||||
{
|
||||
app->project()->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicWellPathImportCompletionsFileFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
actionToSetup->setText( "Import Fishbone Laterals" );
|
||||
actionToSetup->setIcon( QIcon( ":/FishBoneGroupFromFile16x16.png" ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimImportedFishboneLateralsCollection* RicWellPathImportCompletionsFileFeature::selectedWellPathCollection()
|
||||
{
|
||||
RimFishbonesCollection* objToFind = nullptr;
|
||||
caf::PdmUiItem* pdmUiItem = caf::SelectionManager::instance()->selectedItem();
|
||||
caf::PdmObjectHandle* objHandle = dynamic_cast<caf::PdmObjectHandle*>( pdmUiItem );
|
||||
if ( objHandle )
|
||||
{
|
||||
objHandle->firstAncestorOrThisOfType( objToFind );
|
||||
}
|
||||
|
||||
if ( objToFind == nullptr )
|
||||
{
|
||||
std::vector<RimWellPath*> wellPaths;
|
||||
caf::SelectionManager::instance()->objectsByType( &wellPaths );
|
||||
if ( !wellPaths.empty() )
|
||||
{
|
||||
return wellPaths[0]->fishbonesCollection()->wellPathCollection();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return objToFind->wellPathCollection();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafCmdFeature.h"
|
||||
|
||||
class RimImportedFishboneLateralsCollection;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicWellPathImportCompletionsFileFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
// Overrides
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered( bool isChecked ) override;
|
||||
void setupActionLook( QAction* actionToSetup ) override;
|
||||
|
||||
private:
|
||||
static RimImportedFishboneLateralsCollection* selectedWellPathCollection();
|
||||
};
|
@ -21,6 +21,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicMswValveAccumulators.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureTextReportFeatureImpl.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureReportItem.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicExportCompletionsForTemporaryLgrsFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicMswTableFormatterTools.h
|
||||
)
|
||||
|
||||
|
||||
@ -46,6 +47,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicMswValveAccumulators.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureTextReportFeatureImpl.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureReportItem.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicExportCompletionsForTemporaryLgrsFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicMswTableFormatterTools.cpp
|
||||
)
|
||||
|
||||
list(APPEND COMMAND_CODE_HEADER_FILES
|
||||
|
@ -83,7 +83,7 @@ RicExportCompletionDataSettingsUi::RicExportCompletionDataSettingsUi()
|
||||
|
||||
CAF_PDM_InitField( &timeStep, "TimeStepIndex", 0, " Time Step", "", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &includeMsw, "IncludeMSW", true, "Include Multi Segment Well Model", "", "", "" );
|
||||
CAF_PDM_InitField( &includeMsw, "IncludeMSW", true, "Multi Segment Well Model", "", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &useLateralNTG, "UseLateralNTG", false, "Use NTG Horizontally", "", "", "" );
|
||||
|
||||
@ -112,16 +112,17 @@ RicExportCompletionDataSettingsUi::RicExportCompletionDataSettingsUi()
|
||||
"",
|
||||
"" );
|
||||
|
||||
CAF_PDM_InitField( &m_exportDataSourceAsComment,
|
||||
"ExportDataSourceAsComment",
|
||||
true,
|
||||
"Export Data Source In Comment",
|
||||
CAF_PDM_InitField( &m_exportDataSourceAsComment, "ExportDataSourceAsComment", true, "Comment", "", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_exportWelspec, "ExportWelspec", true, "WELSPEC keyword", "", "", "" );
|
||||
CAF_PDM_InitField( &m_completionWelspecAfterMainBore,
|
||||
"CompletionWelspecAfterMainBore",
|
||||
false,
|
||||
"WELSEGS per Completion Type",
|
||||
"",
|
||||
"",
|
||||
"" );
|
||||
|
||||
CAF_PDM_InitField( &m_exportWelspec, "ExportWelspec", true, "Export WELSPEC keyword", "", "", "" );
|
||||
|
||||
m_displayForSimWell = true;
|
||||
|
||||
m_fracturesEnabled = true;
|
||||
@ -217,6 +218,14 @@ bool RicExportCompletionDataSettingsUi::exportWelspec() const
|
||||
return m_exportWelspec;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicExportCompletionDataSettingsUi::exportCompletionWelspecAfterMainBore() const
|
||||
{
|
||||
return m_completionWelspecAfterMainBore();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -329,9 +338,10 @@ void RicExportCompletionDataSettingsUi::defineUiOrdering( QString uiConfigName,
|
||||
group->add( &compdatExport );
|
||||
group->add( &caseToApply );
|
||||
group->add( &useLateralNTG );
|
||||
group->add( &includeMsw );
|
||||
group->add( &m_exportDataSourceAsComment );
|
||||
group->add( &m_exportWelspec );
|
||||
group->add( &includeMsw );
|
||||
group->add( &m_completionWelspecAfterMainBore );
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -98,6 +98,7 @@ public:
|
||||
bool reportCompletionsTypesIndividually() const;
|
||||
bool exportDataSourceAsComment() const;
|
||||
bool exportWelspec() const;
|
||||
bool exportCompletionWelspecAfterMainBore() const;
|
||||
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
|
||||
@ -112,6 +113,7 @@ private:
|
||||
caf::PdmField<CombinationModeType> m_reportCompletionTypesSeparately;
|
||||
caf::PdmField<bool> m_exportDataSourceAsComment;
|
||||
caf::PdmField<bool> m_exportWelspec;
|
||||
caf::PdmField<bool> m_completionWelspecAfterMainBore;
|
||||
|
||||
bool m_displayForSimWell;
|
||||
bool m_fracturesEnabled;
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimFishbones.h"
|
||||
#include "RimFishbonesCollection.h"
|
||||
#include "RimImportedFishboneLateralsCollection.h"
|
||||
#include "RimPerforationCollection.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPath.h"
|
||||
|
@ -30,14 +30,12 @@
|
||||
#include "RigCompletionData.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigWellLogExtractor.h"
|
||||
#include "RigWellPath.h"
|
||||
#include "RigWellPathIntersectionTools.h"
|
||||
|
||||
#include "RigWellLogExtractor.h"
|
||||
#include "RimFishbones.h"
|
||||
#include "RimFishbonesCollection.h"
|
||||
#include "RimImportedFishboneLaterals.h"
|
||||
#include "RimImportedFishboneLateralsCollection.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCompletions.h"
|
||||
|
||||
@ -98,7 +96,6 @@ std::vector<RigCompletionData>
|
||||
std::map<size_t, std::vector<WellBorePartForTransCalc>> wellBorePartsInCells; // wellBore = main bore or fishbone
|
||||
// lateral
|
||||
findFishboneLateralsWellBoreParts( wellBorePartsInCells, wellPath, settings );
|
||||
findFishboneImportedLateralsWellBoreParts( wellBorePartsInCells, wellPath, settings );
|
||||
|
||||
const RigActiveCellInfo* activeCellInfo =
|
||||
settings.caseToApply->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||
@ -221,40 +218,44 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWell
|
||||
exportInfo.setLinerDiameter( mswParameters->linerDiameter( unitSystem ) );
|
||||
exportInfo.setRoughnessFactor( mswParameters->roughnessFactor( unitSystem ) );
|
||||
|
||||
RicWellPathExportMswCompletionsImpl::generateFishbonesMswExportInfo( settings.caseToApply(),
|
||||
wellPath,
|
||||
0.0,
|
||||
{},
|
||||
false,
|
||||
&exportInfo,
|
||||
exportInfo.mainBoreBranch() );
|
||||
RicWellPathExportMswCompletionsImpl::generateFishbonesMswExportInfoForWell( settings.caseToApply(),
|
||||
wellPath,
|
||||
&exportInfo,
|
||||
exportInfo.mainBoreBranch() );
|
||||
|
||||
bool isMainBore = false;
|
||||
|
||||
for ( auto segment : exportInfo.mainBoreBranch()->segments() )
|
||||
for ( auto mainBoreSegment : exportInfo.mainBoreBranch()->segments() )
|
||||
{
|
||||
for ( auto completion : segment->completions() )
|
||||
for ( auto mainBoreCompletion : mainBoreSegment->completions() )
|
||||
{
|
||||
for ( auto completionSegment : completion->segments() )
|
||||
for ( auto completionSegment : mainBoreCompletion->segments() )
|
||||
{
|
||||
for ( std::shared_ptr<RicMswSegmentCellIntersection> intersection : completionSegment->intersections() )
|
||||
for ( auto completion : completionSegment->completions() )
|
||||
{
|
||||
double diameter = segment->holeDiameter();
|
||||
QString completionMetaData =
|
||||
( segment->label() +
|
||||
QString( ": Sub: %1 Lateral: %2" ).arg( segment->subIndex() ).arg( completion->index() ) );
|
||||
for ( auto segment : completion->segments() )
|
||||
{
|
||||
for ( auto intersection : segment->intersections() )
|
||||
{
|
||||
double diameter = segment->holeDiameter();
|
||||
QString completionMetaData = ( segment->label() + QString( ": Sub: %1 Lateral: %2" )
|
||||
.arg( segment->subIndex() + 1 )
|
||||
.arg( completion->index() + 1 ) );
|
||||
|
||||
WellBorePartForTransCalc wellBorePart = WellBorePartForTransCalc( intersection->lengthsInCell(),
|
||||
diameter / 2.0,
|
||||
segment->skinFactor(),
|
||||
isMainBore,
|
||||
completionMetaData );
|
||||
WellBorePartForTransCalc wellBorePart =
|
||||
WellBorePartForTransCalc( intersection->lengthsInCell(),
|
||||
diameter / 2.0,
|
||||
segment->skinFactor(),
|
||||
isMainBore,
|
||||
completionMetaData );
|
||||
|
||||
wellBorePart.intersectionWithWellMeasuredDepth = segment->endMD();
|
||||
wellBorePart.lateralIndex = completion->index();
|
||||
wellBorePart.setSourcePdmObject( segment->sourcePdmObject() );
|
||||
wellBorePart.intersectionWithWellMeasuredDepth = segment->endMD();
|
||||
wellBorePart.lateralIndex = completion->index();
|
||||
wellBorePart.setSourcePdmObject( segment->sourcePdmObject() );
|
||||
|
||||
wellBorePartsInCells[intersection->globalCellIndex()].push_back( wellBorePart );
|
||||
wellBorePartsInCells[intersection->globalCellIndex()].push_back( wellBorePart );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -262,8 +263,8 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWell
|
||||
|
||||
{
|
||||
// Note that it is not supported to export main bore perforation intervals for Imported Laterals, only for
|
||||
// fishbones defined by ResInsight. It is not trivial to define the open section of the main bore for imported
|
||||
// laterals.
|
||||
// fishbones defined by ResInsight. It is not trivial to define the open section of the main bore for
|
||||
// imported laterals.
|
||||
|
||||
if ( wellPath->fishbonesCollection()->isChecked() )
|
||||
{
|
||||
@ -295,56 +296,6 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWell
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneImportedLateralsWellBoreParts(
|
||||
std::map<size_t, std::vector<WellBorePartForTransCalc>>& wellBorePartsInCells,
|
||||
const RimWellPath* wellPath,
|
||||
const RicExportCompletionDataSettingsUi& settings )
|
||||
{
|
||||
RiaDefines::EclipseUnitSystem unitSystem = settings.caseToApply->eclipseCaseData()->unitsType();
|
||||
|
||||
if ( !wellPath ) return;
|
||||
if ( !wellPath->wellPathGeometry() ) return;
|
||||
|
||||
bool isMainBore = false;
|
||||
double holeRadius = wellPath->fishbonesCollection()->wellPathCollection()->holeDiameter( unitSystem ) / 2.0;
|
||||
double skinFactor = wellPath->fishbonesCollection()->wellPathCollection()->skinFactor();
|
||||
|
||||
for ( const RimImportedFishboneLaterals* fishbonesPath :
|
||||
wellPath->fishbonesCollection()->wellPathCollection()->wellPaths() )
|
||||
{
|
||||
if ( !fishbonesPath->isChecked() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<WellPathCellIntersectionInfo> intersectedCells =
|
||||
RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath( settings.caseToApply->eclipseCaseData(),
|
||||
wellPath->name(),
|
||||
fishbonesPath->coordinates(),
|
||||
fishbonesPath->measuredDepths() );
|
||||
|
||||
for ( const auto& cellIntersectionInfo : intersectedCells )
|
||||
{
|
||||
QString completionMetaData = fishbonesPath->name();
|
||||
WellBorePartForTransCalc wellBorePart =
|
||||
WellBorePartForTransCalc( cellIntersectionInfo.intersectionLengthsInCellCS,
|
||||
holeRadius,
|
||||
skinFactor,
|
||||
isMainBore,
|
||||
completionMetaData );
|
||||
wellBorePart.intersectionWithWellMeasuredDepth = cellIntersectionInfo.startMD;
|
||||
|
||||
wellBorePartsInCells[cellIntersectionInfo.globCellIndex].push_back( wellBorePart );
|
||||
}
|
||||
}
|
||||
|
||||
// Note that it is not supported to export main bore perforation intervals for Imported Laterals, only for fishbones
|
||||
// defined by ResInsight
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -48,11 +48,6 @@ private:
|
||||
const RimWellPath* wellPath,
|
||||
const RicExportCompletionDataSettingsUi& settings );
|
||||
|
||||
static void
|
||||
findFishboneImportedLateralsWellBoreParts( std::map<size_t, std::vector<WellBorePartForTransCalc>>& wellBorePartsInCells,
|
||||
const RimWellPath* wellPath,
|
||||
const RicExportCompletionDataSettingsUi& settings );
|
||||
|
||||
static void appendMainWellBoreParts( std::map<size_t, std::vector<WellBorePartForTransCalc>>& wellBorePartsInCells,
|
||||
const RimWellPath* wellPath,
|
||||
const RicExportCompletionDataSettingsUi& settings,
|
||||
|
@ -1,3 +1,21 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2021- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RicMswBranch.h"
|
||||
|
||||
#include "RicMswCompletions.h"
|
||||
@ -139,6 +157,39 @@ std::vector<RicMswSegment*> RicMswBranch::segments()
|
||||
return allSegments;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicMswSegment* RicMswBranch::findClosestSegmentByMidpoint( double measuredDepthLocation )
|
||||
{
|
||||
if ( measuredDepthLocation < startMD() )
|
||||
{
|
||||
return segmentCount() > 0 ? segments().front() : nullptr;
|
||||
}
|
||||
|
||||
if ( measuredDepthLocation > endMD() )
|
||||
{
|
||||
return segmentCount() > 0 ? segments().back() : nullptr;
|
||||
}
|
||||
|
||||
RicMswSegment* closestSegment = nullptr;
|
||||
double smallestDistance = std::numeric_limits<double>::infinity();
|
||||
|
||||
for ( auto seg : segments() )
|
||||
{
|
||||
double midpointMD = 0.5 * ( seg->startMD() + seg->endMD() );
|
||||
|
||||
double candidateDistance = std::abs( midpointMD - measuredDepthLocation );
|
||||
if ( candidateDistance < smallestDistance )
|
||||
{
|
||||
closestSegment = seg;
|
||||
smallestDistance = candidateDistance;
|
||||
}
|
||||
}
|
||||
|
||||
return closestSegment;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -53,6 +53,8 @@ public:
|
||||
std::vector<const RicMswSegment*> segments() const;
|
||||
std::vector<RicMswSegment*> segments();
|
||||
|
||||
RicMswSegment* findClosestSegmentByMidpoint( double measuredDepth );
|
||||
|
||||
size_t segmentCount() const;
|
||||
|
||||
std::vector<const RicMswBranch*> branches() const;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018 Equinor ASA
|
||||
// Copyright (C) 2021- 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
|
||||
@ -18,9 +18,11 @@
|
||||
|
||||
#include "RicMswCompletions.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
#include "RicMswSegmentCellIntersection.h"
|
||||
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathValve.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -123,30 +125,22 @@ void RicMswValve::setIsValid( bool valid )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::unique_ptr<RicMswValve> RicMswValve::createExportValve( const QString& label,
|
||||
const RimWellPath* wellPath,
|
||||
double startMD,
|
||||
double startTVD,
|
||||
const RimWellPathValve* wellPathValve )
|
||||
std::unique_ptr<RicMswValve> RicMswValve::createTieInValve( const QString& label,
|
||||
const RimWellPath* wellPath,
|
||||
double startMD,
|
||||
double startTVD,
|
||||
const RimWellPathValve* wellPathValve )
|
||||
{
|
||||
std::unique_ptr<RicMswValve> outletValve;
|
||||
if ( wellPathValve->componentType() == RiaDefines::WellPathComponentType::ICD )
|
||||
if ( wellPathValve->componentType() != RiaDefines::WellPathComponentType::ICV )
|
||||
{
|
||||
outletValve = std::make_unique<RicMswPerforationICD>( label, wellPath, startMD, startTVD, wellPathValve );
|
||||
RiaLogging::error( "MSW export: The outlet valve must be of type ICV" );
|
||||
return nullptr;
|
||||
}
|
||||
else if ( wellPathValve->componentType() == RiaDefines::WellPathComponentType::ICV )
|
||||
{
|
||||
outletValve = std::make_unique<RicMswPerforationICV>( label, wellPath, startMD, startTVD, wellPathValve );
|
||||
}
|
||||
else if ( wellPathValve->componentType() == RiaDefines::WellPathComponentType::AICD )
|
||||
{
|
||||
outletValve = std::make_unique<RicMswPerforationAICD>( label, wellPath, startMD, startTVD, wellPathValve );
|
||||
}
|
||||
else
|
||||
{
|
||||
CAF_ASSERT( false && "Valve needs to be either an ICD, ICVF or AICD" );
|
||||
}
|
||||
return outletValve;
|
||||
|
||||
std::unique_ptr<RicMswTieInICV> tieInValve =
|
||||
std::make_unique<RicMswTieInICV>( label, wellPath, startMD, startTVD, wellPathValve );
|
||||
|
||||
return tieInValve;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -247,6 +241,10 @@ RicMswPerforationICV::RicMswPerforationICV( const QString& label,
|
||||
: RicMswWsegValve( label, wellPath, startMD, startTVD, wellPathValve )
|
||||
{
|
||||
setIsValid( true );
|
||||
|
||||
setFlowCoefficient( wellPathValve->flowCoefficient() );
|
||||
double orificeRadius = wellPathValve->orificeDiameter( wellPath->unitSystem() ) / 2;
|
||||
setArea( orificeRadius * orificeRadius * cvf::PI_D );
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@ -270,6 +268,7 @@ RicMswPerforationAICD::RicMswPerforationAICD( const QString& label,
|
||||
, m_length( 0.0 )
|
||||
, m_flowScalingFactor( 0.0 )
|
||||
{
|
||||
m_parameters.fill( std::numeric_limits<double>::infinity() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -343,3 +342,28 @@ std::array<double, AICD_NUM_PARAMS>& RicMswPerforationAICD::values()
|
||||
{
|
||||
return m_parameters;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicMswTieInICV::RicMswTieInICV( const QString& label,
|
||||
const RimWellPath* wellPath,
|
||||
double startMD,
|
||||
double startTVD,
|
||||
const RimWellPathValve* wellPathValve )
|
||||
: RicMswWsegValve( label, wellPath, startMD, startTVD, wellPathValve )
|
||||
{
|
||||
setIsValid( true );
|
||||
|
||||
setFlowCoefficient( wellPathValve->flowCoefficient() );
|
||||
double orificeRadius = wellPathValve->orificeDiameter( wellPath->unitSystem() ) / 2;
|
||||
setArea( orificeRadius * orificeRadius * cvf::PI_D );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigCompletionData::CompletionType RicMswTieInICV::completionType() const
|
||||
{
|
||||
return RigCompletionData::PERFORATION_ICV;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018 Equinor ASA
|
||||
// Copyright (C) 2021- 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
|
||||
@ -15,6 +15,7 @@
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RicMswBranch.h"
|
||||
@ -26,6 +27,7 @@
|
||||
#include "cvfMath.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class RimWellPathValve;
|
||||
@ -49,6 +51,9 @@ private:
|
||||
size_t m_index;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicMswFishbones : public RicMswCompletion
|
||||
{
|
||||
public:
|
||||
@ -111,11 +116,11 @@ public:
|
||||
bool isValid() const;
|
||||
void setIsValid( bool valid );
|
||||
|
||||
static std::unique_ptr<RicMswValve> createExportValve( const QString& label,
|
||||
const RimWellPath* wellPath,
|
||||
double startMD,
|
||||
double startTVD,
|
||||
const RimWellPathValve* wellPathValve );
|
||||
static std::unique_ptr<RicMswValve> createTieInValve( const QString& label,
|
||||
const RimWellPath* wellPath,
|
||||
double startMD,
|
||||
double startTVD,
|
||||
const RimWellPathValve* wellPathValve );
|
||||
|
||||
private:
|
||||
bool m_valid;
|
||||
@ -186,6 +191,22 @@ public:
|
||||
RigCompletionData::CompletionType completionType() const override;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
// This object is representing the optional tie-in valve used to limit the inflow from a branch
|
||||
// into the parent branch
|
||||
// ICV valve is the only supported valve for this MSW item
|
||||
//==================================================================================================
|
||||
class RicMswTieInICV : public RicMswWsegValve
|
||||
{
|
||||
public:
|
||||
RicMswTieInICV( const QString& label,
|
||||
const RimWellPath* wellPath,
|
||||
double startMD,
|
||||
double startTVD,
|
||||
const RimWellPathValve* wellPathValve );
|
||||
RigCompletionData::CompletionType completionType() const override;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
|
@ -1,3 +1,21 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2021- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RicMswItem.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -40,7 +40,7 @@ RicMswSegment::RicMswSegment( const QString& label,
|
||||
, m_endTVD( endTVD )
|
||||
, m_outputMD( 0.0 )
|
||||
, m_outputTVD( 0.0 )
|
||||
, m_effectiveDiameter( 0.15 )
|
||||
, m_equivalentDiameter( 0.15 )
|
||||
, m_holeDiameter( RicMswExportInfo::defaultDoubleValue() )
|
||||
, m_openHoleRoughnessFactor( 5.0e-5 )
|
||||
, m_skinFactor( RicMswExportInfo::defaultDoubleValue() )
|
||||
@ -116,9 +116,9 @@ double RicMswSegment::outputTVD() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RicMswSegment::effectiveDiameter() const
|
||||
double RicMswSegment::equivalentDiameter() const
|
||||
{
|
||||
return m_effectiveDiameter;
|
||||
return m_equivalentDiameter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -198,9 +198,9 @@ void RicMswSegment::setLabel( const QString& label )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswSegment::setEffectiveDiameter( double effectiveDiameter )
|
||||
void RicMswSegment::setEquivalentDiameter( double effectiveDiameter )
|
||||
{
|
||||
m_effectiveDiameter = effectiveDiameter;
|
||||
m_equivalentDiameter = effectiveDiameter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
void setOutputTVD( double outputTVD );
|
||||
double outputTVD() const;
|
||||
|
||||
double effectiveDiameter() const;
|
||||
double equivalentDiameter() const;
|
||||
double holeDiameter() const;
|
||||
double openHoleRoughnessFactor() const;
|
||||
double skinFactor() const;
|
||||
@ -65,7 +65,7 @@ public:
|
||||
std::vector<RicMswCompletion*> completions();
|
||||
|
||||
void setLabel( const QString& label );
|
||||
void setEffectiveDiameter( double effectiveDiameter );
|
||||
void setEquivalentDiameter( double diameter );
|
||||
void setHoleDiameter( double holeDiameter );
|
||||
void setOpenHoleRoughnessFactor( double roughnessFactor );
|
||||
void setSkinFactor( double skinFactor );
|
||||
@ -88,10 +88,10 @@ private:
|
||||
double m_startTVD;
|
||||
double m_endTVD;
|
||||
|
||||
double m_outputMD;
|
||||
double m_outputTVD;
|
||||
double m_outputMD;
|
||||
double m_outputTVD;
|
||||
|
||||
double m_effectiveDiameter;
|
||||
double m_equivalentDiameter;
|
||||
double m_holeDiameter;
|
||||
double m_openHoleRoughnessFactor;
|
||||
double m_skinFactor;
|
||||
|
@ -0,0 +1,998 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2021 Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RicMswTableFormatterTools.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RicMswCompletions.h"
|
||||
#include "RicMswExportInfo.h"
|
||||
|
||||
#include "RifTextDataTableFormatter.h"
|
||||
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RimWellPath.h" // TODO: Consider adding wellnameforexport to RicMswExportInfo to avoid these includes
|
||||
#include "RimWellPathCompletionSettings.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::generateWelsegsTable( RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
bool exportCompletionSegmentsAfterMainBore )
|
||||
{
|
||||
formatter.keyword( "WELSEGS" );
|
||||
|
||||
double startMD = exportInfo.mainBoreBranch()->startMD();
|
||||
double startTVD = exportInfo.mainBoreBranch()->startTVD();
|
||||
|
||||
{
|
||||
std::vector<RifTextDataTableColumn> header = {
|
||||
RifTextDataTableColumn( "Name" ),
|
||||
RifTextDataTableColumn( "Dep 1" ),
|
||||
RifTextDataTableColumn( "Tlen 1" ),
|
||||
RifTextDataTableColumn( "Vol 1" ),
|
||||
RifTextDataTableColumn( "Len&Dep" ),
|
||||
RifTextDataTableColumn( "PresDrop" ),
|
||||
};
|
||||
formatter.header( header );
|
||||
|
||||
formatter.add( exportInfo.mainBoreBranch()->wellPath()->completionSettings()->wellNameForExport() );
|
||||
formatter.add( startTVD );
|
||||
formatter.add( startMD );
|
||||
formatter.addValueOrDefaultMarker( exportInfo.topWellBoreVolume(), RicMswExportInfo::defaultDoubleValue() );
|
||||
formatter.add( exportInfo.lengthAndDepthText() );
|
||||
formatter.add( QString( "'%1'" ).arg( exportInfo.pressureDropText() ) );
|
||||
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<RifTextDataTableColumn> header =
|
||||
{ RifTextDataTableColumn( "First Seg" ),
|
||||
RifTextDataTableColumn( "Last Seg" ),
|
||||
RifTextDataTableColumn( "Branch Num" ),
|
||||
RifTextDataTableColumn( "Outlet Seg" ),
|
||||
RifTextDataTableColumn( "Length" ),
|
||||
RifTextDataTableColumn( "Depth Change" ),
|
||||
RifTextDataTableColumn( "Diam" ),
|
||||
RifTextDataTableColumn( "Rough", RifTextDataTableDoubleFormatting( RIF_FLOAT, 7 ) ) };
|
||||
formatter.header( header );
|
||||
}
|
||||
|
||||
int segmentNumber = 2; // There's an implicit segment number 1.
|
||||
|
||||
RicMswSegment* parentSegment = nullptr;
|
||||
writeWelsegsSegmentsRecursively( formatter,
|
||||
exportInfo,
|
||||
exportInfo.mainBoreBranch(),
|
||||
&segmentNumber,
|
||||
maxSegmentLength,
|
||||
exportCompletionSegmentsAfterMainBore,
|
||||
parentSegment );
|
||||
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::writeWelsegsSegmentsRecursively( RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
gsl::not_null<RicMswBranch*> branch,
|
||||
gsl::not_null<int*> segmentNumber,
|
||||
double maxSegmentLength,
|
||||
bool exportCompletionSegmentsAfterMainBore,
|
||||
RicMswSegment* connectedToSegment )
|
||||
{
|
||||
auto outletSegment = connectedToSegment;
|
||||
|
||||
RicMswValve* outletValve = nullptr;
|
||||
|
||||
auto branchSegments = branch->segments();
|
||||
auto it = branchSegments.begin();
|
||||
if ( outletValve = dynamic_cast<RicMswTieInICV*>( branch.get() ); outletValve != nullptr )
|
||||
{
|
||||
writeValveWelsegsSegment( outletSegment, outletValve, formatter, exportInfo, maxSegmentLength, segmentNumber );
|
||||
|
||||
auto valveSegments = outletValve->segments();
|
||||
outletSegment = valveSegments.front();
|
||||
|
||||
*segmentNumber = outletSegment->segmentNumber() + 1;
|
||||
++it; // skip segment below
|
||||
}
|
||||
|
||||
formatter.addOptionalComment( QString( "Segments on branch %1" ).arg( branch->label() ) );
|
||||
|
||||
auto branchStartSegmentIterator = it;
|
||||
for ( ; it != branchSegments.end(); ++it )
|
||||
{
|
||||
auto segment = *it;
|
||||
segment->setSegmentNumber( *segmentNumber );
|
||||
|
||||
if ( segment->subIndex() != cvf::UNDEFINED_SIZE_T )
|
||||
{
|
||||
QString comment = segment->label() + QString( ", sub %1" ).arg( segment->subIndex() + 1 );
|
||||
formatter.addOptionalComment( comment );
|
||||
}
|
||||
|
||||
writeWelsegsSegment( segment, outletSegment, formatter, exportInfo, maxSegmentLength, branch, segmentNumber );
|
||||
outletSegment = segment;
|
||||
|
||||
if ( !exportCompletionSegmentsAfterMainBore )
|
||||
{
|
||||
writeCompletionsForSegment( outletSegment, segment, &outletValve, formatter, exportInfo, maxSegmentLength, segmentNumber );
|
||||
}
|
||||
}
|
||||
|
||||
if ( exportCompletionSegmentsAfterMainBore )
|
||||
{
|
||||
it = branchStartSegmentIterator;
|
||||
|
||||
for ( ; it != branchSegments.end(); ++it )
|
||||
{
|
||||
auto segment = *it;
|
||||
|
||||
writeCompletionsForSegment( outletSegment, segment, &outletValve, formatter, exportInfo, maxSegmentLength, segmentNumber );
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto childBranch : branch->branches() )
|
||||
{
|
||||
RicMswSegment* outletSegmentForChildBranch = outletSegment;
|
||||
|
||||
RicMswSegment* tieInSegmentOnParentBranch = branch->findClosestSegmentByMidpoint( childBranch->startMD() );
|
||||
if ( tieInSegmentOnParentBranch ) outletSegmentForChildBranch = tieInSegmentOnParentBranch;
|
||||
|
||||
writeWelsegsSegmentsRecursively( formatter,
|
||||
exportInfo,
|
||||
childBranch,
|
||||
segmentNumber,
|
||||
maxSegmentLength,
|
||||
exportCompletionSegmentsAfterMainBore,
|
||||
outletSegmentForChildBranch );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::writeWelsegsCompletionCommentHeader( RifTextDataTableFormatter& formatter,
|
||||
RigCompletionData::CompletionType completionType )
|
||||
{
|
||||
QString optionalCommentText;
|
||||
|
||||
switch ( completionType )
|
||||
{
|
||||
case RigCompletionData::FISHBONES:
|
||||
break;
|
||||
case RigCompletionData::FRACTURE:
|
||||
optionalCommentText = "Fracture Segments";
|
||||
break;
|
||||
case RigCompletionData::PERFORATION:
|
||||
optionalCommentText = "Perforation Segments";
|
||||
break;
|
||||
case RigCompletionData::FISHBONES_ICD:
|
||||
optionalCommentText = "Fishbones Segments - ICD";
|
||||
break;
|
||||
case RigCompletionData::PERFORATION_ICD:
|
||||
optionalCommentText = "Perforation Segments - ICD";
|
||||
break;
|
||||
case RigCompletionData::PERFORATION_AICD:
|
||||
optionalCommentText = "Perforation Segments - AICD";
|
||||
break;
|
||||
case RigCompletionData::PERFORATION_ICV:
|
||||
optionalCommentText = "Perforation Segments - ICV";
|
||||
break;
|
||||
case RigCompletionData::CT_UNDEFINED:
|
||||
optionalCommentText = "Main Stem";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !optionalCommentText.isEmpty() )
|
||||
{
|
||||
formatter.addOptionalComment( optionalCommentText );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::generateCompsegTables( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo )
|
||||
{
|
||||
/*
|
||||
* TODO: Creating the regular perforation COMPSEGS table should come in here, before the others
|
||||
* should take precedence by appearing later in the output. See #3230.
|
||||
*/
|
||||
|
||||
std::set<size_t> intersectedCells;
|
||||
|
||||
{
|
||||
std::set<RigCompletionData::CompletionType> perforationTypes = { RigCompletionData::PERFORATION,
|
||||
RigCompletionData::PERFORATION_ICD,
|
||||
RigCompletionData::PERFORATION_ICV,
|
||||
RigCompletionData::PERFORATION_AICD };
|
||||
|
||||
{
|
||||
bool headerGenerated = false;
|
||||
generateCompsegTable( formatter,
|
||||
exportInfo,
|
||||
exportInfo.mainBoreBranch(),
|
||||
false,
|
||||
perforationTypes,
|
||||
&headerGenerated,
|
||||
&intersectedCells );
|
||||
|
||||
if ( headerGenerated ) formatter.tableCompleted();
|
||||
}
|
||||
|
||||
if ( exportInfo.hasSubGridIntersections() )
|
||||
{
|
||||
bool headerGenerated = false;
|
||||
generateCompsegTable( formatter,
|
||||
exportInfo,
|
||||
exportInfo.mainBoreBranch(),
|
||||
true,
|
||||
perforationTypes,
|
||||
&headerGenerated,
|
||||
&intersectedCells );
|
||||
if ( headerGenerated ) formatter.tableCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::set<RigCompletionData::CompletionType> fishbonesTypes = { RigCompletionData::FISHBONES_ICD,
|
||||
RigCompletionData::FISHBONES };
|
||||
{
|
||||
bool headerGenerated = false;
|
||||
generateCompsegTable( formatter,
|
||||
exportInfo,
|
||||
exportInfo.mainBoreBranch(),
|
||||
false,
|
||||
fishbonesTypes,
|
||||
&headerGenerated,
|
||||
&intersectedCells );
|
||||
if ( headerGenerated ) formatter.tableCompleted();
|
||||
}
|
||||
if ( exportInfo.hasSubGridIntersections() )
|
||||
{
|
||||
bool headerGenerated = false;
|
||||
generateCompsegTable( formatter,
|
||||
exportInfo,
|
||||
exportInfo.mainBoreBranch(),
|
||||
true,
|
||||
fishbonesTypes,
|
||||
&headerGenerated,
|
||||
&intersectedCells );
|
||||
if ( headerGenerated ) formatter.tableCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::set<RigCompletionData::CompletionType> fractureTypes = { RigCompletionData::FRACTURE };
|
||||
|
||||
{
|
||||
bool headerGenerated = false;
|
||||
generateCompsegTable( formatter,
|
||||
exportInfo,
|
||||
exportInfo.mainBoreBranch(),
|
||||
false,
|
||||
fractureTypes,
|
||||
&headerGenerated,
|
||||
&intersectedCells );
|
||||
if ( headerGenerated ) formatter.tableCompleted();
|
||||
}
|
||||
|
||||
if ( exportInfo.hasSubGridIntersections() )
|
||||
{
|
||||
bool headerGenerated = false;
|
||||
generateCompsegTable( formatter,
|
||||
exportInfo,
|
||||
exportInfo.mainBoreBranch(),
|
||||
true,
|
||||
fractureTypes,
|
||||
&headerGenerated,
|
||||
&intersectedCells );
|
||||
if ( headerGenerated ) formatter.tableCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::generateCompsegTable( RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
gsl::not_null<const RicMswBranch*> branch,
|
||||
bool exportSubGridIntersections,
|
||||
const std::set<RigCompletionData::CompletionType>& exportCompletionTypes,
|
||||
gsl::not_null<bool*> headerGenerated,
|
||||
gsl::not_null<std::set<size_t>*> intersectedCells )
|
||||
{
|
||||
for ( auto segment : branch->segments() )
|
||||
{
|
||||
auto completion = dynamic_cast<const RicMswCompletion*>( branch.get() );
|
||||
|
||||
for ( auto intersection : segment->intersections() )
|
||||
{
|
||||
bool isSubGridIntersection = !intersection->gridName().isEmpty();
|
||||
if ( isSubGridIntersection != exportSubGridIntersections ) continue;
|
||||
|
||||
double startLength = segment->startMD();
|
||||
double endLength = segment->endMD();
|
||||
|
||||
if ( completion )
|
||||
{
|
||||
bool isPerforationValve = completion->completionType() == RigCompletionData::PERFORATION_ICD ||
|
||||
completion->completionType() == RigCompletionData::PERFORATION_AICD ||
|
||||
completion->completionType() == RigCompletionData::PERFORATION_ICV;
|
||||
|
||||
if ( isPerforationValve )
|
||||
{
|
||||
startLength = segment->startMD();
|
||||
endLength = segment->endMD();
|
||||
}
|
||||
}
|
||||
|
||||
size_t globalCellIndex = intersection->globalCellIndex();
|
||||
|
||||
// Here we check if the cell is already reported. Make sure we report intersections before other completions
|
||||
// on the segment to be able to connect the branch with most flow
|
||||
if ( !intersectedCells->count( globalCellIndex ) )
|
||||
{
|
||||
if ( exportSubGridIntersections )
|
||||
{
|
||||
formatter.add( intersection->gridName() );
|
||||
}
|
||||
|
||||
cvf::Vec3st ijk = intersection->gridLocalCellIJK();
|
||||
formatter.addOneBasedCellIndex( ijk.x() ).addOneBasedCellIndex( ijk.y() ).addOneBasedCellIndex( ijk.z() );
|
||||
|
||||
int branchNumber = -1;
|
||||
if ( completion ) branchNumber = completion->branchNumber();
|
||||
formatter.add( branchNumber );
|
||||
|
||||
formatter.add( startLength );
|
||||
formatter.add( endLength );
|
||||
|
||||
formatter.rowCompleted();
|
||||
intersectedCells->insert( globalCellIndex );
|
||||
}
|
||||
}
|
||||
|
||||
// Report connected completions after the intersection on current segment has been reported
|
||||
for ( auto completion : segment->completions() )
|
||||
{
|
||||
if ( completion->segments().empty() || !exportCompletionTypes.count( completion->completionType() ) )
|
||||
continue;
|
||||
|
||||
if ( !*headerGenerated )
|
||||
{
|
||||
generateCompsegHeader( formatter, exportInfo, completion->completionType(), exportSubGridIntersections );
|
||||
*headerGenerated = true;
|
||||
}
|
||||
|
||||
generateCompsegTable( formatter,
|
||||
exportInfo,
|
||||
completion,
|
||||
exportSubGridIntersections,
|
||||
exportCompletionTypes,
|
||||
headerGenerated,
|
||||
intersectedCells );
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto childBranch : branch->branches() )
|
||||
{
|
||||
generateCompsegTable( formatter,
|
||||
exportInfo,
|
||||
childBranch,
|
||||
exportSubGridIntersections,
|
||||
exportCompletionTypes,
|
||||
headerGenerated,
|
||||
intersectedCells );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::generateCompsegHeader( RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
RigCompletionData::CompletionType completionType,
|
||||
bool exportSubGridIntersections )
|
||||
{
|
||||
if ( exportSubGridIntersections )
|
||||
{
|
||||
formatter.keyword( "COMPSEGL" );
|
||||
}
|
||||
else
|
||||
{
|
||||
formatter.keyword( "COMPSEGS" );
|
||||
}
|
||||
|
||||
if ( completionType == RigCompletionData::FISHBONES_ICD )
|
||||
{
|
||||
formatter.comment( "Fishbones" );
|
||||
}
|
||||
else if ( completionType == RigCompletionData::FRACTURE )
|
||||
{
|
||||
formatter.comment( "Fractures" );
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<RifTextDataTableColumn> header = { RifTextDataTableColumn( "Name" ) };
|
||||
formatter.header( header );
|
||||
formatter.add( exportInfo.mainBoreBranch()->wellPath()->completionSettings()->wellNameForExport() );
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<RifTextDataTableColumn> allHeaders;
|
||||
if ( exportSubGridIntersections )
|
||||
{
|
||||
allHeaders.push_back( RifTextDataTableColumn( "Grid" ) );
|
||||
}
|
||||
|
||||
std::vector<RifTextDataTableColumn> commonHeaders = { RifTextDataTableColumn( "I" ),
|
||||
RifTextDataTableColumn( "J" ),
|
||||
RifTextDataTableColumn( "K" ),
|
||||
RifTextDataTableColumn( "Branch no" ),
|
||||
RifTextDataTableColumn( "Start Length" ),
|
||||
RifTextDataTableColumn( "End Length" ),
|
||||
RifTextDataTableColumn( "Dir Pen" ),
|
||||
RifTextDataTableColumn( "End Range" ),
|
||||
RifTextDataTableColumn( "Connection Depth" ) };
|
||||
allHeaders.insert( allHeaders.end(), commonHeaders.begin(), commonHeaders.end() );
|
||||
formatter.header( allHeaders );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::generateWsegvalvTable( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo )
|
||||
{
|
||||
bool foundValve = false;
|
||||
|
||||
generateWsegvalvTableRecursively( formatter,
|
||||
exportInfo.mainBoreBranch(),
|
||||
foundValve,
|
||||
exportInfo.mainBoreBranch()->wellPath()->completionSettings()->wellNameForExport() );
|
||||
|
||||
if ( foundValve )
|
||||
{
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::generateWsegvalvTableRecursively( RifTextDataTableFormatter& formatter,
|
||||
gsl::not_null<RicMswBranch*> branch,
|
||||
bool& isHeaderWritten,
|
||||
const QString& wellNameForExport )
|
||||
{
|
||||
{
|
||||
auto tieInValve = dynamic_cast<RicMswTieInICV*>( branch.get() );
|
||||
if ( tieInValve && !tieInValve->segments().empty() )
|
||||
{
|
||||
if ( !isHeaderWritten )
|
||||
{
|
||||
writeWsegvalHeader( formatter );
|
||||
|
||||
isHeaderWritten = true;
|
||||
}
|
||||
|
||||
auto firstSubSegment = tieInValve->segments().front();
|
||||
CAF_ASSERT( tieInValve->completionType() == RigCompletionData::PERFORATION_ICV );
|
||||
{
|
||||
formatter.addOptionalComment( tieInValve->label() );
|
||||
}
|
||||
formatter.add( wellNameForExport );
|
||||
formatter.add( firstSubSegment->segmentNumber() );
|
||||
formatter.add( tieInValve->flowCoefficient() );
|
||||
formatter.add( QString( "%1" ).arg( tieInValve->area(), 8, 'g', 4 ) );
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto segment : branch->segments() )
|
||||
{
|
||||
for ( auto completion : segment->completions() )
|
||||
{
|
||||
if ( RigCompletionData::isWsegValveTypes( completion->completionType() ) )
|
||||
{
|
||||
if ( !isHeaderWritten )
|
||||
{
|
||||
writeWsegvalHeader( formatter );
|
||||
|
||||
isHeaderWritten = true;
|
||||
}
|
||||
|
||||
auto wsegValve = static_cast<RicMswWsegValve*>( completion );
|
||||
if ( !wsegValve->segments().empty() )
|
||||
{
|
||||
CVF_ASSERT( wsegValve->segments().size() == 1u );
|
||||
|
||||
auto firstSubSegment = wsegValve->segments().front();
|
||||
|
||||
// TODO: The following line was blocking export of valves for fishbones
|
||||
// Unclear why this line was included. Remove when MSW export has ben verified correctly
|
||||
// if ( !firstSubSegment->intersections().empty() )
|
||||
{
|
||||
if ( wsegValve->completionType() == RigCompletionData::PERFORATION_ICD ||
|
||||
wsegValve->completionType() == RigCompletionData::PERFORATION_ICV )
|
||||
{
|
||||
formatter.addOptionalComment( wsegValve->label() );
|
||||
}
|
||||
formatter.add( wellNameForExport );
|
||||
formatter.add( firstSubSegment->segmentNumber() );
|
||||
formatter.add( wsegValve->flowCoefficient() );
|
||||
formatter.add( QString( "%1" ).arg( wsegValve->area(), 8, 'g', 4 ) );
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto childBranch : branch->branches() )
|
||||
{
|
||||
generateWsegvalvTableRecursively( formatter, childBranch, isHeaderWritten, wellNameForExport );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::generateWsegAicdTable( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo )
|
||||
{
|
||||
RifTextDataTableFormatter tighterFormatter( formatter );
|
||||
tighterFormatter.setColumnSpacing( 1 );
|
||||
tighterFormatter.setTableRowPrependText( " " );
|
||||
|
||||
bool foundValve = false;
|
||||
|
||||
for ( auto segment : exportInfo.mainBoreBranch()->segments() )
|
||||
{
|
||||
for ( auto completion : segment->completions() )
|
||||
{
|
||||
if ( completion->completionType() == RigCompletionData::PERFORATION_AICD )
|
||||
{
|
||||
auto aicd = static_cast<RicMswPerforationAICD*>( completion );
|
||||
if ( aicd->isValid() )
|
||||
{
|
||||
if ( !foundValve )
|
||||
{
|
||||
std::vector<QString> columnDescriptions =
|
||||
{ "Well Name",
|
||||
"Segment Number",
|
||||
"Segment Number",
|
||||
"Strength of AICD",
|
||||
"Flow Scaling Factor for AICD",
|
||||
"Density of Calibration Fluid",
|
||||
"Viscosity of Calibration Fluid",
|
||||
"Critical water in liquid fraction for emulsions viscosity model",
|
||||
"Emulsion viscosity transition region",
|
||||
"Max ratio of emulsion viscosity to continuous phase viscosity",
|
||||
"Flow scaling factor method",
|
||||
"Maximum flow rate for AICD device",
|
||||
"Volume flow rate exponent, x",
|
||||
"Viscosity function exponent, y",
|
||||
"Device OPEN/SHUT",
|
||||
"Exponent of the oil flowing fraction in the density mixture calculation",
|
||||
"Exponent of the water flowing fraction in the density mixture calculation",
|
||||
"Exponent of the gas flowing fraction in the density mixture calculation",
|
||||
"Exponent of the oil flowing fraction in the density viscosity calculation",
|
||||
"Exponent of the water flowing fraction in the density viscosity calculation",
|
||||
"Exponent of the gas flowing fraction in the density viscosity calculation" };
|
||||
|
||||
tighterFormatter.keyword( "WSEGAICD" );
|
||||
tighterFormatter.comment( "Column Overview:" );
|
||||
for ( size_t i = 0; i < columnDescriptions.size(); ++i )
|
||||
{
|
||||
tighterFormatter.comment(
|
||||
QString( "%1: %2" ).arg( i + 1, 2, 10, QChar( '0' ) ).arg( columnDescriptions[i] ) );
|
||||
}
|
||||
|
||||
std::vector<RifTextDataTableColumn> header;
|
||||
for ( size_t i = 1; i <= 21; ++i )
|
||||
{
|
||||
QString cName = QString( "%1" ).arg( i, 2, 10, QChar( '0' ) );
|
||||
RifTextDataTableColumn col( cName,
|
||||
RifTextDataTableDoubleFormatting(
|
||||
RifTextDataTableDoubleFormat::RIF_CONSISE ),
|
||||
RIGHT );
|
||||
header.push_back( col );
|
||||
}
|
||||
tighterFormatter.header( header );
|
||||
|
||||
foundValve = true;
|
||||
}
|
||||
if ( !aicd->segments().empty() )
|
||||
{
|
||||
CVF_ASSERT( aicd->segments().size() == 1u );
|
||||
tighterFormatter.comment( aicd->label() );
|
||||
tighterFormatter.add(
|
||||
exportInfo.mainBoreBranch()->wellPath()->completionSettings()->wellNameForExport() ); // #1
|
||||
tighterFormatter.add( aicd->segments().front()->segmentNumber() );
|
||||
tighterFormatter.add( aicd->segments().front()->segmentNumber() );
|
||||
|
||||
std::array<double, AICD_NUM_PARAMS> values = aicd->values();
|
||||
tighterFormatter.add( values[AICD_STRENGTH] );
|
||||
|
||||
tighterFormatter.add( aicd->flowScalingFactor() ); // #5 Flow scaling factor used when item
|
||||
// #11 is set to '1'
|
||||
|
||||
tighterFormatter.add( values[AICD_DENSITY_CALIB_FLUID] );
|
||||
tighterFormatter.add( values[AICD_VISCOSITY_CALIB_FLUID] );
|
||||
tighterFormatter.addValueOrDefaultMarker( values[AICD_CRITICAL_WATER_IN_LIQUID_FRAC],
|
||||
RicMswExportInfo::defaultDoubleValue() );
|
||||
tighterFormatter.addValueOrDefaultMarker( values[AICD_EMULSION_VISC_TRANS_REGION],
|
||||
RicMswExportInfo::defaultDoubleValue() );
|
||||
tighterFormatter.addValueOrDefaultMarker( values[AICD_MAX_RATIO_EMULSION_VISC],
|
||||
RicMswExportInfo::defaultDoubleValue() ); // #10
|
||||
|
||||
tighterFormatter.add( 1 ); // #11 : Always use method "b. Scale factor". The value of the
|
||||
// scale factor is given in item #5
|
||||
|
||||
tighterFormatter.addValueOrDefaultMarker( values[AICD_MAX_FLOW_RATE],
|
||||
RicMswExportInfo::defaultDoubleValue() );
|
||||
tighterFormatter.add( values[AICD_VOL_FLOW_EXP] );
|
||||
tighterFormatter.add( values[AICD_VISOSITY_FUNC_EXP] );
|
||||
tighterFormatter.add( aicd->isOpen() ? "OPEN" : "SHUT" ); // #15
|
||||
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_OIL_FRAC_DENSITY],
|
||||
RicMswExportInfo::defaultDoubleValue() );
|
||||
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_WATER_FRAC_DENSITY],
|
||||
RicMswExportInfo::defaultDoubleValue() );
|
||||
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_GAS_FRAC_DENSITY],
|
||||
RicMswExportInfo::defaultDoubleValue() );
|
||||
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_OIL_FRAC_VISCOSITY],
|
||||
RicMswExportInfo::defaultDoubleValue() );
|
||||
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_WATER_FRAC_VISCOSITY],
|
||||
RicMswExportInfo::defaultDoubleValue() ); // #20
|
||||
tighterFormatter.addValueOrDefaultMarker( values[AICD_EXP_GAS_FRAC_VISCOSITY],
|
||||
RicMswExportInfo::defaultDoubleValue() );
|
||||
tighterFormatter.rowCompleted();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( QString( "Export AICD Valve (%1): Valve is invalid. At least one required "
|
||||
"template parameter is not set." )
|
||||
.arg( aicd->label() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( foundValve )
|
||||
{
|
||||
tighterFormatter.tableCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::writeWelsegsSegment( RicMswSegment* segment,
|
||||
const RicMswSegment* previousSegment,
|
||||
RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
gsl::not_null<RicMswBranch*> branch,
|
||||
int* segmentNumber )
|
||||
{
|
||||
CVF_ASSERT( segment && segmentNumber );
|
||||
|
||||
double startMD = segment->startMD();
|
||||
double endMD = segment->endMD();
|
||||
|
||||
std::vector<std::pair<double, double>> segments = createSubSegmentMDPairs( startMD, endMD, maxSegmentLength );
|
||||
|
||||
CVF_ASSERT( branch->wellPath() );
|
||||
auto wellPathGeometry = branch->wellPath()->wellPathGeometry();
|
||||
CVF_ASSERT( wellPathGeometry );
|
||||
|
||||
double prevOutMD = branch->startMD();
|
||||
double prevOutTVD = branch->startTVD();
|
||||
if ( previousSegment )
|
||||
{
|
||||
prevOutMD = previousSegment->outputMD();
|
||||
prevOutTVD = previousSegment->outputTVD();
|
||||
}
|
||||
|
||||
auto outletSegment = previousSegment;
|
||||
for ( const auto& [subStartMD, subEndMD] : segments )
|
||||
{
|
||||
double depth = 0;
|
||||
double length = 0;
|
||||
|
||||
double midPointMD = 0.5 * ( subStartMD + subEndMD );
|
||||
double midPointTVD = tvdFromMeasuredDepth( branch->wellPath(), midPointMD );
|
||||
|
||||
if ( exportInfo.lengthAndDepthText() == QString( "INC" ) )
|
||||
{
|
||||
depth = midPointTVD - prevOutTVD;
|
||||
length = midPointMD - prevOutMD;
|
||||
}
|
||||
else
|
||||
{
|
||||
depth = midPointTVD;
|
||||
length = midPointMD;
|
||||
}
|
||||
segment->setOutputMD( midPointMD );
|
||||
segment->setOutputTVD( midPointTVD );
|
||||
segment->setSegmentNumber( *segmentNumber );
|
||||
|
||||
formatter.add( *segmentNumber ).add( *segmentNumber );
|
||||
formatter.add( branch->branchNumber() );
|
||||
if ( outletSegment )
|
||||
formatter.add( outletSegment->segmentNumber() );
|
||||
else
|
||||
formatter.add( 1 );
|
||||
formatter.add( length );
|
||||
formatter.add( depth );
|
||||
formatter.add( exportInfo.linerDiameter() );
|
||||
formatter.add( exportInfo.roughnessFactor() );
|
||||
formatter.rowCompleted();
|
||||
( *segmentNumber )++;
|
||||
outletSegment = segment;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::writeValveWelsegsSegment( const RicMswSegment* outletSegment,
|
||||
RicMswValve* valve,
|
||||
RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
int* segmentNumber )
|
||||
{
|
||||
CVF_ASSERT( valve );
|
||||
if ( !valve->isValid() ) return;
|
||||
|
||||
CVF_ASSERT( !valve->label().isEmpty() );
|
||||
CVF_ASSERT( valve->wellPath() );
|
||||
|
||||
formatter.addOptionalComment( valve->label() );
|
||||
|
||||
auto segments = valve->segments();
|
||||
|
||||
auto subSegment = segments.front();
|
||||
subSegment->setSegmentNumber( *segmentNumber );
|
||||
|
||||
double startMD = subSegment->startMD();
|
||||
double endMD = subSegment->endMD();
|
||||
|
||||
double midPointMD = 0.5 * ( startMD + endMD );
|
||||
double midPointTVD = tvdFromMeasuredDepth( valve->wellPath(), midPointMD );
|
||||
|
||||
subSegment->setOutputMD( midPointMD );
|
||||
subSegment->setOutputTVD( midPointTVD );
|
||||
|
||||
std::vector<std::pair<double, double>> splitSegments = createSubSegmentMDPairs( startMD, endMD, maxSegmentLength );
|
||||
|
||||
auto wellPathGeometry = valve->wellPath()->wellPathGeometry();
|
||||
CVF_ASSERT( wellPathGeometry );
|
||||
|
||||
for ( const auto& [subStartMD, subEndMD] : splitSegments )
|
||||
{
|
||||
int subSegmentNumber = ( *segmentNumber )++;
|
||||
|
||||
double subStartTVD = tvdFromMeasuredDepth( valve->wellPath(), subStartMD );
|
||||
double subEndTVD = tvdFromMeasuredDepth( valve->wellPath(), subEndMD );
|
||||
|
||||
double depth = 0;
|
||||
double length = 0;
|
||||
|
||||
if ( exportInfo.lengthAndDepthText() == QString( "INC" ) )
|
||||
{
|
||||
depth = subEndTVD - subStartTVD;
|
||||
length = subEndMD - subStartMD;
|
||||
}
|
||||
else
|
||||
{
|
||||
depth = subEndTVD;
|
||||
length = subEndMD;
|
||||
}
|
||||
|
||||
formatter.add( subSegmentNumber );
|
||||
formatter.add( subSegmentNumber );
|
||||
formatter.add( valve->branchNumber() );
|
||||
formatter.add( outletSegment->segmentNumber() );
|
||||
|
||||
formatter.add( length );
|
||||
formatter.add( depth );
|
||||
formatter.add( exportInfo.linerDiameter() );
|
||||
formatter.add( exportInfo.roughnessFactor() );
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::writeCompletionWelsegsSegments( gsl::not_null<const RicMswSegment*> outletSegment,
|
||||
gsl::not_null<const RicMswCompletion*> completion,
|
||||
RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
int* segmentNumber )
|
||||
{
|
||||
writeWelsegsCompletionCommentHeader( formatter, completion->completionType() );
|
||||
|
||||
if ( completion->completionType() == RigCompletionData::FISHBONES )
|
||||
{
|
||||
formatter.addOptionalComment(
|
||||
QString( "Sub index %1 - %2" ).arg( outletSegment->subIndex() + 1 ).arg( completion->label() ) );
|
||||
}
|
||||
else if ( completion->completionType() == RigCompletionData::FRACTURE )
|
||||
{
|
||||
formatter.addOptionalComment(
|
||||
QString( "%1 connected to segment %2" ).arg( completion->label() ).arg( outletSegment->segmentNumber() ) );
|
||||
}
|
||||
|
||||
CVF_ASSERT( completion->wellPath() );
|
||||
|
||||
int outletSegmentNumber = outletSegment->segmentNumber();
|
||||
|
||||
for ( auto segment : completion->segments() )
|
||||
{
|
||||
double startMD = segment->startMD();
|
||||
double endMD = segment->endMD();
|
||||
|
||||
std::vector<std::pair<double, double>> splitSegments = createSubSegmentMDPairs( startMD, endMD, maxSegmentLength );
|
||||
|
||||
for ( const auto& [subStartMD, subEndMD] : splitSegments )
|
||||
{
|
||||
int subSegmentNumber = ( *segmentNumber )++;
|
||||
|
||||
double subStartTVD = tvdFromMeasuredDepth( completion->wellPath(), subStartMD );
|
||||
double subEndTVD = tvdFromMeasuredDepth( completion->wellPath(), subEndMD );
|
||||
|
||||
double depth = 0;
|
||||
double length = 0;
|
||||
|
||||
if ( exportInfo.lengthAndDepthText() == QString( "INC" ) )
|
||||
{
|
||||
depth = subEndTVD - subStartTVD;
|
||||
length = subEndMD - subStartMD;
|
||||
}
|
||||
else
|
||||
{
|
||||
depth = subEndTVD;
|
||||
length = subEndMD;
|
||||
}
|
||||
formatter.add( subSegmentNumber );
|
||||
formatter.add( subSegmentNumber );
|
||||
formatter.add( completion->branchNumber() );
|
||||
formatter.add( outletSegmentNumber );
|
||||
formatter.add( length );
|
||||
formatter.add( depth );
|
||||
formatter.add( segment->equivalentDiameter() );
|
||||
formatter.add( segment->openHoleRoughnessFactor() );
|
||||
formatter.rowCompleted();
|
||||
outletSegmentNumber = subSegmentNumber;
|
||||
}
|
||||
|
||||
for ( auto completionSegment : completion->segments() )
|
||||
{
|
||||
auto noConst = const_cast<RicMswSegment*>( completionSegment );
|
||||
noConst->setSegmentNumber( outletSegmentNumber );
|
||||
for ( auto comp : completionSegment->completions() )
|
||||
{
|
||||
writeCompletionWelsegsSegments( completionSegment, comp, formatter, exportInfo, maxSegmentLength, segmentNumber );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::writeCompletionsForSegment( gsl::not_null<const RicMswSegment*> outletSegment,
|
||||
gsl::not_null<RicMswSegment*> segment,
|
||||
RicMswValve** outletValve,
|
||||
RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
int* segmentNumber )
|
||||
{
|
||||
for ( auto& completion : segment->completions() )
|
||||
{
|
||||
// For a well with perforation intervals, the WELSEGS segments are reported twice if if we include the
|
||||
// RicMswPerforation completions. Investigate when this class is intended to be exported to file
|
||||
auto performationMsw = dynamic_cast<RicMswPerforation*>( completion );
|
||||
if ( performationMsw ) continue;
|
||||
|
||||
auto segmentValve = dynamic_cast<RicMswValve*>( completion );
|
||||
auto fishboneIcd = dynamic_cast<RicMswFishbonesICD*>( completion );
|
||||
if ( !fishboneIcd && segmentValve != nullptr )
|
||||
{
|
||||
writeValveWelsegsSegment( segment, segmentValve, formatter, exportInfo, maxSegmentLength, segmentNumber );
|
||||
*outletValve = segmentValve;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we have a valve, the outlet segment is the valve's segment
|
||||
RicMswSegment* outletSegment = *outletValve && ( *outletValve )->segmentCount() > 0
|
||||
? ( *outletValve )->segments().front()
|
||||
: segment.get();
|
||||
writeCompletionWelsegsSegments( outletSegment, completion, formatter, exportInfo, maxSegmentLength, segmentNumber );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<std::pair<double, double>>
|
||||
RicMswTableFormatterTools::createSubSegmentMDPairs( double startMD, double endMD, double maxSegmentLength )
|
||||
{
|
||||
int subSegmentCount = (int)( std::trunc( ( endMD - startMD ) / maxSegmentLength ) + 1 );
|
||||
|
||||
double subSegmentLength = ( endMD - startMD ) / subSegmentCount;
|
||||
|
||||
std::vector<std::pair<double, double>> subSegmentMDPairs;
|
||||
|
||||
double subStartMD = startMD;
|
||||
double subEndMD = startMD + subSegmentLength;
|
||||
for ( int i = 0; i < subSegmentCount; ++i )
|
||||
{
|
||||
subSegmentMDPairs.push_back( std::make_pair( subStartMD, subEndMD ) );
|
||||
subStartMD += subSegmentLength;
|
||||
subEndMD += std::min( subSegmentLength, endMD );
|
||||
}
|
||||
return subSegmentMDPairs;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RicMswTableFormatterTools::tvdFromMeasuredDepth( gsl::not_null<const RimWellPath*> wellPath, double measuredDepth )
|
||||
{
|
||||
auto wellPathGeometry = wellPath->wellPathGeometry();
|
||||
CVF_ASSERT( wellPathGeometry );
|
||||
|
||||
double tvdValue = -wellPathGeometry->interpolatedPointAlongWellPath( measuredDepth ).z();
|
||||
|
||||
return tvdValue;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMswTableFormatterTools::writeWsegvalHeader( RifTextDataTableFormatter& formatter )
|
||||
{
|
||||
formatter.keyword( "WSEGVALV" );
|
||||
std::vector<RifTextDataTableColumn> header = {
|
||||
RifTextDataTableColumn( "Well Name" ),
|
||||
RifTextDataTableColumn( "Seg No" ),
|
||||
RifTextDataTableColumn( "Cv" ),
|
||||
RifTextDataTableColumn( "Ac" ),
|
||||
};
|
||||
formatter.header( header );
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2021 Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RigCompletionData.h"
|
||||
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <gsl/gsl>
|
||||
|
||||
class RicMswExportInfo;
|
||||
class RifTextDataTableFormatter;
|
||||
class RicMswBranch;
|
||||
class RicMswSegment;
|
||||
class RicMswValve;
|
||||
class RicMswCompletion;
|
||||
class RimWellPath;
|
||||
|
||||
namespace RicMswTableFormatterTools
|
||||
{
|
||||
class CvfVec3stComparator
|
||||
{
|
||||
public:
|
||||
bool operator()( const cvf::Vec3st& lhs, const cvf::Vec3st& rhs ) const
|
||||
{
|
||||
if ( lhs.z() == rhs.z() )
|
||||
{
|
||||
if ( lhs.y() == rhs.y() )
|
||||
{
|
||||
return lhs.x() < rhs.x();
|
||||
}
|
||||
return lhs.y() < rhs.y();
|
||||
}
|
||||
return lhs.z() < rhs.z();
|
||||
}
|
||||
};
|
||||
|
||||
void generateWelsegsTable( RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
bool exportCompletionSegmentsAfterMainBore );
|
||||
|
||||
void writeWelsegsSegmentsRecursively( RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
gsl::not_null<RicMswBranch*> branch,
|
||||
gsl::not_null<int*> segmentNumber,
|
||||
double maxSegmentLength,
|
||||
bool exportCompletionSegmentsAfterMainBore,
|
||||
RicMswSegment* connectedToSegment );
|
||||
|
||||
void writeWelsegsSegment( RicMswSegment* segment,
|
||||
const RicMswSegment* previousSegment,
|
||||
RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
gsl::not_null<RicMswBranch*> branch,
|
||||
int* segmentNumber );
|
||||
|
||||
void writeValveWelsegsSegment( const RicMswSegment* outletSegment,
|
||||
RicMswValve* valve,
|
||||
RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
int* segmentNumber );
|
||||
|
||||
void writeCompletionWelsegsSegments( gsl::not_null<const RicMswSegment*> outletSegment,
|
||||
gsl::not_null<const RicMswCompletion*> completion,
|
||||
RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
int* segmentNumber );
|
||||
|
||||
void writeCompletionsForSegment( gsl::not_null<const RicMswSegment*> outletSegment,
|
||||
gsl::not_null<RicMswSegment*> segment,
|
||||
RicMswValve** outletValve,
|
||||
RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
int* segmentNumber );
|
||||
|
||||
void writeWelsegsCompletionCommentHeader( RifTextDataTableFormatter& formatter,
|
||||
RigCompletionData::CompletionType completionType );
|
||||
|
||||
void generateCompsegTables( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo );
|
||||
|
||||
void generateCompsegTable( RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
gsl::not_null<const RicMswBranch*> branch,
|
||||
bool exportSubGridIntersections,
|
||||
const std::set<RigCompletionData::CompletionType>& exportCompletionTypes,
|
||||
gsl::not_null<bool*> headerGenerated,
|
||||
gsl::not_null<std::set<size_t>*> intersectedCells );
|
||||
|
||||
void generateCompsegHeader( RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
RigCompletionData::CompletionType completionType,
|
||||
bool exportSubGridIntersections );
|
||||
|
||||
void generateWsegvalvTable( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo );
|
||||
|
||||
void generateWsegvalvTableRecursively( RifTextDataTableFormatter& formatter,
|
||||
gsl::not_null<RicMswBranch*> branch,
|
||||
bool& isHeaderWritten,
|
||||
const QString& wellNameForExport );
|
||||
|
||||
void generateWsegAicdTable( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo );
|
||||
|
||||
std::vector<std::pair<double, double>> createSubSegmentMDPairs( double startMD, double endMD, double maxSegmentLength );
|
||||
|
||||
double tvdFromMeasuredDepth( gsl::not_null<const RimWellPath*> wellPath, double measuredDepth );
|
||||
|
||||
void writeWsegvalHeader( RifTextDataTableFormatter& formatter );
|
||||
|
||||
} // namespace RicMswTableFormatterTools
|
@ -99,7 +99,33 @@ void RicWellPathExportCompletionDataFeature::prepareExportSettingsAndExportCompl
|
||||
s->descendantsIncludingThisOfType( simWellFractures );
|
||||
}
|
||||
|
||||
for ( auto w : wellPaths )
|
||||
std::vector<RimWellPath*> topLevelWells;
|
||||
{
|
||||
std::set<RimWellPath*> myWells;
|
||||
|
||||
for ( auto w : wellPaths )
|
||||
{
|
||||
myWells.insert( w->topLevelWellPath() );
|
||||
}
|
||||
|
||||
topLevelWells.assign( myWells.begin(), myWells.end() );
|
||||
}
|
||||
|
||||
std::vector<RimWellPath*> allLaterals;
|
||||
{
|
||||
std::set<RimWellPath*> laterals;
|
||||
|
||||
for ( auto t : topLevelWells )
|
||||
{
|
||||
auto laterals = t->wellPathLateralsRecursively();
|
||||
for ( auto l : laterals )
|
||||
{
|
||||
allLaterals.push_back( l );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto w : allLaterals )
|
||||
{
|
||||
w->descendantsIncludingThisOfType( wellPathFractures );
|
||||
w->descendantsIncludingThisOfType( wellPathFishbones );
|
||||
@ -162,7 +188,7 @@ void RicWellPathExportCompletionDataFeature::prepareExportSettingsAndExportCompl
|
||||
|
||||
RiaApplication::instance()->setLastUsedDialogDirectory( "COMPLETIONS", exportSettings->folder );
|
||||
|
||||
RicWellPathExportCompletionDataFeatureImpl::exportCompletions( wellPaths, simWells, *exportSettings );
|
||||
RicWellPathExportCompletionDataFeatureImpl::exportCompletions( topLevelWells, simWells, *exportSettings );
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,25 +246,5 @@ std::vector<RimWellPath*> RicWellPathExportCompletionDataFeature::selectedWellPa
|
||||
std::vector<RimWellPath*> wellPaths;
|
||||
caf::SelectionManager::instance()->objectsByType( &wellPaths );
|
||||
|
||||
std::set<RimWellPath*> uniqueWellPaths( wellPaths.begin(), wellPaths.end() );
|
||||
wellPaths.assign( uniqueWellPaths.begin(), uniqueWellPaths.end() );
|
||||
|
||||
if ( wellPaths.empty() )
|
||||
{
|
||||
RimWellPathCompletions* completions =
|
||||
caf::SelectionManager::instance()->selectedItemAncestorOfType<RimWellPathCompletions>();
|
||||
if ( completions )
|
||||
{
|
||||
RimWellPath* wellPath = nullptr;
|
||||
completions->firstAncestorOrThisOfTypeAsserted( wellPath );
|
||||
wellPaths.push_back( wellPath );
|
||||
}
|
||||
}
|
||||
|
||||
wellPaths.erase( std::remove_if( wellPaths.begin(),
|
||||
wellPaths.end(),
|
||||
[]( auto wellPath ) { return !wellPath->isTopLevelWellPath(); } ),
|
||||
wellPaths.end() );
|
||||
|
||||
return wellPaths;
|
||||
}
|
||||
|
@ -85,7 +85,7 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicWellPathExportCompletionDataFeatureImpl::exportCompletions( const std::vector<RimWellPath*>& wellPaths,
|
||||
void RicWellPathExportCompletionDataFeatureImpl::exportCompletions( const std::vector<RimWellPath*>& topLevelWellPaths,
|
||||
const std::vector<RimSimWellInView*>& simWells,
|
||||
const RicExportCompletionDataSettingsUi& exportSettings )
|
||||
{
|
||||
@ -111,12 +111,16 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions( const std::v
|
||||
if ( exportSettings.compdatExport == RicExportCompletionDataSettingsUi::TRANSMISSIBILITIES ||
|
||||
exportSettings.compdatExport == RicExportCompletionDataSettingsUi::WPIMULT_AND_DEFAULT_CONNECTION_FACTORS )
|
||||
{
|
||||
std::vector<RimWellPath*> usedWellPaths;
|
||||
for ( RimWellPath* wellPath : wellPaths )
|
||||
std::vector<RimWellPath*> allWellPathLaterals;
|
||||
for ( RimWellPath* wellPath : topLevelWellPaths )
|
||||
{
|
||||
if ( wellPath->unitSystem() == exportSettings.caseToApply->eclipseCaseData()->unitsType() )
|
||||
{
|
||||
usedWellPaths.push_back( wellPath );
|
||||
auto tieInWells = wellPath->wellPathLateralsRecursively();
|
||||
for ( auto w : tieInWells )
|
||||
{
|
||||
allWellPathLaterals.push_back( w );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -162,11 +166,11 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions( const std::v
|
||||
}
|
||||
|
||||
size_t maxProgress =
|
||||
usedWellPaths.size() * 3 + simWells.size() +
|
||||
allWellPathLaterals.size() * 3 + simWells.size() +
|
||||
( exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL
|
||||
? usedWellPaths.size()
|
||||
? allWellPathLaterals.size()
|
||||
: exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL_AND_COMPLETION_TYPE
|
||||
? usedWellPaths.size() * 3
|
||||
? allWellPathLaterals.size() * 3
|
||||
: 1 ) +
|
||||
simWells.size();
|
||||
|
||||
@ -176,7 +180,7 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions( const std::v
|
||||
|
||||
std::vector<RigCompletionData> completions;
|
||||
|
||||
for ( auto wellPath : usedWellPaths )
|
||||
for ( auto wellPath : allWellPathLaterals )
|
||||
{
|
||||
std::map<size_t, std::vector<RigCompletionData>> completionsPerEclipseCellAllCompletionTypes;
|
||||
std::map<size_t, std::vector<RigCompletionData>> completionsPerEclipseCellFishbones;
|
||||
@ -297,12 +301,12 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions( const std::v
|
||||
}
|
||||
else if ( exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL )
|
||||
{
|
||||
for ( auto wellPath : usedWellPaths )
|
||||
for ( auto wellPath : topLevelWellPaths )
|
||||
{
|
||||
std::vector<RigCompletionData> completionsForWell;
|
||||
for ( const auto& completion : completions )
|
||||
{
|
||||
if ( RicWellPathExportCompletionDataFeatureImpl::isCompletionWellPathEqual( completion, wellPath ) )
|
||||
if ( wellPath == topLevelWellPath( completion ) )
|
||||
{
|
||||
completionsForWell.push_back( completion );
|
||||
}
|
||||
@ -340,15 +344,14 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions( const std::v
|
||||
|
||||
for ( const auto& completionType : completionTypes )
|
||||
{
|
||||
for ( auto wellPath : usedWellPaths )
|
||||
for ( auto wellPath : topLevelWellPaths )
|
||||
{
|
||||
std::vector<RigCompletionData> completionsForWell;
|
||||
for ( const auto& completion : completions )
|
||||
{
|
||||
if ( completionType == completion.completionType() )
|
||||
{
|
||||
if ( RicWellPathExportCompletionDataFeatureImpl::isCompletionWellPathEqual( completion,
|
||||
wellPath ) )
|
||||
if ( wellPath == topLevelWellPath( completion ) )
|
||||
{
|
||||
completionsForWell.push_back( completion );
|
||||
}
|
||||
@ -439,7 +442,7 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions( const std::v
|
||||
|
||||
if ( exportSettings.includeMsw )
|
||||
{
|
||||
RicWellPathExportMswCompletionsImpl::exportWellSegmentsForAllCompletions( exportSettings, wellPaths );
|
||||
RicWellPathExportMswCompletionsImpl::exportWellSegmentsForAllCompletions( exportSettings, topLevelWellPaths );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1746,18 +1749,20 @@ std::pair<double, cvf::Vec2i> RicWellPathExportCompletionDataFeatureImpl::wellPa
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicWellPathExportCompletionDataFeatureImpl::isCompletionWellPathEqual( const RigCompletionData& completion,
|
||||
const RimWellPath* wellPath )
|
||||
RimWellPath* RicWellPathExportCompletionDataFeatureImpl::topLevelWellPath( const RigCompletionData& completion )
|
||||
{
|
||||
if ( !wellPath ) return false;
|
||||
|
||||
RimWellPath* parentWellPath = nullptr;
|
||||
if ( completion.sourcePdmObject() )
|
||||
{
|
||||
completion.sourcePdmObject()->firstAncestorOrThisOfType( parentWellPath );
|
||||
}
|
||||
|
||||
return ( parentWellPath == wellPath );
|
||||
if ( parentWellPath )
|
||||
{
|
||||
return parentWellPath->topLevelWellPath();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -194,5 +194,5 @@ private:
|
||||
|
||||
static void exportCarfinForTemporaryLgrs( const RimEclipseCase* sourceCase, const QString& folder );
|
||||
|
||||
static bool isCompletionWellPathEqual( const RigCompletionData& completion, const RimWellPath* wellPath );
|
||||
static RimWellPath* topLevelWellPath( const RigCompletionData& completion );
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -21,24 +21,21 @@
|
||||
#include "RicMswCompletions.h"
|
||||
#include "RicMswExportInfo.h"
|
||||
#include "RicMswSegment.h"
|
||||
#include "RigCompletionData.h"
|
||||
|
||||
#include <gsl/gsl>
|
||||
|
||||
#include <set>
|
||||
|
||||
class RicExportCompletionDataSettingsUi;
|
||||
class RifTextDataTableFormatter;
|
||||
class RigActiveCellInfo;
|
||||
class RimEclipseCase;
|
||||
class RimFishbones;
|
||||
class RimPerforationInterval;
|
||||
class RimWellPath;
|
||||
class RimWellPathValve;
|
||||
class RimWellPathFracture;
|
||||
class RimMswCompletionParameters;
|
||||
class SubSegmentIntersectionInfo;
|
||||
class RigWellPath;
|
||||
class RimModeledWellPath;
|
||||
|
||||
struct WellPathCellIntersectionInfo;
|
||||
|
||||
@ -47,23 +44,6 @@ class QFile;
|
||||
class RicWellPathExportMswCompletionsImpl
|
||||
{
|
||||
private:
|
||||
class CvfVec3stComparator
|
||||
{
|
||||
public:
|
||||
bool operator()( const cvf::Vec3st& lhs, const cvf::Vec3st& rhs ) const
|
||||
{
|
||||
if ( lhs.z() == rhs.z() )
|
||||
{
|
||||
if ( lhs.y() == rhs.y() )
|
||||
{
|
||||
return lhs.x() < rhs.x();
|
||||
}
|
||||
return lhs.y() < rhs.y();
|
||||
}
|
||||
return lhs.z() < rhs.z();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
static void exportWellSegmentsForAllCompletions( const RicExportCompletionDataSettingsUi& exportSettings,
|
||||
const std::vector<RimWellPath*>& wellPaths );
|
||||
@ -71,20 +51,29 @@ public:
|
||||
static void exportWellSegmentsForFractures( RimEclipseCase* eclipseCase,
|
||||
std::shared_ptr<QFile> exportFile,
|
||||
const RimWellPath* wellPath,
|
||||
bool exportDataSourceAsComment );
|
||||
bool exportDataSourceAsComment,
|
||||
bool completionSegmentsAfterMainBore );
|
||||
|
||||
static void exportWellSegmentsForFishbones( RimEclipseCase* eclipseCase,
|
||||
std::shared_ptr<QFile> exportFile,
|
||||
const RimWellPath* wellPath,
|
||||
bool exportDataSourceAsComment );
|
||||
bool exportDataSourceAsComment,
|
||||
bool completionSegmentsAfterMainBore );
|
||||
|
||||
static void exportWellSegmentsForPerforations( RimEclipseCase* eclipseCase,
|
||||
std::shared_ptr<QFile> exportFile,
|
||||
const RimWellPath* wellPath,
|
||||
int timeStep,
|
||||
bool exportDataSourceAsComment );
|
||||
bool exportDataSourceAsComment,
|
||||
bool completionSegmentsAfterMainBore );
|
||||
|
||||
static void generateFishbonesMswExportInfo( const RimEclipseCase* caseToApply,
|
||||
static void generateFishbonesMswExportInfoForWell( const RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
gsl::not_null<RicMswExportInfo*> exportInfo,
|
||||
gsl::not_null<RicMswBranch*> branch );
|
||||
|
||||
private:
|
||||
static void generateFishbonesMswExportInfo( const RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
double initialMD,
|
||||
const std::vector<WellPathCellIntersectionInfo>& cellIntersections,
|
||||
@ -92,8 +81,7 @@ public:
|
||||
gsl::not_null<RicMswExportInfo*> exportInfo,
|
||||
gsl::not_null<RicMswBranch*> branch );
|
||||
|
||||
private:
|
||||
static void generateFishbonesMswExportInfo( const RimEclipseCase* caseToApply,
|
||||
static void generateFishbonesMswExportInfo( const RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
double initialMD,
|
||||
const std::vector<WellPathCellIntersectionInfo>& cellIntersections,
|
||||
@ -102,11 +90,12 @@ private:
|
||||
gsl::not_null<RicMswExportInfo*> exportInfo,
|
||||
gsl::not_null<RicMswBranch*> branch );
|
||||
|
||||
static RicMswExportInfo generateFracturesMswExportInfo( RimEclipseCase* caseToApply, const RimWellPath* wellPath );
|
||||
|
||||
static RicMswExportInfo generateFracturesMswExportInfo( RimEclipseCase* caseToApply,
|
||||
const RimWellPath* wellPath,
|
||||
const std::vector<RimWellPathFracture*>& fractures );
|
||||
static bool generateFracturesMswExportInfo( RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
double initialMD,
|
||||
const std::vector<WellPathCellIntersectionInfo>& cellIntersections,
|
||||
gsl::not_null<RicMswExportInfo*> exportInfo,
|
||||
gsl::not_null<RicMswBranch*> branch );
|
||||
|
||||
static bool generatePerforationsMswExportInfo( RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
@ -127,64 +116,12 @@ private:
|
||||
gsl::not_null<const RigWellPath*> wellPathGeometry,
|
||||
gsl::not_null<const RimEclipseCase*> eclipseCase );
|
||||
|
||||
static void generateWelsegsTable( RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength );
|
||||
|
||||
static void writeWelsegsSegmentsRecursively( RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
gsl::not_null<RicMswBranch*> branch,
|
||||
gsl::not_null<int*> segmentNumber,
|
||||
double maxSegmentLength,
|
||||
RicMswSegment* connectedToSegment = nullptr );
|
||||
|
||||
static void writeWelsegsSegment( RicMswSegment* segment,
|
||||
const RicMswSegment* previousSegment,
|
||||
RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
gsl::not_null<RicMswBranch*> branch,
|
||||
int* segmentNumber );
|
||||
static void writeValveWelsegsSegment( const RicMswSegment* outletSegment,
|
||||
RicMswValve* valve,
|
||||
RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
int* segmentNumber );
|
||||
static void writeCompletionWelsegsSegments( gsl::not_null<const RicMswSegment*> outletSegment,
|
||||
gsl::not_null<const RicMswCompletion*> completion,
|
||||
RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
double maxSegmentLength,
|
||||
int* segmentNumber );
|
||||
|
||||
static void writeWelsegsCompletionCommentHeader( RifTextDataTableFormatter& formatter,
|
||||
RigCompletionData::CompletionType completionType );
|
||||
static void generateCompsegTables( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo );
|
||||
static void generateCompsegTable( RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
gsl::not_null<const RicMswBranch*> branch,
|
||||
bool exportSubGridIntersections,
|
||||
const std::set<RigCompletionData::CompletionType>& exportCompletionTypes,
|
||||
gsl::not_null<bool*> headerGenerated,
|
||||
gsl::not_null<std::set<cvf::Vec3st, CvfVec3stComparator>*> intersectedCells );
|
||||
static void generateCompsegHeader( RifTextDataTableFormatter& formatter,
|
||||
RicMswExportInfo& exportInfo,
|
||||
RigCompletionData::CompletionType completionType,
|
||||
bool exportSubGridIntersections );
|
||||
static void generateWsegvalvTable( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo );
|
||||
static void generateWsegAicdTable( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo );
|
||||
|
||||
static std::pair<double, double>
|
||||
calculateOverlapWithActiveCells( double startMD,
|
||||
double endMD,
|
||||
const std::vector<WellPathCellIntersectionInfo>& wellPathIntersections,
|
||||
const RigActiveCellInfo* activeCellInfo );
|
||||
|
||||
private:
|
||||
static std::vector<std::pair<double, double>>
|
||||
createSubSegmentMDPairs( double startMD, double endMD, double maxSegmentLength );
|
||||
|
||||
static void createWellPathSegments( gsl::not_null<RicMswBranch*> branch,
|
||||
const std::vector<WellPathCellIntersectionInfo>& cellSegmentIntersections,
|
||||
const std::vector<const RimPerforationInterval*>& perforationIntervals,
|
||||
@ -211,14 +148,15 @@ private:
|
||||
|
||||
static void moveIntersectionsToSuperICDsOrAICDs( gsl::not_null<RicMswBranch*> branch );
|
||||
|
||||
static void assignFishbonesLateralIntersections( const RimEclipseCase* caseToApply,
|
||||
static void assignFishbonesLateralIntersections( const RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
const RimFishbones* fishbonesSubs,
|
||||
gsl::not_null<RicMswSegment*> segment,
|
||||
bool* foundSubGridIntersections,
|
||||
double maxSegmentLength );
|
||||
double maxSegmentLength,
|
||||
RiaDefines::EclipseUnitSystem unitSystem );
|
||||
|
||||
static void assignFractureCompletionsToCellSegment( const RimEclipseCase* caseToApply,
|
||||
static void assignFractureCompletionsToCellSegment( const RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
const RimWellPathFracture* fracture,
|
||||
const std::vector<RigCompletionData>& completionData,
|
||||
@ -238,17 +176,19 @@ private:
|
||||
double overlapEnd,
|
||||
bool* foundSubGridIntersections );
|
||||
|
||||
static void assignBranchNumbersToPerforations( const RimEclipseCase* caseToApply,
|
||||
static void assignBranchNumbersToPerforations( const RimEclipseCase* eclipseCase,
|
||||
gsl::not_null<RicMswSegment*> segment,
|
||||
gsl::not_null<int*> branchNumber );
|
||||
static void assignBranchNumbersToOtherCompletions( const RimEclipseCase* caseToApply,
|
||||
static void assignBranchNumbersToOtherCompletions( const RimEclipseCase* eclipseCase,
|
||||
gsl::not_null<RicMswSegment*> segment,
|
||||
gsl::not_null<int*> branchNumber );
|
||||
|
||||
static void assignBranchNumbersToBranch( const RimEclipseCase* caseToApply,
|
||||
static void assignBranchNumbersToBranch( const RimEclipseCase* eclipseCase,
|
||||
RicMswExportInfo* exportInfo,
|
||||
gsl::not_null<RicMswBranch*> branch,
|
||||
gsl::not_null<int*> branchNumber );
|
||||
|
||||
static double tvdFromMeasuredDepth( gsl::not_null<const RimWellPath*> wellPath, double measuredDepth );
|
||||
static std::unique_ptr<RicMswBranch> createChildMswBranch( const RimModeledWellPath* childWellPath );
|
||||
|
||||
static std::vector<RimModeledWellPath*> wellPathsWithTieIn( const RimWellPath* wellPath );
|
||||
};
|
||||
|
@ -143,7 +143,8 @@ void RicEclipseCellResultToFileImpl::writeDataToTextFile( QFile*
|
||||
textstream << "\n";
|
||||
textstream << "-- Exported from ResInsight"
|
||||
<< "\n";
|
||||
textstream << eclipseKeyword << "\n" << right << qSetFieldWidth( 16 );
|
||||
textstream << eclipseKeyword << "\n" << qSetFieldWidth( 16 );
|
||||
textstream.setFieldAlignment( QTextStream::AlignRight );
|
||||
|
||||
caf::ProgressInfo pi( resultData.size(), QString( "Writing data to file %1" ).arg( file->fileName() ) );
|
||||
size_t progressSteps = resultData.size() / 20;
|
||||
|
@ -15,6 +15,7 @@
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RicNewWellPathLateralAtDepthFeature.h"
|
||||
|
||||
#include "WellPathCommands/RicWellPathsUnitSystemSettingsImpl.h"
|
||||
@ -23,12 +24,11 @@
|
||||
#include "RimFishbones.h"
|
||||
#include "RimFishbonesCollection.h"
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimTools.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPathGeometryDef.h"
|
||||
#include "RimWellPathGroup.h"
|
||||
#include "RimWellPathTarget.h"
|
||||
|
||||
#include "Riu3DMainWindowTools.h"
|
||||
@ -38,6 +38,7 @@
|
||||
|
||||
#include <QAction>
|
||||
|
||||
#include "RiaTextStringTools.h"
|
||||
#include <cmath>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicNewWellPathLateralAtDepthFeature, "RicNewWellPathLateralAtDepthFeature" );
|
||||
@ -63,56 +64,44 @@ void RicNewWellPathLateralAtDepthFeature::onActionTriggered( bool isChecked )
|
||||
RiuWellPathSelectionItem* wellPathSelItem = wellPathSelectionItem();
|
||||
CVF_ASSERT( wellPathSelItem );
|
||||
|
||||
RimWellPath* wellPath = wellPathSelItem->m_wellpath;
|
||||
CVF_ASSERT( wellPath );
|
||||
RimWellPathGroup* wellPathGroup = nullptr;
|
||||
wellPath->firstAncestorOrThisOfType( wellPathGroup );
|
||||
RimWellPath* parentWellPath = wellPathSelItem->m_wellpath;
|
||||
CVF_ASSERT( parentWellPath );
|
||||
|
||||
RimProject* project = RimProject::current();
|
||||
if ( project && RimProject::current()->activeOilField() )
|
||||
RimProject* project = RimProject::current();
|
||||
RimWellPathCollection* wellPathColl = RimTools::wellPathCollection();
|
||||
if ( project && wellPathColl )
|
||||
{
|
||||
RimWellPathCollection* wellPathCollection = RimProject::current()->activeOilField()->wellPathCollection();
|
||||
double parentWellMD = wellPathSelItem->m_measuredDepth;
|
||||
|
||||
if ( wellPathCollection )
|
||||
{
|
||||
auto newModeledWellPath = new RimModeledWellPath();
|
||||
auto newModeledWellPath = new RimModeledWellPath();
|
||||
|
||||
auto [pointVector, measuredDepths] =
|
||||
wellPath->wellPathGeometry()->clippedPointSubset( wellPath->wellPathGeometry()->measuredDepths().front(),
|
||||
wellPathSelItem->m_measuredDepth );
|
||||
if ( pointVector.size() < 2u ) return;
|
||||
newModeledWellPath->geometryDefinition()->setMdAtFirstTarget( measuredDepths.back() );
|
||||
newModeledWellPath->geometryDefinition()->setUseAutoGeneratedTargetAtSeaLevel( false );
|
||||
newModeledWellPath->geometryDefinition()->setFixedWellPathPoints( pointVector );
|
||||
newModeledWellPath->geometryDefinition()->setFixedMeasuredDepths( measuredDepths );
|
||||
newModeledWellPath->setName( wellPath->name() + QString( " md=%1" ).arg( wellPathSelItem->m_measuredDepth ) );
|
||||
auto [pointVector, measuredDepths] =
|
||||
parentWellPath->wellPathGeometry()
|
||||
->clippedPointSubset( parentWellPath->wellPathGeometry()->measuredDepths().front(), parentWellMD );
|
||||
if ( pointVector.size() < 2u ) return;
|
||||
|
||||
{
|
||||
RimWellPathTarget* newTarget = newModeledWellPath->geometryDefinition()->appendTarget();
|
||||
auto lastPoint = pointVector.back();
|
||||
auto tangent = lastPoint - pointVector[pointVector.size() - 2];
|
||||
newTarget->setAsPointXYZAndTangentTarget( { lastPoint[0], lastPoint[1], lastPoint[2] }, tangent );
|
||||
}
|
||||
newModeledWellPath->geometryDefinition()->setIsAttachedToParentWell( true );
|
||||
newModeledWellPath->geometryDefinition()->setMdAtFirstTarget( measuredDepths.back() );
|
||||
newModeledWellPath->geometryDefinition()->setUseAutoGeneratedTargetAtSeaLevel( false );
|
||||
newModeledWellPath->geometryDefinition()->setFixedWellPathPoints( pointVector );
|
||||
newModeledWellPath->geometryDefinition()->setFixedMeasuredDepths( measuredDepths );
|
||||
|
||||
newModeledWellPath->geometryDefinition()->enableTargetPointPicking( true );
|
||||
auto nameOfNewWell = updateNameOfParentAndFindNameOfSideStep( parentWellPath );
|
||||
newModeledWellPath->setName( nameOfNewWell );
|
||||
newModeledWellPath->connectWellPaths( parentWellPath, parentWellMD );
|
||||
|
||||
newModeledWellPath->createWellPathGeometry();
|
||||
if ( wellPathGroup )
|
||||
{
|
||||
wellPathGroup->addChildWellPath( newModeledWellPath );
|
||||
}
|
||||
else
|
||||
{
|
||||
bool importedWellPath = false;
|
||||
wellPathCollection->addWellPath( newModeledWellPath, importedWellPath );
|
||||
wellPathCollection->groupWellPaths( { wellPath, newModeledWellPath } );
|
||||
}
|
||||
newModeledWellPath->firstAncestorOrThisOfTypeAsserted( wellPathGroup );
|
||||
wellPathGroup->updateAllRequiredEditors();
|
||||
project->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
newModeledWellPath->geometryDefinition()->enableTargetPointPicking( true );
|
||||
newModeledWellPath->setUnitSystem( parentWellPath->unitSystem() );
|
||||
|
||||
Riu3DMainWindowTools::selectAsCurrentItem( newModeledWellPath->geometryDefinition() );
|
||||
}
|
||||
newModeledWellPath->createWellPathGeometry();
|
||||
|
||||
bool importGrouped = false;
|
||||
wellPathColl->addWellPath( newModeledWellPath, importGrouped );
|
||||
wellPathColl->updateAllRequiredEditors();
|
||||
|
||||
project->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
|
||||
Riu3DMainWindowTools::selectAsCurrentItem( newModeledWellPath->geometryDefinition() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,3 +126,76 @@ RiuWellPathSelectionItem* RicNewWellPathLateralAtDepthFeature::wellPathSelection
|
||||
|
||||
return wellPathItem;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RicNewWellPathLateralAtDepthFeature::updateNameOfParentAndFindNameOfSideStep( RimWellPath* parentwWellPath )
|
||||
{
|
||||
if ( !parentwWellPath ) return "";
|
||||
|
||||
QString nameOfNewWell;
|
||||
|
||||
auto topLevelWell = parentwWellPath->topLevelWellPath();
|
||||
|
||||
QStringList allNames;
|
||||
{
|
||||
RimProject* proj = RimProject::current();
|
||||
const std::vector<RimWellPath*>& wellPaths = proj->allWellPaths();
|
||||
|
||||
for ( auto wellPath : wellPaths )
|
||||
{
|
||||
if ( wellPath )
|
||||
{
|
||||
auto currentTopLevelWell = wellPath->topLevelWellPath();
|
||||
if ( topLevelWell == currentTopLevelWell )
|
||||
{
|
||||
allNames.push_back( wellPath->name() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( allNames.size() == 1 )
|
||||
{
|
||||
QString name = parentwWellPath->name();
|
||||
|
||||
if ( name.contains( "Y1" ) )
|
||||
{
|
||||
nameOfNewWell = name.replace( "Y1", "Y2" );
|
||||
}
|
||||
else
|
||||
{
|
||||
parentwWellPath->setNameNoUpdateOfExportName( name + " Y1" );
|
||||
nameOfNewWell = name + " Y2";
|
||||
}
|
||||
|
||||
return nameOfNewWell;
|
||||
}
|
||||
|
||||
{
|
||||
QString commonRoot = RiaTextStringTools::commonRoot( allNames );
|
||||
QString trimmedCommonRoot = RiaTextStringTools::trimNonAlphaNumericCharacters( commonRoot );
|
||||
|
||||
// Remove side step prefix
|
||||
trimmedCommonRoot.replace( " Y", "" );
|
||||
|
||||
int maxYValue = 0;
|
||||
for ( auto n : allNames )
|
||||
{
|
||||
auto suffix = n.replace( trimmedCommonRoot, "" );
|
||||
|
||||
int candidate = suffix.toInt();
|
||||
maxYValue = std::max( maxYValue, candidate );
|
||||
}
|
||||
|
||||
if ( !trimmedCommonRoot.isEmpty() && trimmedCommonRoot.endsWith( "Y" ) )
|
||||
{
|
||||
trimmedCommonRoot = trimmedCommonRoot.left( trimmedCommonRoot.size() - 1 ).trimmed();
|
||||
}
|
||||
|
||||
nameOfNewWell = QString( "%1 Y%2" ).arg( trimmedCommonRoot ).arg( maxYValue + 1 );
|
||||
}
|
||||
|
||||
return nameOfNewWell;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "cafCmdFeature.h"
|
||||
|
||||
class RiuWellPathSelectionItem;
|
||||
class RimWellPath;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -37,4 +38,5 @@ protected:
|
||||
|
||||
private:
|
||||
static RiuWellPathSelectionItem* wellPathSelectionItem();
|
||||
QString updateNameOfParentAndFindNameOfSideStep( RimWellPath* parentwWellPath );
|
||||
};
|
||||
|
@ -562,12 +562,12 @@ void RifEclipseInputFileTools::saveFault( QString
|
||||
}
|
||||
|
||||
QTextStream stream( &exportFile );
|
||||
stream << "FAULTS" << endl;
|
||||
stream << "FAULTS" << '\n';
|
||||
|
||||
stream << "-- Name I1 I2 J1 J2 K1 K2 Face ( I/J/K )" << endl;
|
||||
stream << "-- Name I1 I2 J1 J2 K1 K2 Face ( I/J/K )" << '\n';
|
||||
|
||||
saveFault( stream, mainGrid, faultFaces, faultName, min, maxIn, refinement );
|
||||
stream << "/" << endl;
|
||||
stream << "/" << '\n';
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -744,9 +744,9 @@ void RifEclipseInputFileTools::saveFaults( QTextStream& stream,
|
||||
const cvf::Vec3st& max /*= cvf::Vec3st::UNDEFINED*/,
|
||||
const cvf::Vec3st& refinement /*= cvf::Vec3st(1, 1, 1)*/ )
|
||||
{
|
||||
stream << "FAULTS" << endl;
|
||||
stream << "FAULTS" << '\n';
|
||||
|
||||
stream << "-- Name I1 I2 J1 J2 K1 K2 Face ( I/J/K )" << endl;
|
||||
stream << "-- Name I1 I2 J1 J2 K1 K2 Face ( I/J/K )" << '\n';
|
||||
|
||||
const cvf::Collection<RigFault>& faults = mainGrid->faults();
|
||||
for ( const auto& fault : faults )
|
||||
@ -757,7 +757,7 @@ void RifEclipseInputFileTools::saveFaults( QTextStream& stream,
|
||||
saveFault( stream, mainGrid, fault->faultFaces(), fault->name(), min, max, refinement );
|
||||
}
|
||||
}
|
||||
stream << "/" << endl;
|
||||
stream << "/" << '\n';
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1319,7 +1319,7 @@ void RifEclipseInputFileTools::writeFaultLine( QTextStream&
|
||||
stream << "'" << faultName << "'"
|
||||
<< " " << i << " " << i << " " << j << " " << j << " " << startK << " " << endK << " "
|
||||
<< faultFaceText( faceType ) << " / ";
|
||||
stream << endl;
|
||||
stream << '\n';
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -62,7 +62,7 @@ bool RifStimPlanModelAsymmetricFrkExporter::writeToFile( RimStimPlanModel* stimP
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifStimPlanModelAsymmetricFrkExporter::appendHeaderToStream( QTextStream& stream )
|
||||
{
|
||||
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl << "<asymmetric>" << endl;
|
||||
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << '\n' << "<asymmetric>" << '\n';
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -75,21 +75,21 @@ void RifStimPlanModelAsymmetricFrkExporter::appendBarrierDataToStream( QTextStre
|
||||
double barrierDipDeg,
|
||||
int wellPenetrationLayer )
|
||||
{
|
||||
stream << "<BedDipDeg>" << endl
|
||||
<< bedDipDeg << endl
|
||||
<< "</BedDipDeg>" << endl
|
||||
<< "<Barrier>" << endl
|
||||
<< static_cast<int>( hasBarrier ) << endl
|
||||
<< "</Barrier>" << endl
|
||||
<< "<BarrierDipDeg>" << endl
|
||||
<< barrierDipDeg << endl
|
||||
<< "</BarrierDipDeg>" << endl
|
||||
<< "<DistanceToBarrier>" << endl
|
||||
<< distanceToBarrier << endl
|
||||
<< "</DistanceToBarrier>" << endl
|
||||
<< "<WellPenetrationLayer>" << endl
|
||||
<< wellPenetrationLayer << endl
|
||||
<< "</WellPenetrationLayer>" << endl;
|
||||
stream << "<BedDipDeg>" << '\n'
|
||||
<< bedDipDeg << '\n'
|
||||
<< "</BedDipDeg>" << '\n'
|
||||
<< "<Barrier>" << '\n'
|
||||
<< static_cast<int>( hasBarrier ) << '\n'
|
||||
<< "</Barrier>" << '\n'
|
||||
<< "<BarrierDipDeg>" << '\n'
|
||||
<< barrierDipDeg << '\n'
|
||||
<< "</BarrierDipDeg>" << '\n'
|
||||
<< "<DistanceToBarrier>" << '\n'
|
||||
<< distanceToBarrier << '\n'
|
||||
<< "</DistanceToBarrier>" << '\n'
|
||||
<< "<WellPenetrationLayer>" << '\n'
|
||||
<< wellPenetrationLayer << '\n'
|
||||
<< "</WellPenetrationLayer>" << '\n';
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -97,5 +97,5 @@ void RifStimPlanModelAsymmetricFrkExporter::appendBarrierDataToStream( QTextStre
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifStimPlanModelAsymmetricFrkExporter::appendFooterToStream( QTextStream& stream )
|
||||
{
|
||||
stream << "</asymmetric>" << endl;
|
||||
stream << "</asymmetric>" << '\n';
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ bool RifStimPlanModelDeviationFrkExporter::writeToFile( RimStimPlanModel* stimPl
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifStimPlanModelDeviationFrkExporter::appendHeaderToStream( QTextStream& stream )
|
||||
{
|
||||
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl << "<deviation>" << endl;
|
||||
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << '\n' << "<deviation>" << '\n';
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -86,23 +86,23 @@ void RifStimPlanModelDeviationFrkExporter::appendToStream( QTextStream&
|
||||
const std::vector<double>& values )
|
||||
{
|
||||
stream.setRealNumberPrecision( 20 );
|
||||
stream << "<cNamedSet>" << endl
|
||||
<< "<name>" << endl
|
||||
<< label << endl
|
||||
<< "</name>" << endl
|
||||
<< "<dimCount>" << endl
|
||||
<< 1 << endl
|
||||
<< "</dimCount>" << endl
|
||||
<< "<sizes>" << endl
|
||||
<< values.size() << endl
|
||||
<< "</sizes>" << endl
|
||||
<< "<data>" << endl;
|
||||
stream << "<cNamedSet>" << '\n'
|
||||
<< "<name>" << '\n'
|
||||
<< label << '\n'
|
||||
<< "</name>" << '\n'
|
||||
<< "<dimCount>" << '\n'
|
||||
<< 1 << '\n'
|
||||
<< "</dimCount>" << '\n'
|
||||
<< "<sizes>" << '\n'
|
||||
<< values.size() << '\n'
|
||||
<< "</sizes>" << '\n'
|
||||
<< "<data>" << '\n';
|
||||
for ( auto val : values )
|
||||
{
|
||||
stream << val << endl;
|
||||
stream << val << '\n';
|
||||
}
|
||||
|
||||
stream << "</data>" << endl << "</cNamedSet>" << endl;
|
||||
stream << "</data>" << '\n' << "</cNamedSet>" << '\n';
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -110,7 +110,7 @@ void RifStimPlanModelDeviationFrkExporter::appendToStream( QTextStream&
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifStimPlanModelDeviationFrkExporter::appendFooterToStream( QTextStream& stream )
|
||||
{
|
||||
stream << "</deviation>" << endl;
|
||||
stream << "</deviation>" << '\n';
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -234,7 +234,7 @@ bool RifStimPlanModelGeologicalFrkExporter::writeToCsvFile( const QString&
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifStimPlanModelGeologicalFrkExporter::appendHeaderToStream( QTextStream& stream )
|
||||
{
|
||||
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl << "<geologic>" << endl;
|
||||
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << '\n' << "<geologic>" << endl;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -260,7 +260,7 @@ void RifStimPlanModelGeologicalFrkExporter::appendToStream( QTextStream&
|
||||
stream << val << endl;
|
||||
}
|
||||
|
||||
stream << "</data>" << endl << "</cNamedSet>" << endl;
|
||||
stream << "</data>" << '\n' << "</cNamedSet>" << endl;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -80,7 +80,7 @@ bool RifStimPlanModelPerfsFrkExporter::writeToFile( RimStimPlanModel* stimPlanMo
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifStimPlanModelPerfsFrkExporter::appendHeaderToStream( QTextStream& stream )
|
||||
{
|
||||
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl << "<perfs>" << endl;
|
||||
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << '\n' << "<perfs>" << endl;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -88,7 +88,7 @@ void RifStimPlanModelPerfsFrkExporter::appendHeaderToStream( QTextStream& stream
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifStimPlanModelPerfsFrkExporter::appendFractureOrientationToStream( QTextStream& stream, bool isTransverse )
|
||||
{
|
||||
stream << "<transverse>" << endl << static_cast<int>( isTransverse ) << endl << "</transverse>" << endl;
|
||||
stream << "<transverse>" << '\n' << static_cast<int>( isTransverse ) << '\n' << "</transverse>" << endl;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -32,8 +32,7 @@
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimFishbones.h"
|
||||
#include "RimFishbonesCollection.h"
|
||||
#include "RimImportedFishboneLaterals.h"
|
||||
#include "RimImportedFishboneLateralsCollection.h"
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimPerforationCollection.h"
|
||||
#include "RimPerforationInterval.h"
|
||||
#include "RimRegularLegendConfig.h"
|
||||
@ -49,6 +48,8 @@
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPathFracture.h"
|
||||
#include "RimWellPathFractureCollection.h"
|
||||
#include "RimWellPathGeometryDef.h"
|
||||
#include "RimWellPathTarget.h"
|
||||
#include "RimWellPathValve.h"
|
||||
|
||||
#include "Riv3dWellLogPlanePartMgr.h"
|
||||
@ -67,12 +68,18 @@
|
||||
|
||||
#include "cafDisplayCoordTransform.h"
|
||||
#include "cafEffectGenerator.h"
|
||||
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfDrawableText.h"
|
||||
#include "cvfDrawableVectors.h"
|
||||
#include "cvfFont.h"
|
||||
#include "cvfGeometryBuilderTriangles.h"
|
||||
#include "cvfGeometryUtils.h"
|
||||
#include "cvfModelBasicList.h"
|
||||
#include "cvfOpenGLResourceManager.h"
|
||||
#include "cvfPart.h"
|
||||
#include "cvfScalarMapperContinuousLinear.h"
|
||||
#include "cvfShaderProgram.h"
|
||||
#include "cvfTransform.h"
|
||||
#include "cvfqtUtils.h"
|
||||
|
||||
@ -362,40 +369,6 @@ void RivWellPathPartMgr::appendWellMeasurementsToModel( cvf::ModelBasicList*
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivWellPathPartMgr::appendImportedFishbonesToModel( cvf::ModelBasicList* model,
|
||||
const caf::DisplayCoordTransform* displayCoordTransform,
|
||||
double characteristicCellSize )
|
||||
{
|
||||
if ( !m_rimWellPath || !m_rimWellPath->fishbonesCollection()->wellPathCollection()->isChecked() ) return;
|
||||
|
||||
RivPipeGeometryGenerator geoGenerator;
|
||||
std::vector<RimImportedFishboneLaterals*> fishbonesWellPaths;
|
||||
m_rimWellPath->descendantsIncludingThisOfType( fishbonesWellPaths );
|
||||
for ( RimImportedFishboneLaterals* fbWellPath : fishbonesWellPaths )
|
||||
{
|
||||
if ( !fbWellPath->isChecked() ) continue;
|
||||
|
||||
std::vector<cvf::Vec3d> displayCoords =
|
||||
displayCoordTransform->transformToDisplayCoords( fbWellPath->coordinates() );
|
||||
|
||||
cvf::ref<RivObjectSourceInfo> objectSourceInfo = new RivObjectSourceInfo( fbWellPath );
|
||||
|
||||
cvf::Collection<cvf::Part> parts;
|
||||
geoGenerator.cylinderWithCenterLineParts( &parts,
|
||||
displayCoords,
|
||||
m_rimWellPath->wellPathColor(),
|
||||
m_rimWellPath->combinedScaleFactor() * characteristicCellSize * 0.5 );
|
||||
for ( auto part : parts )
|
||||
{
|
||||
part->setSourceInfo( objectSourceInfo.p() );
|
||||
model->addPart( part.p() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -783,6 +756,73 @@ void RivWellPathPartMgr::buildWellPathParts( const caf::DisplayCoordTransform* d
|
||||
|
||||
m_wellLabelPart = part;
|
||||
}
|
||||
|
||||
auto modeledWellPath = dynamic_cast<RimModeledWellPath*>( m_rimWellPath.p() );
|
||||
if ( modeledWellPath )
|
||||
{
|
||||
bool showWellTargetSpheres = modeledWellPath->geometryDefinition()->showSpheres();
|
||||
|
||||
if ( showWellTargetSpheres )
|
||||
{
|
||||
auto geoDef = modeledWellPath->geometryDefinition();
|
||||
|
||||
auto sphereColor = geoDef->sphereColor();
|
||||
double sphereRadiusFactor = geoDef->sphereRadiusFactor();
|
||||
|
||||
cvf::ref<cvf::Vec3fArray> vertices = new cvf::Vec3fArray;
|
||||
cvf::ref<cvf::Vec3fArray> vecRes = new cvf::Vec3fArray;
|
||||
cvf::ref<cvf::Color3fArray> colors = new cvf::Color3fArray;
|
||||
|
||||
auto wellTargets = geoDef->activeWellTargets();
|
||||
|
||||
size_t pointCount = wellTargets.size();
|
||||
vertices->reserve( pointCount );
|
||||
vecRes->reserve( pointCount );
|
||||
colors->reserve( pointCount );
|
||||
|
||||
for ( const auto target : wellTargets )
|
||||
{
|
||||
auto domainCoord = target->targetPointXYZ() + modeledWellPath->geometryDefinition()->anchorPointXyz();
|
||||
auto displayCoord = displayCoordTransform->transformToDisplayCoord( domainCoord );
|
||||
vertices->add( cvf::Vec3f( displayCoord ) );
|
||||
vecRes->add( cvf::Vec3f::X_AXIS );
|
||||
colors->add( sphereColor );
|
||||
}
|
||||
|
||||
cvf::ref<cvf::DrawableVectors> vectorDrawable;
|
||||
if ( RiaGuiApplication::instance()->useShaders() )
|
||||
{
|
||||
vectorDrawable = new cvf::DrawableVectors( "u_transformationMatrix", "u_color" );
|
||||
}
|
||||
else
|
||||
{
|
||||
vectorDrawable = new cvf::DrawableVectors();
|
||||
}
|
||||
|
||||
vectorDrawable->setVectors( vertices.p(), vecRes.p() );
|
||||
vectorDrawable->setColors( colors.p() );
|
||||
|
||||
double cellRadius = 15.0;
|
||||
auto eclipseView = dynamic_cast<RimEclipseView*>( m_rimView.p() );
|
||||
if ( eclipseView )
|
||||
{
|
||||
double characteristicCellSize = eclipseView->mainGrid()->characteristicIJCellSize();
|
||||
cellRadius = sphereRadiusFactor * characteristicCellSize;
|
||||
}
|
||||
|
||||
cvf::GeometryBuilderTriangles builder;
|
||||
cvf::GeometryUtils::createSphere( cellRadius, 15, 15, &builder );
|
||||
vectorDrawable->setGlyph( builder.trianglesUShort().p(), builder.vertices().p() );
|
||||
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setName( "RivWellPathPartMgr_WellTargetSpheres" );
|
||||
part->setDrawable( vectorDrawable.p() );
|
||||
|
||||
part->setEffect( new cvf::Effect() );
|
||||
|
||||
m_spherePart = part;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -813,8 +853,12 @@ void RivWellPathPartMgr::appendStaticGeometryPartsToModel( cvf::ModelBasicList*
|
||||
model->addPart( m_wellLabelPart.p() );
|
||||
}
|
||||
|
||||
if ( m_spherePart.notNull() )
|
||||
{
|
||||
model->addPart( m_spherePart.p() );
|
||||
}
|
||||
|
||||
appendFishboneSubsPartsToModel( model, displayCoordTransform, characteristicCellSize );
|
||||
appendImportedFishbonesToModel( model, displayCoordTransform, characteristicCellSize );
|
||||
appendWellPathAttributesToModel( model, displayCoordTransform, characteristicCellSize );
|
||||
|
||||
RimGridView* gridView = dynamic_cast<RimGridView*>( m_rimView.p() );
|
||||
@ -852,6 +896,11 @@ void RivWellPathPartMgr::appendFlattenedStaticGeometryPartsToModel( cvf::ModelBa
|
||||
{
|
||||
model->addPart( m_wellLabelPart.p() );
|
||||
}
|
||||
|
||||
if ( m_spherePart.notNull() )
|
||||
{
|
||||
model->addPart( m_spherePart.p() );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -923,6 +972,7 @@ void RivWellPathPartMgr::clearAllBranchData()
|
||||
m_centerLinePart = nullptr;
|
||||
m_centerLineDrawable = nullptr;
|
||||
m_wellLabelPart = nullptr;
|
||||
m_spherePart = nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -98,9 +98,6 @@ private:
|
||||
const caf::DisplayCoordTransform* displayCoordTransform,
|
||||
double characteristicCellSize );
|
||||
|
||||
void appendImportedFishbonesToModel( cvf::ModelBasicList* model,
|
||||
const caf::DisplayCoordTransform* displayCoordTransform,
|
||||
double characteristicCellSize );
|
||||
|
||||
void appendPerforationsToModel( cvf::ModelBasicList* model,
|
||||
size_t timeStepIndex,
|
||||
@ -147,6 +144,7 @@ private:
|
||||
cvf::ref<cvf::Part> m_centerLinePart;
|
||||
cvf::ref<cvf::DrawableGeo> m_centerLineDrawable;
|
||||
cvf::ref<cvf::Part> m_wellLabelPart;
|
||||
cvf::ref<cvf::Part> m_spherePart;
|
||||
|
||||
cvf::ref<Riv3dWellLogPlanePartMgr> m_3dWellLogPlanePartMgr;
|
||||
cvf::ref<RivWellConnectionFactorPartMgr> m_wellConnectionFactorPartMgr;
|
||||
|
@ -152,6 +152,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimCustomObjectiveFunctionWeight.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEquilibriumAxisAnnotation.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimTimeAxisAnnotation.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimPolylinesDataInterface.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathTieIn.h
|
||||
)
|
||||
|
||||
|
||||
@ -304,6 +305,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimCustomObjectiveFunction.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCustomObjectiveFunctionWeight.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEquilibriumAxisAnnotation.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimTimeAxisAnnotation.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathTieIn.cpp
|
||||
)
|
||||
|
||||
if(Qt5Charts_FOUND)
|
||||
|
@ -42,8 +42,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RimCompletionCellIntersectionCalc.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFishbonesCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFishbones.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFishbonesPipeProperties.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimImportedFishboneLaterals.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimImportedFishboneLateralsCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimPerforationCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimPerforationInterval.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathCompletions.cpp
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "RigFishbonesGeometry.h"
|
||||
#include "RigWellPath.h"
|
||||
#include "RimFishbonesCollection.h"
|
||||
#include "RimFishbonesPipeProperties.h"
|
||||
#include "RimMultipleValveLocations.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPath.h"
|
||||
@ -185,7 +186,7 @@ QString RimFishbones::generatedName() const
|
||||
dynamic_cast<caf::PdmChildArrayField<RimFishbones*>*>( this->parentField() );
|
||||
CVF_ASSERT( container );
|
||||
|
||||
size_t index = container->index( this );
|
||||
size_t index = container->index( this ) + 1;
|
||||
return QString( "Fishbone %1" ).arg( index );
|
||||
}
|
||||
|
||||
@ -278,7 +279,17 @@ double RimFishbones::tubingDiameter( RiaDefines::EclipseUnitSystem unitSystem )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFishbones::effectiveDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const
|
||||
double RimFishbones::holeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const
|
||||
{
|
||||
return m_pipeProperties()->holeDiameter( unitSystem );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Compute the equivalent diameter based on the area between two cylinders
|
||||
//
|
||||
// http://www.fekete.com/san/webhelp/feketeharmony/harmony_webhelp/content/html_files/reference_material/calculations_and_correlations/annular_diameters.htm
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFishbones::equivalentDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const
|
||||
{
|
||||
double innerRadius = tubingDiameter( unitSystem ) / 2;
|
||||
double outerRadius = holeDiameter( unitSystem ) / 2;
|
||||
@ -286,12 +297,20 @@ double RimFishbones::effectiveDiameter( RiaDefines::EclipseUnitSystem unitSystem
|
||||
double innerArea = cvf::PI_D * innerRadius * innerRadius;
|
||||
double outerArea = cvf::PI_D * outerRadius * outerRadius;
|
||||
|
||||
double effectiveArea = outerArea - innerArea;
|
||||
double equivalentArea = outerArea - innerArea;
|
||||
|
||||
double effectiveRadius = cvf::Math::sqrt( effectiveArea / cvf::PI_D );
|
||||
double effectiveRadius = cvf::Math::sqrt( equivalentArea / cvf::PI_D );
|
||||
return effectiveRadius * 2;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFishbones::skinFactor() const
|
||||
{
|
||||
return m_pipeProperties()->skinFactor();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -382,6 +401,14 @@ void RimFishbones::geometryUpdated()
|
||||
proj->reloadCompletionTypeResultsInAllViews();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<RimFishbones::SubAndLateralIndex>& RimFishbones::installedLateralIndices() const
|
||||
{
|
||||
return m_subLateralIndices;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -613,13 +640,13 @@ void RimFishbones::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& u
|
||||
}
|
||||
|
||||
{
|
||||
caf::PdmUiGroup* wellGroup = uiOrdering.addNewGroup( "Well Properties" );
|
||||
caf::PdmUiGroup* wellGroup = uiOrdering.addNewGroup( "Lateral Properties" );
|
||||
|
||||
m_pipeProperties->uiOrdering( uiConfigName, *wellGroup );
|
||||
}
|
||||
|
||||
{
|
||||
caf::PdmUiGroup* mswGroup = uiOrdering.addNewGroup( "Multi Segment Wells" );
|
||||
caf::PdmUiGroup* mswGroup = uiOrdering.addNewGroup( "Lateral Multi Segment Wells" );
|
||||
mswGroup->setCollapsedByDefault( true );
|
||||
mswGroup->add( &m_lateralTubingDiameter );
|
||||
mswGroup->add( &m_lateralOpenHoleRoghnessFactor );
|
||||
|
@ -22,7 +22,6 @@
|
||||
|
||||
#include "Rim3dPropertiesInterface.h"
|
||||
#include "RimCheckableNamedObject.h"
|
||||
#include "RimFishbonesPipeProperties.h"
|
||||
#include "RimWellPathComponentInterface.h"
|
||||
|
||||
#include "cvfColor3.h"
|
||||
@ -37,6 +36,7 @@
|
||||
#include <memory>
|
||||
|
||||
class RigFisbonesGeometry;
|
||||
class RimFishbonesPipeProperties;
|
||||
class RimMultipleValveLocations;
|
||||
|
||||
//==================================================================================================
|
||||
@ -79,13 +79,10 @@ public:
|
||||
double exitAngle() const;
|
||||
double buildAngle() const;
|
||||
|
||||
double tubingDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
double holeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const
|
||||
{
|
||||
return m_pipeProperties()->holeDiameter( unitSystem );
|
||||
}
|
||||
double effectiveDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
double skinFactor() const { return m_pipeProperties()->skinFactor(); }
|
||||
double tubingDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
double holeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
double equivalentDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
double skinFactor() const;
|
||||
double openHoleRoughnessFactor( RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
double icdOrificeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
double icdFlowCoefficient() const;
|
||||
@ -94,7 +91,7 @@ public:
|
||||
|
||||
void geometryUpdated();
|
||||
|
||||
const std::vector<SubAndLateralIndex>& installedLateralIndices() const { return m_subLateralIndices; };
|
||||
const std::vector<SubAndLateralIndex>& installedLateralIndices() const;
|
||||
std::vector<cvf::Vec3d> coordsForLateral( size_t subIndex, size_t lateralIndex ) const;
|
||||
std::vector<std::pair<cvf::Vec3d, double>> coordsAndMDForLateral( size_t subIndex, size_t lateralIndex ) const;
|
||||
void recomputeLateralLocations();
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RimFishbones.h"
|
||||
#include "RimImportedFishboneLateralsCollection.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPath.h"
|
||||
|
||||
@ -50,10 +49,6 @@ RimFishbonesCollection::RimFishbonesCollection()
|
||||
|
||||
m_fishbones.uiCapability()->setUiHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_wellPathCollection, "WellPathCollection", "Imported Laterals", "", "", "" );
|
||||
m_wellPathCollection = new RimImportedFishboneLateralsCollection;
|
||||
m_wellPathCollection.uiCapability()->setUiHidden( true );
|
||||
|
||||
CAF_PDM_InitField( &m_startMD, "StartMD", HUGE_VAL, "Start MD", "", "", "" );
|
||||
CAF_PDM_InitField( &m_mainBoreDiameter, "MainBoreDiameter", 0.216, "Main Bore Diameter", "", "", "" );
|
||||
CAF_PDM_InitField( &m_skinFactor, "MainBoreSkinFactor", 0., "Main Bore Skin Factor [0..1]", "", "", "" );
|
||||
@ -74,16 +69,6 @@ RimFishbonesCollection::RimFishbonesCollection()
|
||||
m_lengthAndDepth_OBSOLETE.xmlCapability()->setIOWritable( false );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimImportedFishboneLateralsCollection* RimFishbonesCollection::wellPathCollection() const
|
||||
{
|
||||
CVF_ASSERT( m_wellPathCollection );
|
||||
|
||||
return m_wellPathCollection();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -268,14 +253,6 @@ void RimFishbonesCollection::recalculateStartMD()
|
||||
}
|
||||
}
|
||||
|
||||
for ( const RimImportedFishboneLaterals* wellPath : m_wellPathCollection->wellPaths() )
|
||||
{
|
||||
if ( wellPath->measuredDepths().size() > 0 )
|
||||
{
|
||||
minStartMD = std::min( minStartMD, wellPath->measuredDepths()[0] - 13.0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !manuallyModifiedStartMD || minStartMD < m_startMD() )
|
||||
{
|
||||
m_startMD = minStartMD;
|
||||
@ -342,7 +319,5 @@ void RimFishbonesCollection::setUnitSystemSpecificDefaults()
|
||||
{
|
||||
m_mainBoreDiameter = 0.708;
|
||||
}
|
||||
|
||||
m_wellPathCollection->setUnitSystemSpecificDefaults();
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "cvfColor3.h"
|
||||
|
||||
class RimFishbones;
|
||||
class RimImportedFishboneLateralsCollection;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
@ -44,9 +43,8 @@ class RimFishbonesCollection : public RimCheckableNamedObject
|
||||
public:
|
||||
RimFishbonesCollection();
|
||||
|
||||
RimImportedFishboneLateralsCollection* wellPathCollection() const;
|
||||
void appendFishbonesSubs( RimFishbones* subs );
|
||||
const RimMswCompletionParameters* mswParameters() const;
|
||||
void appendFishbonesSubs( RimFishbones* subs );
|
||||
const RimMswCompletionParameters* mswParameters() const;
|
||||
|
||||
bool hasFishbones() const;
|
||||
std::vector<RimFishbones*> activeFishbonesSubs() const;
|
||||
@ -68,9 +66,8 @@ private:
|
||||
cvf::Color3f nextFishbonesColor() const;
|
||||
|
||||
private:
|
||||
caf::PdmChildArrayField<RimFishbones*> m_fishbones;
|
||||
caf::PdmChildField<RimImportedFishboneLateralsCollection*> m_wellPathCollection;
|
||||
caf::PdmChildField<RimMswCompletionParameters*> m_mswParameters;
|
||||
caf::PdmChildArrayField<RimFishbones*> m_fishbones;
|
||||
caf::PdmChildField<RimMswCompletionParameters*> m_mswParameters;
|
||||
|
||||
caf::PdmField<double> m_startMD;
|
||||
caf::PdmField<double> m_skinFactor;
|
||||
|
@ -1,117 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011- Statoil ASA
|
||||
// Copyright (C) 2013- Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RimImportedFishboneLaterals.h"
|
||||
|
||||
#include "RimProject.h"
|
||||
|
||||
#include "cafPdmUiListEditor.h"
|
||||
#include "cafPdmUiTextEditor.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimImportedFishboneLaterals, "WellPathCompletion" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimImportedFishboneLaterals::RimImportedFishboneLaterals()
|
||||
{
|
||||
CAF_PDM_InitObject( "WellPathCompletion", ":/FishBoneLateralFromFile16x16.png", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_coordinates, "Coordinates", "Coordinates", "", "", "" );
|
||||
m_coordinates.uiCapability()->setUiHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_measuredDepths, "MeasuredDepth", "MeasuredDepth", "", "", "" );
|
||||
m_measuredDepths.uiCapability()->setUiHidden( true );
|
||||
|
||||
userDescriptionField()->uiCapability()->setUiHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_displayCoordinates, "DisplayCoordinates", "Coordinates", "", "", "" );
|
||||
m_displayCoordinates.registerGetMethod( this, &RimImportedFishboneLaterals::displayCoordinates );
|
||||
m_displayCoordinates.uiCapability()->setUiReadOnly( true );
|
||||
m_displayCoordinates.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() );
|
||||
m_displayCoordinates.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosType::TOP );
|
||||
|
||||
setDeletable( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimImportedFishboneLaterals::~RimImportedFishboneLaterals()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimImportedFishboneLaterals::setCoordinates( std::vector<cvf::Vec3d> coordinates )
|
||||
{
|
||||
m_coordinates = coordinates;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimImportedFishboneLaterals::setMeasuredDepths( std::vector<double> measuredDepths )
|
||||
{
|
||||
m_measuredDepths = measuredDepths;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimImportedFishboneLaterals::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
RimProject* proj;
|
||||
this->firstAncestorOrThisOfType( proj );
|
||||
if ( proj ) proj->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimImportedFishboneLaterals::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
uiOrdering.add( &m_displayCoordinates );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimImportedFishboneLaterals::displayCoordinates() const
|
||||
{
|
||||
CVF_ASSERT( m_coordinates().size() == m_measuredDepths().size() );
|
||||
|
||||
QStringList displayValues;
|
||||
|
||||
displayValues.push_back( QString( "X\tY\tZ\tMD" ) );
|
||||
for ( size_t i = 0; i < m_coordinates().size(); i++ )
|
||||
{
|
||||
const cvf::Vec3d& coords = m_coordinates()[i];
|
||||
const double& measuredDepth = m_measuredDepths()[i];
|
||||
displayValues.push_back( QString( "%1\t%2\t%3\t%4" )
|
||||
.arg( coords.x(), 0, 'f', 2 )
|
||||
.arg( coords.y(), 0, 'f', 2 )
|
||||
.arg( coords.z(), 0, 'f', 2 )
|
||||
.arg( measuredDepth, 0, 'f', 2 ) );
|
||||
}
|
||||
|
||||
return displayValues.join( "\n" );
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011- Statoil ASA
|
||||
// Copyright (C) 2013- Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RimCheckableNamedObject.h"
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
// Include to make Pdm work for cvf::Color
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmFieldCvfColor.h"
|
||||
#include "cafPdmFieldCvfVec3d.h"
|
||||
#include "cafPdmProxyValueField.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimImportedFishboneLaterals : public RimCheckableNamedObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimImportedFishboneLaterals();
|
||||
~RimImportedFishboneLaterals() override;
|
||||
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
|
||||
void setCoordinates( std::vector<cvf::Vec3d> coordinates );
|
||||
void setMeasuredDepths( std::vector<double> measuredDepths );
|
||||
|
||||
std::vector<cvf::Vec3d> coordinates() const { return m_coordinates(); }
|
||||
std::vector<double> measuredDepths() const { return m_measuredDepths(); }
|
||||
|
||||
private:
|
||||
QString displayCoordinates() const;
|
||||
|
||||
caf::PdmField<std::vector<cvf::Vec3d>> m_coordinates;
|
||||
caf::PdmField<std::vector<double>> m_measuredDepths;
|
||||
caf::PdmProxyValueField<QString> m_displayCoordinates;
|
||||
};
|
@ -1,149 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2015- Statoil ASA
|
||||
// Copyright (C) 2015- Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RimImportedFishboneLateralsCollection.h"
|
||||
|
||||
#include "Rim3dView.h"
|
||||
#include "RimFishbonesCollection.h"
|
||||
#include "RimImportedFishboneLaterals.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RifWellPathImporter.h"
|
||||
|
||||
#include "Riu3DMainWindowTools.h"
|
||||
|
||||
// The more general term WellPathCompletionCollection was unfortunately used in this more specific case of fishbones
|
||||
// In order to preserve compatibility, the old keyword is kept as an alias, but could be removed in the future.
|
||||
CAF_PDM_SOURCE_INIT( RimImportedFishboneLateralsCollection, "FishboneWellPathCollection", "WellPathCompletionCollection" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimImportedFishboneLateralsCollection::RimImportedFishboneLateralsCollection()
|
||||
{
|
||||
CAF_PDM_InitObject( "WellPathCompletions", ":/FishBoneGroupFromFile16x16.png", "", "" );
|
||||
|
||||
nameField()->uiCapability()->setUiHidden( true );
|
||||
this->setName( "Imported Laterals" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_wellPaths, "WellPaths", "Imported Laterals", "", "", "" );
|
||||
m_wellPaths.uiCapability()->setUiHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_pipeProperties, "PipeProperties", "Pipe Properties", "", "", "" );
|
||||
m_pipeProperties.uiCapability()->setUiHidden( true );
|
||||
m_pipeProperties.uiCapability()->setUiTreeHidden( true );
|
||||
m_pipeProperties.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
m_pipeProperties = new RimFishbonesPipeProperties;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimImportedFishboneLateralsCollection::importCompletionsFromFile( const QStringList& filePaths )
|
||||
{
|
||||
RifWellPathImporter wellPathImporter;
|
||||
|
||||
for ( const QString& filePath : filePaths )
|
||||
{
|
||||
size_t wellDataCount = wellPathImporter.wellDataCount( filePath );
|
||||
|
||||
for ( size_t i = 0; i < wellDataCount; ++i )
|
||||
{
|
||||
RifWellPathImporter::WellData wellData = wellPathImporter.readWellData( filePath, i );
|
||||
RimImportedFishboneLaterals* wellCompletion = new RimImportedFishboneLaterals();
|
||||
wellCompletion->setName( wellData.m_name );
|
||||
wellCompletion->setCoordinates( wellData.m_wellPathGeometry->uniqueWellPathPoints() );
|
||||
wellCompletion->setMeasuredDepths( wellData.m_wellPathGeometry->uniqueMeasuredDepths() );
|
||||
appendCompletion( wellCompletion );
|
||||
}
|
||||
}
|
||||
|
||||
RimFishbonesCollection* fishbonesCollection;
|
||||
firstAncestorOrThisOfType( fishbonesCollection );
|
||||
if ( fishbonesCollection != nullptr )
|
||||
{
|
||||
fishbonesCollection->recalculateStartMD();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimImportedFishboneLateralsCollection::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
RimProject* proj;
|
||||
this->firstAncestorOrThisOfTypeAsserted( proj );
|
||||
proj->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<const RimImportedFishboneLaterals*> RimImportedFishboneLateralsCollection::wellPaths() const
|
||||
{
|
||||
std::vector<const RimImportedFishboneLaterals*> paths;
|
||||
|
||||
for ( const RimImportedFishboneLaterals* path : m_wellPaths )
|
||||
{
|
||||
paths.push_back( path );
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimImportedFishboneLateralsCollection::setUnitSystemSpecificDefaults()
|
||||
{
|
||||
m_pipeProperties->setUnitSystemSpecificDefaults();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimImportedFishboneLateralsCollection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
caf::PdmUiGroup* wellPropertiesGroup = uiOrdering.addNewGroup( "Well Properties" );
|
||||
m_pipeProperties->uiOrdering( uiConfigName, *wellPropertiesGroup );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimImportedFishboneLateralsCollection::appendCompletion( RimImportedFishboneLaterals* completion )
|
||||
{
|
||||
m_wellPaths.push_back( completion );
|
||||
|
||||
updateConnectedEditors();
|
||||
Riu3DMainWindowTools::selectAsCurrentItem( completion );
|
||||
|
||||
uiCapability()->setUiHidden( !m_wellPaths.empty() );
|
||||
|
||||
RimProject* project = nullptr;
|
||||
firstAncestorOrThisOfTypeAsserted( project );
|
||||
if ( project )
|
||||
{
|
||||
project->reloadCompletionTypeResultsInAllViews();
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2015- Statoil ASA
|
||||
// Copyright (C) 2015- Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RimCheckableNamedObject.h"
|
||||
#include "RimFishbonesPipeProperties.h"
|
||||
#include "RimImportedFishboneLaterals.h"
|
||||
|
||||
#include "RiaDefines.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RimImportedFishboneLateralsCollection : public RimCheckableNamedObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimImportedFishboneLateralsCollection();
|
||||
|
||||
void importCompletionsFromFile( const QStringList& filePaths );
|
||||
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
|
||||
std::vector<const RimImportedFishboneLaterals*> wellPaths() const;
|
||||
double holeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const
|
||||
{
|
||||
return m_pipeProperties->holeDiameter( unitSystem );
|
||||
}
|
||||
double skinFactor() const { return m_pipeProperties->skinFactor(); }
|
||||
|
||||
void setUnitSystemSpecificDefaults();
|
||||
|
||||
protected:
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
|
||||
private:
|
||||
void appendCompletion( RimImportedFishboneLaterals* completion );
|
||||
|
||||
private:
|
||||
caf::PdmChildArrayField<RimImportedFishboneLaterals*> m_wellPaths;
|
||||
caf::PdmChildField<RimFishbonesPipeProperties*> m_pipeProperties;
|
||||
};
|
@ -49,7 +49,7 @@ void RimMswCompletionParameters::LengthAndDepthEnum::setUp()
|
||||
{
|
||||
addItem( RimMswCompletionParameters::INC, "INC", "Incremental" );
|
||||
addItem( RimMswCompletionParameters::ABS, "ABS", "Absolute" );
|
||||
setDefault( RimMswCompletionParameters::INC );
|
||||
setDefault( RimMswCompletionParameters::ABS );
|
||||
}
|
||||
} // namespace caf
|
||||
|
||||
|
@ -309,13 +309,7 @@ void RimWellPathCompletionSettings::defineEditorAttribute( const caf::PdmFieldHa
|
||||
caf::PdmUiEditorAttribute* attribute )
|
||||
{
|
||||
caf::PdmUiLineEditorAttribute* lineEditorAttr = dynamic_cast<caf::PdmUiLineEditorAttribute*>( attribute );
|
||||
if ( field == &m_wellNameForExport && lineEditorAttr )
|
||||
{
|
||||
QRegExpValidator* validator = new QRegExpValidator( nullptr );
|
||||
validator->setRegExp( wellNameForExportRegExp() );
|
||||
lineEditorAttr->validator = validator;
|
||||
}
|
||||
else if ( field == &m_drainageRadiusForPI && lineEditorAttr )
|
||||
if ( field == &m_drainageRadiusForPI && lineEditorAttr )
|
||||
{
|
||||
caf::PdmDoubleStringValidator* validator = new caf::PdmDoubleStringValidator( "1*" );
|
||||
lineEditorAttr->validator = validator;
|
||||
|
@ -22,7 +22,6 @@
|
||||
|
||||
#include "RimFishbones.h"
|
||||
#include "RimFishbonesCollection.h"
|
||||
#include "RimImportedFishboneLateralsCollection.h"
|
||||
#include "RimPerforationCollection.h"
|
||||
#include "RimPerforationInterval.h"
|
||||
#include "RimProject.h"
|
||||
@ -211,9 +210,7 @@ bool RimWellPathCompletions::hasCompletions() const
|
||||
return true;
|
||||
}
|
||||
|
||||
return !m_fishbonesCollection->allFishbonesSubs().empty() ||
|
||||
!m_fishbonesCollection->wellPathCollection()->wellPaths().empty() ||
|
||||
!m_perforationCollection->perforations().empty();
|
||||
return !m_fishbonesCollection->allFishbonesSubs().empty() || !m_perforationCollection->perforations().empty();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -244,8 +241,7 @@ void RimWellPathCompletions::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTre
|
||||
uiTreeOrdering.add( &m_perforationCollection );
|
||||
}
|
||||
|
||||
if ( !m_fishbonesCollection->allFishbonesSubs().empty() ||
|
||||
!m_fishbonesCollection->wellPathCollection()->wellPaths().empty() )
|
||||
if ( !m_fishbonesCollection->allFishbonesSubs().empty() )
|
||||
{
|
||||
uiTreeOrdering.add( &m_fishbonesCollection );
|
||||
}
|
||||
|
@ -304,6 +304,14 @@ std::vector<std::pair<double, double>> RimWellPathValve::valveSegments() const
|
||||
return segments;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathValve::setComponentTypeFilter( const std::set<RiaDefines::WellPathComponentType>& filter )
|
||||
{
|
||||
m_componentTypeFilter = filter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -456,6 +464,11 @@ QList<caf::PdmOptionItemInfo> RimWellPathValve::calculateValueOptions( const caf
|
||||
std::vector<RimValveTemplate*> allTemplates = project->allValveTemplates();
|
||||
for ( RimValveTemplate* valveTemplate : allTemplates )
|
||||
{
|
||||
if ( !m_componentTypeFilter.empty() )
|
||||
{
|
||||
if ( m_componentTypeFilter.count( valveTemplate->type() ) == 0 ) continue;
|
||||
}
|
||||
|
||||
options.push_back( caf::PdmOptionItemInfo( valveTemplate->name(), valveTemplate ) );
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,8 @@ public:
|
||||
|
||||
std::vector<std::pair<double, double>> valveSegments() const;
|
||||
|
||||
void setComponentTypeFilter( const std::set<RiaDefines::WellPathComponentType>& filter );
|
||||
|
||||
// Overrides from RimWellPathCompletionInterface
|
||||
bool isEnabled() const override;
|
||||
RiaDefines::WellPathComponentType componentType() const override;
|
||||
@ -92,4 +94,6 @@ private:
|
||||
caf::PdmChildField<RimMultipleValveLocations*> m_multipleValveLocations;
|
||||
caf::PdmField<bool> m_editValveTemplate;
|
||||
caf::PdmField<bool> m_createValveTemplate;
|
||||
|
||||
std::set<RiaDefines::WellPathComponentType> m_componentTypeFilter;
|
||||
};
|
||||
|
@ -88,7 +88,6 @@
|
||||
#include "RimGridCrossPlotCollection.h"
|
||||
#include "RimGridCrossPlotDataSet.h"
|
||||
#include "RimIdenticalGridCaseGroup.h"
|
||||
#include "RimImportedFishboneLateralsCollection.h"
|
||||
#include "RimIntersectionCollection.h"
|
||||
#include "RimIntersectionResultDefinition.h"
|
||||
#include "RimIntersectionResultsDefinitionCollection.h"
|
||||
@ -336,7 +335,6 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
|
||||
menuBuilder << "RicReloadWellPathFormationNamesFeature";
|
||||
menuBuilder.addSeparator();
|
||||
menuBuilder << "RicWellPathImportPerforationIntervalsFeature";
|
||||
menuBuilder << "RicWellPathImportCompletionsFileFeature";
|
||||
menuBuilder << "RicImportWellMeasurementsFeature";
|
||||
menuBuilder.subMenuEnd();
|
||||
menuBuilder.addSeparator();
|
||||
@ -392,10 +390,6 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
|
||||
menuBuilder << "RicShowWellPlanFeature";
|
||||
}
|
||||
}
|
||||
else if ( dynamic_cast<RimImportedFishboneLateralsCollection*>( firstUiItem ) )
|
||||
{
|
||||
appendImportMenu( menuBuilder );
|
||||
}
|
||||
else if ( dynamic_cast<RimWellPathCompletions*>( firstUiItem ) )
|
||||
{
|
||||
menuBuilder.subMenuStart( "Create Completions", QIcon( ":/CompletionsSymbol16x16.png" ) );
|
||||
@ -418,8 +412,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
|
||||
menuBuilder.addSeparator();
|
||||
appendExportCompletions( menuBuilder );
|
||||
}
|
||||
else if ( dynamic_cast<RimFishbonesCollection*>( firstUiItem ) || dynamic_cast<RimFishbones*>( firstUiItem ) ||
|
||||
dynamic_cast<RimImportedFishboneLateralsCollection*>( firstUiItem ) )
|
||||
else if ( dynamic_cast<RimFishbonesCollection*>( firstUiItem ) || dynamic_cast<RimFishbones*>( firstUiItem ) )
|
||||
{
|
||||
menuBuilder << "RicNewFishbonesSubsFeature";
|
||||
appendExportCompletions( menuBuilder );
|
||||
@ -1335,8 +1328,6 @@ int RimContextCommandBuilder::appendImportMenu( caf::CmdFeatureMenuBuilder& menu
|
||||
candidates << "RicWellPathFormationsImportFileFeature";
|
||||
candidates << "RicWellLogsImportFileFeature";
|
||||
candidates << "RicReloadWellPathFormationNamesFeature";
|
||||
candidates << "Separator";
|
||||
candidates << "RicWellPathImportCompletionsFileFeature";
|
||||
|
||||
return appendSubMenuWithCommands( menuBuilder, candidates, "Import", QIcon(), addSeparatorBeforeMenu );
|
||||
}
|
||||
|
@ -18,21 +18,24 @@
|
||||
|
||||
#include "RimModeledWellPath.h"
|
||||
|
||||
#include "RiaCompletionTypeCalculationScheduler.h"
|
||||
#include "RicfCommandObject.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPathGeometryDef.h"
|
||||
|
||||
#include "RifTextDataTableFormatter.h"
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RiaCompletionTypeCalculationScheduler.h"
|
||||
#include "RifTextDataTableFormatter.h"
|
||||
#include "RimExtrudedCurveIntersection.h"
|
||||
#include "RimPlotCurve.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimTools.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathFracture.h"
|
||||
#include "RimWellPathFractureCollection.h"
|
||||
#include "RimWellPathGeometryDef.h"
|
||||
#include "RimWellPathTarget.h"
|
||||
#include "RimWellPathTieIn.h"
|
||||
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
#include "cafPdmUiDoubleValueEditor.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimModeledWellPath, "ModeledWellPath" );
|
||||
@ -191,6 +194,7 @@ void RimModeledWellPath::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrd
|
||||
void RimModeledWellPath::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
uiOrdering.add( &m_name );
|
||||
|
||||
RimWellPath::defineUiOrdering( uiConfigName, uiOrdering );
|
||||
}
|
||||
|
||||
@ -198,10 +202,95 @@ void RimModeledWellPath::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimModeledWellPath::onGeometryDefinitionChanged( const caf::SignalEmitter* emitter, bool fullUpdate )
|
||||
{
|
||||
updateGeometry( fullUpdate );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimModeledWellPath::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
// TODO remove if nothing happens here
|
||||
|
||||
RimWellPath::fieldChangedByUi( changedField, oldValue, newValue );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimModeledWellPath::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly )
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimModeledWellPath::updateGeometry( bool fullUpdate )
|
||||
{
|
||||
updateWellPathVisualization();
|
||||
|
||||
std::vector<RimWellPathTieIn*> tieInObjects;
|
||||
objectsWithReferringPtrFieldsOfType( tieInObjects );
|
||||
for ( auto tieIn : tieInObjects )
|
||||
{
|
||||
if ( tieIn->parentWell() == this )
|
||||
{
|
||||
tieIn->updateChildWellGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
if ( fullUpdate )
|
||||
{
|
||||
scheduleUpdateOfDependentVisualization();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimModeledWellPath::updateTieInLocationFromParentWell()
|
||||
{
|
||||
RimWellPath* parentWellPath = nullptr;
|
||||
|
||||
RimWellPathTieIn* tieIn = wellPathTieIn();
|
||||
if ( tieIn )
|
||||
{
|
||||
parentWellPath = tieIn->parentWell();
|
||||
|
||||
auto targets = m_geometryDefinition->activeWellTargets();
|
||||
if ( parentWellPath && !targets.empty() )
|
||||
{
|
||||
auto [pointVector, measuredDepths] =
|
||||
parentWellPath->wellPathGeometry()
|
||||
->clippedPointSubset( parentWellPath->wellPathGeometry()->measuredDepths().front(),
|
||||
tieIn->tieInMeasuredDepth() );
|
||||
|
||||
if ( pointVector.size() > 2u )
|
||||
{
|
||||
auto firstTarget = targets.front();
|
||||
firstTarget->setPointXYZ( pointVector.back() );
|
||||
|
||||
m_geometryDefinition->setIsAttachedToParentWell( true );
|
||||
m_geometryDefinition->setMdAtFirstTarget( measuredDepths.back() );
|
||||
m_geometryDefinition->setFixedWellPathPoints( pointVector );
|
||||
m_geometryDefinition->setFixedMeasuredDepths( measuredDepths );
|
||||
|
||||
updateGeometry( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !parentWellPath )
|
||||
{
|
||||
m_geometryDefinition->setIsAttachedToParentWell( false );
|
||||
m_geometryDefinition->setFixedWellPathPoints( {} );
|
||||
m_geometryDefinition->setFixedMeasuredDepths( {} );
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "RimWellPath.h"
|
||||
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
class RimWellPathTarget;
|
||||
class RimWellPath;
|
||||
@ -38,11 +39,20 @@ public:
|
||||
void scheduleUpdateOfDependentVisualization();
|
||||
RimWellPathGeometryDef* geometryDefinition() const;
|
||||
QString wellPlanText();
|
||||
void updateTieInLocationFromParentWell();
|
||||
|
||||
private:
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void onGeometryDefinitionChanged( const caf::SignalEmitter* emitter, bool fullUpdate );
|
||||
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly ) override;
|
||||
|
||||
void updateGeometry( bool fullUpdate );
|
||||
|
||||
private:
|
||||
caf::PdmChildField<RimWellPathGeometryDef*> m_geometryDefinition;
|
||||
};
|
||||
|
@ -234,19 +234,43 @@ QString RimTools::relocateFile( const QString& originalFileName,
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTools::wellPathOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
void RimTools::wellPathOptionItemsSubset( const std::vector<RimWellPath*>& wellPathsToExclude,
|
||||
QList<caf::PdmOptionItemInfo>* options )
|
||||
{
|
||||
CVF_ASSERT( options );
|
||||
if ( !options ) return;
|
||||
|
||||
auto wellPathColl = RimTools::wellPathCollection();
|
||||
if ( wellPathColl )
|
||||
{
|
||||
caf::IconProvider wellIcon( ":/Well.svg" );
|
||||
for ( auto wellPath : wellPathColl->allWellPaths() )
|
||||
std::vector<RimWellPath*> wellPathsToInclude;
|
||||
|
||||
auto all = wellPathColl->allWellPaths();
|
||||
for ( auto w : all )
|
||||
{
|
||||
options->push_back( caf::PdmOptionItemInfo( wellPath->name(), wellPath, false, wellIcon ) );
|
||||
bool include = true;
|
||||
for ( auto exclude : wellPathsToExclude )
|
||||
{
|
||||
if ( w == exclude ) include = false;
|
||||
}
|
||||
|
||||
if ( include ) wellPathsToInclude.push_back( w );
|
||||
}
|
||||
|
||||
optionItemsForSpecifiedWellPaths( wellPathsToInclude, options );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTools::wellPathOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
{
|
||||
if ( !options ) return;
|
||||
|
||||
auto wellPathColl = RimTools::wellPathCollection();
|
||||
if ( wellPathColl )
|
||||
{
|
||||
optionItemsForSpecifiedWellPaths( wellPathColl->allWellPaths(), options );
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,17 +279,12 @@ void RimTools::wellPathOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTools::wellPathWithFormationsOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
{
|
||||
CVF_ASSERT( options );
|
||||
if ( !options ) return;
|
||||
|
||||
std::vector<RimWellPath*> wellPaths;
|
||||
RimTools::wellPathWithFormations( &wellPaths );
|
||||
|
||||
caf::IconProvider wellIcon( ":/Well.svg" );
|
||||
for ( auto wellPath : wellPaths )
|
||||
{
|
||||
options->push_back( caf::PdmOptionItemInfo( wellPath->name(), wellPath, false, wellIcon ) );
|
||||
}
|
||||
optionItemsForSpecifiedWellPaths( wellPaths, options );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -291,7 +310,6 @@ void RimTools::wellPathWithFormations( std::vector<RimWellPath*>* wellPaths )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTools::caseOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
{
|
||||
CVF_ASSERT( options );
|
||||
if ( !options ) return;
|
||||
|
||||
RimProject* proj = RimProject::current();
|
||||
@ -312,7 +330,6 @@ void RimTools::caseOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTools::eclipseCaseOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
{
|
||||
CVF_ASSERT( options );
|
||||
if ( !options ) return;
|
||||
|
||||
RimProject* proj = RimProject::current();
|
||||
@ -337,7 +354,6 @@ void RimTools::eclipseCaseOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTools::geoMechCaseOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
{
|
||||
CVF_ASSERT( options );
|
||||
if ( !options ) return;
|
||||
|
||||
RimProject* proj = RimProject::current();
|
||||
@ -362,7 +378,6 @@ void RimTools::geoMechCaseOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTools::colorLegendOptionItems( QList<caf::PdmOptionItemInfo>* options )
|
||||
{
|
||||
CVF_ASSERT( options );
|
||||
if ( !options ) return;
|
||||
|
||||
RimProject* project = RimProject::current();
|
||||
@ -407,3 +422,18 @@ void RimTools::timeStepsForCase( RimCase* gridCase, QList<caf::PdmOptionItemInfo
|
||||
options->push_back( caf::PdmOptionItemInfo( timeStepNames[i], i ) );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimTools::optionItemsForSpecifiedWellPaths( const std::vector<RimWellPath*>& wellPaths,
|
||||
QList<caf::PdmOptionItemInfo>* options )
|
||||
{
|
||||
if ( !options ) return;
|
||||
|
||||
caf::IconProvider wellIcon( ":/Well.svg" );
|
||||
for ( auto wellPath : wellPaths )
|
||||
{
|
||||
options->push_back( caf::PdmOptionItemInfo( wellPath->name(), wellPath, false, wellIcon ) );
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ public:
|
||||
bool* foundFile,
|
||||
std::vector<QString>* searchedPaths );
|
||||
|
||||
static void wellPathOptionItemsSubset( const std::vector<RimWellPath*>& wellPathsToExclude,
|
||||
QList<caf::PdmOptionItemInfo>* options );
|
||||
static void wellPathOptionItems( QList<caf::PdmOptionItemInfo>* options );
|
||||
static void wellPathWithFormationsOptionItems( QList<caf::PdmOptionItemInfo>* options );
|
||||
static void wellPathWithFormations( std::vector<RimWellPath*>* wellPaths );
|
||||
@ -61,4 +63,8 @@ public:
|
||||
static RimWellPathCollection* wellPathCollection();
|
||||
|
||||
static void timeStepsForCase( RimCase* gridCase, QList<caf::PdmOptionItemInfo>* options );
|
||||
|
||||
private:
|
||||
static void optionItemsForSpecifiedWellPaths( const std::vector<RimWellPath*>& wellPaths,
|
||||
QList<caf::PdmOptionItemInfo>* options );
|
||||
};
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "RimWellPathCompletions.h"
|
||||
#include "RimWellPathFracture.h"
|
||||
#include "RimWellPathFractureCollection.h"
|
||||
#include "RimWellPathTieIn.h"
|
||||
|
||||
#include "RiuMainWindow.h"
|
||||
|
||||
@ -131,6 +132,8 @@ RimWellPath::RimWellPath()
|
||||
m_wellPathAttributes = new RimWellPathAttributeCollection;
|
||||
m_wellPathAttributes->uiCapability()->setUiTreeHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_wellPathTieIn, "WellPathTieIn", "well Path Tie-In", "", "", "" );
|
||||
|
||||
this->setDeletable( true );
|
||||
}
|
||||
|
||||
@ -285,7 +288,9 @@ const RimWellPathCompletions* RimWellPath::completions() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RimWellPathCompletionSettings* RimWellPath::completionSettings() const
|
||||
{
|
||||
return m_completionSettings();
|
||||
if ( isTopLevelWellPath() ) return m_completionSettings();
|
||||
|
||||
return topLevelWellPath()->completionSettings();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -293,7 +298,9 @@ const RimWellPathCompletionSettings* RimWellPath::completionSettings() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPathCompletionSettings* RimWellPath::completionSettings()
|
||||
{
|
||||
return m_completionSettings();
|
||||
if ( isTopLevelWellPath() ) return m_completionSettings();
|
||||
|
||||
return topLevelWellPath()->completionSettings();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -612,6 +619,11 @@ void RimWellPath::setWellPathGeometry( RigWellPath* wellPathModel )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPath::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
if ( m_wellPathTieIn() )
|
||||
{
|
||||
m_wellPathTieIn->uiOrdering( uiConfigName, uiOrdering );
|
||||
}
|
||||
|
||||
if ( m_simWellName().isEmpty() )
|
||||
{
|
||||
// Try to set default simulation well name
|
||||
@ -961,12 +973,18 @@ std::vector<const RimWellPathComponentInterface*> RimWellPath::allCompletionsRec
|
||||
{
|
||||
std::vector<const RimWellPathComponentInterface*> allCompletions;
|
||||
|
||||
std::vector<const RimWellPathCompletions*> completionCollections;
|
||||
this->descendantsOfType( completionCollections );
|
||||
for ( auto collection : completionCollections )
|
||||
auto tieInWells = wellPathLateralsRecursively();
|
||||
tieInWells.push_back( const_cast<RimWellPath*>( this ) );
|
||||
|
||||
for ( auto w : tieInWells )
|
||||
{
|
||||
std::vector<const RimWellPathComponentInterface*> completions = collection->allCompletions();
|
||||
allCompletions.insert( allCompletions.end(), completions.begin(), completions.end() );
|
||||
std::vector<const RimWellPathCompletions*> completionCollections;
|
||||
w->descendantsOfType( completionCollections );
|
||||
for ( auto collection : completionCollections )
|
||||
{
|
||||
std::vector<const RimWellPathComponentInterface*> completions = collection->allCompletions();
|
||||
allCompletions.insert( allCompletions.end(), completions.begin(), completions.end() );
|
||||
}
|
||||
}
|
||||
|
||||
return allCompletions;
|
||||
@ -1048,12 +1066,27 @@ bool RimWellPath::isMultiLateralWellPath() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPath* RimWellPath::topLevelWellPath() const
|
||||
RimWellPath* RimWellPath::topLevelWellPath()
|
||||
{
|
||||
std::vector<RimWellPath*> wellPathHierarchy;
|
||||
this->allAncestorsOrThisOfType( wellPathHierarchy );
|
||||
RimWellPath* wellPath = wellPathHierarchy.back();
|
||||
return wellPath;
|
||||
if ( m_wellPathTieIn() && m_wellPathTieIn->parentWell() )
|
||||
{
|
||||
return m_wellPathTieIn()->parentWell()->topLevelWellPath();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RimWellPath* RimWellPath::topLevelWellPath() const
|
||||
{
|
||||
if ( m_wellPathTieIn() && m_wellPathTieIn->parentWell() )
|
||||
{
|
||||
return m_wellPathTieIn()->parentWell()->topLevelWellPath();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1062,3 +1095,46 @@ RimWellPath* RimWellPath::topLevelWellPath() const
|
||||
void RimWellPath::updateAfterAddingToWellPathGroup()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimWellPath*> RimWellPath::wellPathLateralsRecursively() const
|
||||
{
|
||||
std::vector<RimWellPath*> tieInWells;
|
||||
|
||||
auto wellPathColl = RimTools::wellPathCollection();
|
||||
if ( wellPathColl )
|
||||
{
|
||||
wellPathColl->allWellPaths();
|
||||
|
||||
for ( auto w : wellPathColl->allWellPaths() )
|
||||
{
|
||||
if ( w->topLevelWellPath() == this )
|
||||
{
|
||||
tieInWells.push_back( w );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tieInWells;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPathTieIn* RimWellPath::wellPathTieIn() const
|
||||
{
|
||||
return m_wellPathTieIn();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPath::connectWellPaths( RimWellPath* parentWell, double parentTieInMeasuredDepth )
|
||||
{
|
||||
if ( !m_wellPathTieIn() ) m_wellPathTieIn = new RimWellPathTieIn;
|
||||
|
||||
m_wellPathTieIn->connectWellPaths( parentWell, this, parentTieInMeasuredDepth );
|
||||
m_wellPathTieIn->updateFirstTargetFromParentWell();
|
||||
}
|
||||
|
@ -54,10 +54,10 @@ class RimPerforationCollection;
|
||||
class RimWellPathAttributeCollection;
|
||||
class RimWellPathCompletions;
|
||||
class RimWellPathCompletionSettings;
|
||||
|
||||
class RimWellPathFractureCollection;
|
||||
class Rim3dWellLogCurve;
|
||||
class Rim3dWellLogCurveCollection;
|
||||
class RimWellPathTieIn;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -154,10 +154,15 @@ public:
|
||||
void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray,
|
||||
std::vector<caf::PdmObjectHandle*>& referringObjects ) override;
|
||||
|
||||
bool isTopLevelWellPath() const;
|
||||
bool isMultiLateralWellPath() const;
|
||||
RimWellPath* topLevelWellPath() const;
|
||||
void updateAfterAddingToWellPathGroup();
|
||||
bool isTopLevelWellPath() const;
|
||||
bool isMultiLateralWellPath() const;
|
||||
RimWellPath* topLevelWellPath();
|
||||
const RimWellPath* topLevelWellPath() const;
|
||||
void updateAfterAddingToWellPathGroup();
|
||||
std::vector<RimWellPath*> wellPathLateralsRecursively() const;
|
||||
|
||||
RimWellPathTieIn* wellPathTieIn() const;
|
||||
void connectWellPaths( RimWellPath* childWell, double tieInMeasuredDepth );
|
||||
|
||||
protected:
|
||||
// Override PdmObject
|
||||
@ -201,6 +206,8 @@ private:
|
||||
caf::PdmChildField<RimWellPathCompletions*> m_completions;
|
||||
caf::PdmChildField<RimWellPathAttributeCollection*> m_wellPathAttributes;
|
||||
|
||||
caf::PdmChildField<RimWellPathTieIn*> m_wellPathTieIn;
|
||||
|
||||
private:
|
||||
static size_t simulationWellBranchCount( const QString& simWellName );
|
||||
|
||||
|
@ -74,7 +74,10 @@ RimWellPathGeometryDef::RimWellPathGeometryDef()
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_airGap, "AirGap", 0.0, "Air Gap", "", "", "" );
|
||||
m_airGap.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_mdAtFirstTarget, "MdAtFirstTarget", 0.0, "MD at First Target", "", "", "" );
|
||||
m_mdAtFirstTarget.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_wellTargets, "WellPathTargets", "Well Targets", "", "", "" );
|
||||
m_wellTargets.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() );
|
||||
m_wellTargets.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
@ -93,11 +96,16 @@ RimWellPathGeometryDef::RimWellPathGeometryDef()
|
||||
m_autoTargetAtSeaLevel = new RimWellPathTarget;
|
||||
m_autoTargetAtSeaLevel->setEnabled( false );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_isAttachedToParentWell, "AttachedToParentWell", false, "Attached to Parent Well", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_fixedWellPathPoints, "FixedWellPathPoints", "", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_fixedMeasuredDepths, "FixedMeasuredDepths", "", "", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_pickPointsEnabled, "m_pickPointsEnabled", false, "", "", "", "" );
|
||||
caf::PdmUiPushButtonEditor::configureEditorForField( &m_pickPointsEnabled );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_showSpheres, "ShowSpheres", false, "Spheres", "", "", "" );
|
||||
CAF_PDM_InitField( &m_sphereColor, "SphereColor", cvf::Color3f( cvf::Color3f::CEETRON ), "Sphere Color", "", "", "" );
|
||||
CAF_PDM_InitField( &m_sphereRadiusFactor, "SphereRadiusFactor", 0.15, "Sphere Radius Factor", "", "", "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -159,6 +167,14 @@ void RimWellPathGeometryDef::setMdAtFirstTarget( double md )
|
||||
m_mdAtFirstTarget = md;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathGeometryDef::setIsAttachedToParentWell( bool isAttached )
|
||||
{
|
||||
m_isAttachedToParentWell = isAttached;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -244,6 +260,30 @@ std::vector<RiaWellPlanCalculator::WellPlanSegment> RimWellPathGeometryDef::well
|
||||
return wpCalc.wellPlan();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimWellPathGeometryDef::showSpheres() const
|
||||
{
|
||||
return m_showSpheres();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Color3f RimWellPathGeometryDef::sphereColor() const
|
||||
{
|
||||
return m_sphereColor();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimWellPathGeometryDef::sphereRadiusFactor() const
|
||||
{
|
||||
return m_sphereRadiusFactor();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -406,10 +446,19 @@ void RimWellPathGeometryDef::fieldChangedByUi( const caf::PdmFieldHandle* change
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathGeometryDef::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
uiOrdering.add( &m_referencePointUtmXyd );
|
||||
uiOrdering.add( &m_airGap );
|
||||
uiOrdering.add( &m_mdAtFirstTarget );
|
||||
uiOrdering.add( &m_useAutoGeneratedTargetAtSeaLevel );
|
||||
if ( !m_isAttachedToParentWell )
|
||||
{
|
||||
uiOrdering.add( &m_referencePointUtmXyd );
|
||||
uiOrdering.add( &m_airGap );
|
||||
uiOrdering.add( &m_mdAtFirstTarget );
|
||||
uiOrdering.add( &m_useAutoGeneratedTargetAtSeaLevel );
|
||||
}
|
||||
|
||||
auto group = uiOrdering.addNewGroup( "Well Target Appearance" );
|
||||
group->add( &m_showSpheres );
|
||||
group->add( &m_sphereColor );
|
||||
group->add( &m_sphereRadiusFactor );
|
||||
|
||||
uiOrdering.add( &m_wellTargets );
|
||||
uiOrdering.add( &m_pickPointsEnabled );
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
#include "cvfColor3.h"
|
||||
#include "cvfObject.h"
|
||||
|
||||
class RimWellPath;
|
||||
@ -55,6 +56,7 @@ public:
|
||||
double mdAtFirstTarget() const;
|
||||
void setMdAtFirstTarget( double mdrkb );
|
||||
|
||||
void setIsAttachedToParentWell( bool isAttached );
|
||||
void setFixedWellPathPoints( const std::vector<cvf::Vec3d>& points );
|
||||
void setFixedMeasuredDepths( const std::vector<double>& mds );
|
||||
|
||||
@ -80,6 +82,11 @@ public:
|
||||
|
||||
std::vector<RiaWellPlanCalculator::WellPlanSegment> wellPlan() const;
|
||||
|
||||
// Well target appearance
|
||||
bool showSpheres() const;
|
||||
cvf::Color3f sphereColor() const;
|
||||
double sphereRadiusFactor() const;
|
||||
|
||||
protected:
|
||||
void defineCustomContextMenu( const caf::PdmFieldHandle* fieldNeedingMenu, QMenu* menu, QWidget* fieldEditorWidget ) override;
|
||||
|
||||
@ -116,5 +123,11 @@ private:
|
||||
caf::PdmField<std::vector<cvf::Vec3d>> m_fixedWellPathPoints;
|
||||
caf::PdmField<std::vector<double>> m_fixedMeasuredDepths;
|
||||
|
||||
caf::PdmField<bool> m_isAttachedToParentWell;
|
||||
|
||||
caf::PdmField<bool> m_showSpheres;
|
||||
caf::PdmField<cvf::Color3f> m_sphereColor;
|
||||
caf::PdmField<double> m_sphereRadiusFactor;
|
||||
|
||||
std::shared_ptr<RicCreateWellTargetsPickEventHandler> m_pickTargetsEventHandler;
|
||||
};
|
||||
|
@ -96,6 +96,14 @@ bool RimWellPathTarget::isEnabled() const
|
||||
return m_isEnabled;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathTarget::setPointXYZ( const cvf::Vec3d& point )
|
||||
{
|
||||
m_targetPoint = { point.x(), point.y(), -point.z() };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -42,8 +42,9 @@ public:
|
||||
void setEnabled( bool enable );
|
||||
bool isEnabled() const;
|
||||
|
||||
void setPointXYZ( const cvf::Vec3d& point );
|
||||
void setAsPointTargetXYD( const cvf::Vec3d& point );
|
||||
void setAsPointTargetXYZ( const cvf::Vec3d& point);
|
||||
void setAsPointTargetXYZ( const cvf::Vec3d& point );
|
||||
void setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, const cvf::Vec3d& tangent );
|
||||
void setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, double azimuth, double inclination );
|
||||
void setDerivedTangent( double azimuth, double inclination );
|
||||
|
205
ApplicationLibCode/ProjectDataModel/RimWellPathTieIn.cpp
Normal file
205
ApplicationLibCode/ProjectDataModel/RimWellPathTieIn.cpp
Normal file
@ -0,0 +1,205 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RimWellPathTieIn.h"
|
||||
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimTools.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPathGeometryDef.h"
|
||||
#include "RimWellPathTarget.h"
|
||||
#include "RimWellPathValve.h"
|
||||
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
#include "cafPdmObjectScriptingCapability.h"
|
||||
#include "cafPdmUiDoubleValueEditor.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimWellPathTieIn, "RimWellPathTieIn" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPathTieIn::RimWellPathTieIn()
|
||||
{
|
||||
CAF_PDM_InitObject( "Well Path Tie In", ":/NotDefined.png", "", "Well Path Tie In description" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_parentWell, "ParentWellPath", "ParentWellPath", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_childWell, "ChildWellPath", "ChildWellPath", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_tieInMeasuredDepth, "TieInMeasuredDepth", "TieInMeasuredDepth", "", "", "" );
|
||||
m_tieInMeasuredDepth.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_addValveAtConnection,
|
||||
"AddValveAtConnection",
|
||||
false,
|
||||
"Add Outlet Valve for Branches",
|
||||
"",
|
||||
"",
|
||||
"" );
|
||||
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_valve, "Valve", "Branch Outlet Valve", "", "", "" );
|
||||
|
||||
m_valve = new RimWellPathValve;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathTieIn::connectWellPaths( RimWellPath* parentWell, RimWellPath* childWell, double tieInMeasuredDepth )
|
||||
{
|
||||
m_parentWell = parentWell;
|
||||
m_childWell = childWell;
|
||||
m_tieInMeasuredDepth = tieInMeasuredDepth;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPath* RimWellPathTieIn::parentWell() const
|
||||
{
|
||||
return m_parentWell();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimWellPathTieIn::tieInMeasuredDepth() const
|
||||
{
|
||||
return m_tieInMeasuredDepth();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPath* RimWellPathTieIn::childWell() const
|
||||
{
|
||||
return m_childWell();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathTieIn::updateChildWellGeometry()
|
||||
{
|
||||
auto modeledWellPath = dynamic_cast<RimModeledWellPath*>( m_childWell() );
|
||||
if ( modeledWellPath )
|
||||
{
|
||||
modeledWellPath->updateTieInLocationFromParentWell();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathTieIn::updateFirstTargetFromParentWell()
|
||||
{
|
||||
auto parentWellPath = m_parentWell();
|
||||
if ( !parentWellPath ) return;
|
||||
|
||||
auto modeledWellPath = dynamic_cast<RimModeledWellPath*>( m_childWell() );
|
||||
if ( modeledWellPath && modeledWellPath->geometryDefinition() )
|
||||
{
|
||||
auto [pointVector, measuredDepths] =
|
||||
parentWellPath->wellPathGeometry()
|
||||
->clippedPointSubset( parentWellPath->wellPathGeometry()->measuredDepths().front(), m_tieInMeasuredDepth );
|
||||
if ( pointVector.size() < 2u ) return;
|
||||
|
||||
RimWellPathTarget* newTarget = nullptr;
|
||||
|
||||
if ( modeledWellPath->geometryDefinition()->activeWellTargets().empty() )
|
||||
{
|
||||
newTarget = modeledWellPath->geometryDefinition()->appendTarget();
|
||||
}
|
||||
else
|
||||
{
|
||||
newTarget = modeledWellPath->geometryDefinition()->activeWellTargets().front();
|
||||
}
|
||||
|
||||
auto lastPoint = pointVector.back();
|
||||
auto tangent = lastPoint - pointVector[pointVector.size() - 2];
|
||||
newTarget->setAsPointXYZAndTangentTarget( { lastPoint[0], lastPoint[1], lastPoint[2] }, tangent );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RimWellPathValve* RimWellPathTieIn::outletValve() const
|
||||
{
|
||||
return m_addValveAtConnection() && m_valve() && m_valve->valveTemplate() ? m_valve() : nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathTieIn::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
auto tieInGroup = uiOrdering.addNewGroup( "Tie In Settings" );
|
||||
tieInGroup->add( &m_parentWell );
|
||||
tieInGroup->add( &m_tieInMeasuredDepth );
|
||||
tieInGroup->add( &m_addValveAtConnection );
|
||||
|
||||
// Display only ICV valves
|
||||
m_valve->setComponentTypeFilter( { RiaDefines::WellPathComponentType::ICV } );
|
||||
|
||||
if ( m_addValveAtConnection )
|
||||
{
|
||||
m_valve->uiOrdering( "TemplateOnly", *tieInGroup );
|
||||
}
|
||||
|
||||
uiOrdering.skipRemainingFields();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathTieIn::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
if ( changedField == &m_parentWell )
|
||||
{
|
||||
updateFirstTargetFromParentWell();
|
||||
}
|
||||
|
||||
updateChildWellGeometry();
|
||||
|
||||
// Update all well paths to make sure the visibility of completion settings is updated
|
||||
// Completions settings is only visible for top-level wells, not for tie-in wells
|
||||
RimTools::wellPathCollection()->updateAllRequiredEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimWellPathTieIn::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly )
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
|
||||
if ( fieldNeedingOptions == &m_parentWell )
|
||||
{
|
||||
std::vector<RimWellPath*> wellPathsToExclude = { m_childWell() };
|
||||
RimTools::wellPathOptionItemsSubset( wellPathsToExclude, &options );
|
||||
|
||||
options.push_front( caf::PdmOptionItemInfo( "None", nullptr ) );
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
62
ApplicationLibCode/ProjectDataModel/RimWellPathTieIn.h
Normal file
62
ApplicationLibCode/ProjectDataModel/RimWellPathTieIn.h
Normal file
@ -0,0 +1,62 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
class RimWellPath;
|
||||
class RimWellPathValve;
|
||||
|
||||
class RimWellPathTieIn : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimWellPathTieIn();
|
||||
|
||||
void connectWellPaths( RimWellPath* parentWell, RimWellPath* childWell, double tieInMeasuredDepth );
|
||||
RimWellPath* parentWell() const;
|
||||
double tieInMeasuredDepth() const;
|
||||
|
||||
RimWellPath* childWell() const;
|
||||
void updateChildWellGeometry();
|
||||
|
||||
void updateFirstTargetFromParentWell();
|
||||
|
||||
const RimWellPathValve* outletValve() const;
|
||||
|
||||
private:
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly ) override;
|
||||
|
||||
private:
|
||||
caf::PdmPtrField<RimWellPath*> m_parentWell;
|
||||
caf::PdmPtrField<RimWellPath*> m_childWell;
|
||||
caf::PdmField<double> m_tieInMeasuredDepth;
|
||||
|
||||
caf::PdmField<bool> m_addValveAtConnection;
|
||||
caf::PdmChildField<RimWellPathValve*> m_valve;
|
||||
};
|
@ -159,6 +159,8 @@ std::vector<WellPathCellIntersectionInfo> RigWellPathIntersectionTools::buildCon
|
||||
{
|
||||
std::vector<WellPathCellIntersectionInfo> intersectionsNoGap;
|
||||
|
||||
if ( originalIntersections.empty() ) return intersectionsNoGap;
|
||||
|
||||
for ( size_t i = 0; i < originalIntersections.size() - 1; i++ )
|
||||
{
|
||||
const WellPathCellIntersectionInfo& current = originalIntersections[i];
|
||||
|
@ -531,7 +531,6 @@ void RiuViewerCommands::displayContextMenu( QMouseEvent* event )
|
||||
menuBuilder << "RicNewWellPathStimPlanModelAtPosFeature";
|
||||
menuBuilder.addSeparator();
|
||||
menuBuilder << "RicNewWellPathAttributeFeature";
|
||||
menuBuilder << "RicWellPathImportCompletionsFileFeature";
|
||||
|
||||
menuBuilder.subMenuEnd();
|
||||
|
||||
|
@ -10,7 +10,7 @@ set(RESINSIGHT_VERSION_TEXT "-dev")
|
||||
# Must be unique and increasing within one combination of major/minor/patch version
|
||||
# The uniqueness of this text is independent of RESINSIGHT_VERSION_TEXT
|
||||
# Format of text must be ".xx"
|
||||
set(RESINSIGHT_DEV_VERSION ".02")
|
||||
set(RESINSIGHT_DEV_VERSION ".11")
|
||||
|
||||
# https://github.com/CRAVA/crava/tree/master/libs/nrlib
|
||||
set(NRLIB_GITHUB_SHA "ba35d4359882f1c6f5e9dc30eb95fe52af50fd6f")
|
||||
|
Loading…
Reference in New Issue
Block a user