mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Bubble plot (#5452)
Bubble plot issues #5209 #2285 #5308 Co-authored-by: Kristian Bendiksen <kristian.bendiksen@gmail.com>
This commit is contained in:
@@ -34,6 +34,7 @@
|
|||||||
#include "RimOilField.h"
|
#include "RimOilField.h"
|
||||||
#include "RimProject.h"
|
#include "RimProject.h"
|
||||||
#include "RimSimWellInView.h"
|
#include "RimSimWellInView.h"
|
||||||
|
#include "RimSimWellInViewTools.h"
|
||||||
#include "RimSummaryCaseMainCollection.h"
|
#include "RimSummaryCaseMainCollection.h"
|
||||||
#include "RimSummaryCurve.h"
|
#include "RimSummaryCurve.h"
|
||||||
#include "RimSummaryCurveAppearanceCalculator.h"
|
#include "RimSummaryCurveAppearanceCalculator.h"
|
||||||
@@ -58,7 +59,7 @@ bool RicPlotProductionRateFeature::isCommandEnabled()
|
|||||||
|
|
||||||
for ( RimSimWellInView* well : collection )
|
for ( RimSimWellInView* well : collection )
|
||||||
{
|
{
|
||||||
RimGridSummaryCase* gridSummaryCase = RicPlotProductionRateFeature::gridSummaryCaseForWell( well );
|
RimGridSummaryCase* gridSummaryCase = RimSimWellInViewTools::gridSummaryCaseForWell( well );
|
||||||
if ( gridSummaryCase )
|
if ( gridSummaryCase )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -90,12 +91,12 @@ void RicPlotProductionRateFeature::onActionTriggered( bool isChecked )
|
|||||||
|
|
||||||
for ( RimSimWellInView* well : collection )
|
for ( RimSimWellInView* well : collection )
|
||||||
{
|
{
|
||||||
RimGridSummaryCase* gridSummaryCase = RicPlotProductionRateFeature::gridSummaryCaseForWell( well );
|
RimGridSummaryCase* gridSummaryCase = RimSimWellInViewTools::gridSummaryCaseForWell( well );
|
||||||
if ( !gridSummaryCase ) continue;
|
if ( !gridSummaryCase ) continue;
|
||||||
|
|
||||||
QString description = "Well Production Rates : ";
|
QString description = "Well Production Rates : ";
|
||||||
|
|
||||||
if ( isInjector( well ) )
|
if ( RimSimWellInViewTools::isInjector( well ) )
|
||||||
{
|
{
|
||||||
description = "Well Injection Rates : ";
|
description = "Well Injection Rates : ";
|
||||||
}
|
}
|
||||||
@@ -103,7 +104,7 @@ void RicPlotProductionRateFeature::onActionTriggered( bool isChecked )
|
|||||||
description += well->name();
|
description += well->name();
|
||||||
RimSummaryPlot* plot = summaryPlotColl->createNamedSummaryPlot( description );
|
RimSummaryPlot* plot = summaryPlotColl->createNamedSummaryPlot( description );
|
||||||
|
|
||||||
if ( isInjector( well ) )
|
if ( RimSimWellInViewTools::isInjector( well ) )
|
||||||
{
|
{
|
||||||
// Left Axis
|
// Left Axis
|
||||||
|
|
||||||
@@ -239,63 +240,6 @@ void RicPlotProductionRateFeature::setupActionLook( QAction* actionToSetup )
|
|||||||
actionToSetup->setText( "Plot Production Rates" );
|
actionToSetup->setText( "Plot Production Rates" );
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
RimGridSummaryCase* RicPlotProductionRateFeature::gridSummaryCaseForWell( RimSimWellInView* well )
|
|
||||||
{
|
|
||||||
RimProject* project = RiaApplication::instance()->project();
|
|
||||||
if ( !project ) return nullptr;
|
|
||||||
|
|
||||||
RimSummaryCaseMainCollection* sumCaseColl = project->activeOilField()
|
|
||||||
? project->activeOilField()->summaryCaseMainCollection()
|
|
||||||
: nullptr;
|
|
||||||
if ( !sumCaseColl ) return nullptr;
|
|
||||||
|
|
||||||
RimEclipseResultCase* eclCase = nullptr;
|
|
||||||
well->firstAncestorOrThisOfType( eclCase );
|
|
||||||
if ( eclCase )
|
|
||||||
{
|
|
||||||
RimGridSummaryCase* gridSummaryCase = dynamic_cast<RimGridSummaryCase*>(
|
|
||||||
sumCaseColl->findSummaryCaseFromEclipseResultCase( eclCase ) );
|
|
||||||
if ( gridSummaryCase )
|
|
||||||
{
|
|
||||||
return gridSummaryCase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
bool RicPlotProductionRateFeature::isInjector( RimSimWellInView* well )
|
|
||||||
{
|
|
||||||
RigSimWellData* wRes = well->simWellData();
|
|
||||||
if ( wRes )
|
|
||||||
{
|
|
||||||
Rim3dView* rimView = nullptr;
|
|
||||||
well->firstAncestorOrThisOfTypeAsserted( rimView );
|
|
||||||
|
|
||||||
int currentTimeStep = rimView->currentTimeStep();
|
|
||||||
|
|
||||||
if ( wRes->hasWellResult( currentTimeStep ) )
|
|
||||||
{
|
|
||||||
const RigWellResultFrame& wrf = wRes->wellResultFrame( currentTimeStep );
|
|
||||||
|
|
||||||
if ( wrf.m_productionType == RigWellResultFrame::OIL_INJECTOR ||
|
|
||||||
wrf.m_productionType == RigWellResultFrame::GAS_INJECTOR ||
|
|
||||||
wrf.m_productionType == RigWellResultFrame::WATER_INJECTOR )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RivPolylinesAnnotationSourceInfo.h
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RivPolylineGenerator.h
|
${CMAKE_CURRENT_LIST_DIR}/RivPolylineGenerator.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RivMeasurementPartMgr.h
|
${CMAKE_CURRENT_LIST_DIR}/RivMeasurementPartMgr.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RivTextLabelSourceInfo.h
|
${CMAKE_CURRENT_LIST_DIR}/RivTextLabelSourceInfo.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RivDiskGeometryGenerator.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RivWellDiskPartMgr.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set (SOURCE_GROUP_SOURCE_FILES
|
set (SOURCE_GROUP_SOURCE_FILES
|
||||||
@@ -108,6 +110,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RivPolylinesAnnotationSourceInfo.cpp
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RivPolylineGenerator.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RivPolylineGenerator.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RivMeasurementPartMgr.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RivMeasurementPartMgr.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RivTextLabelSourceInfo.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RivTextLabelSourceInfo.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RivDiskGeometryGenerator.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RivWellDiskPartMgr.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND CODE_HEADER_FILES
|
list(APPEND CODE_HEADER_FILES
|
||||||
|
|||||||
141
ApplicationCode/ModelVisualization/RivDiskGeometryGenerator.cpp
Normal file
141
ApplicationCode/ModelVisualization/RivDiskGeometryGenerator.cpp
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019- 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 "RivDiskGeometryGenerator.h"
|
||||||
|
|
||||||
|
#include "cvfArray.h"
|
||||||
|
#include "cvfBase.h"
|
||||||
|
#include "cvfMath.h"
|
||||||
|
|
||||||
|
#include "cvfGeometryBuilder.h"
|
||||||
|
#include "cvfGeometryUtils.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RivDiskGeometryGenerator::RivDiskGeometryGenerator()
|
||||||
|
: m_relativeRadius( 0.085f )
|
||||||
|
, m_relativeLength( 0.25f )
|
||||||
|
, m_numSlices( 20 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RivDiskGeometryGenerator::setRelativeRadius( float relativeRadius )
|
||||||
|
{
|
||||||
|
m_relativeRadius = relativeRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RivDiskGeometryGenerator::setRelativeLength( float relativeLength )
|
||||||
|
{
|
||||||
|
m_relativeLength = relativeLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RivDiskGeometryGenerator::setNumSlices( unsigned int numSlices )
|
||||||
|
{
|
||||||
|
m_numSlices = numSlices;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
/// Create a disc centered at origin with its normal along positive z-axis
|
||||||
|
///
|
||||||
|
/// \param radius Outer radius of the disc
|
||||||
|
/// \param numSlices The number of subdivisions around the z-axis. Must be >= 4
|
||||||
|
/// \param builder Geometry builder to use when creating geometry
|
||||||
|
///
|
||||||
|
/// Creates a disc on the z = 0 plane, centered at origin and with its surface normal pointing
|
||||||
|
/// along the positive z-axis.
|
||||||
|
///
|
||||||
|
/// The disk is subdivided around the z axis into numSlices (as in pizza slices).
|
||||||
|
///
|
||||||
|
/// Each slice is a triangle which does not share any vertices with other slices. This
|
||||||
|
/// is the main different between cvf::GeometryUtils::createDisc. This method generates 3x
|
||||||
|
/// more vertices, but the result is easier to use if you need to color each slice separately.
|
||||||
|
///
|
||||||
|
/// The sourceNodes that will be produced by this method:
|
||||||
|
///
|
||||||
|
/// The following triangle connectivities will be produced:
|
||||||
|
/// (0,1,2) (3,4,5) (6,7,8) ...
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void createDisc( double radius, size_t numSlices, cvf::GeometryBuilder* builder )
|
||||||
|
{
|
||||||
|
CVF_ASSERT( numSlices >= 4 );
|
||||||
|
CVF_ASSERT( builder );
|
||||||
|
|
||||||
|
double da = 2 * cvf::PI_D / numSlices;
|
||||||
|
|
||||||
|
// Find the start point on the circle for each slice
|
||||||
|
cvf::Vec3fArray points;
|
||||||
|
points.reserve( numSlices );
|
||||||
|
for ( size_t i = 0; i < numSlices; i++ )
|
||||||
|
{
|
||||||
|
// Precompute this one (A = i*da;)
|
||||||
|
double sinA = cvf::Math::sin( i * da );
|
||||||
|
double cosA = cvf::Math::cos( i * da );
|
||||||
|
|
||||||
|
cvf::Vec3f point = cvf::Vec3f::ZERO;
|
||||||
|
point.x() = static_cast<float>( -sinA * radius );
|
||||||
|
point.y() = static_cast<float>( cosA * radius );
|
||||||
|
points.add( point );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create independent vertices per slice
|
||||||
|
cvf::Vec3fArray verts;
|
||||||
|
verts.reserve( numSlices * 3 );
|
||||||
|
for ( size_t i = 0; i < numSlices; i++ )
|
||||||
|
{
|
||||||
|
verts.add( cvf::Vec3f::ZERO );
|
||||||
|
verts.add( points[i] );
|
||||||
|
if ( i == numSlices - 1 )
|
||||||
|
{
|
||||||
|
// Last slice complete the circle.
|
||||||
|
verts.add( points[0] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
verts.add( points[i + 1] );
|
||||||
|
}
|
||||||
|
|
||||||
|
cvf::uint baseNodeIdx = builder->addVertices( verts );
|
||||||
|
|
||||||
|
// Build the triangles for each slice
|
||||||
|
for ( cvf::uint i = 0; i < static_cast<cvf::uint>( numSlices ); i++ )
|
||||||
|
{
|
||||||
|
cvf::uint v1 = baseNodeIdx + ( i * 3 ) + 0;
|
||||||
|
cvf::uint v2 = baseNodeIdx + ( i * 3 ) + 1;
|
||||||
|
cvf::uint v3 = baseNodeIdx + ( i * 3 ) + 2;
|
||||||
|
|
||||||
|
builder->addTriangle( v1, v2, v3 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RivDiskGeometryGenerator::generate( cvf::GeometryBuilder* builder )
|
||||||
|
{
|
||||||
|
const unsigned int numPolysZDir = 1;
|
||||||
|
createDisc( m_relativeRadius, m_numSlices, builder );
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019- 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
|
||||||
|
|
||||||
|
namespace cvf
|
||||||
|
{
|
||||||
|
class GeometryBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RivDiskGeometryGenerator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RivDiskGeometryGenerator();
|
||||||
|
|
||||||
|
void setRelativeRadius( float relativeRadius );
|
||||||
|
void setRelativeLength( float relativeLength );
|
||||||
|
|
||||||
|
void setNumSlices( unsigned int numSlices );
|
||||||
|
|
||||||
|
void generate( cvf::GeometryBuilder* builder );
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m_relativeRadius;
|
||||||
|
float m_relativeLength;
|
||||||
|
|
||||||
|
unsigned int m_numSlices;
|
||||||
|
};
|
||||||
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "RivSimWellPipesPartMgr.h"
|
#include "RivSimWellPipesPartMgr.h"
|
||||||
#include "RivWellConnectionsPartMgr.h"
|
#include "RivWellConnectionsPartMgr.h"
|
||||||
|
#include "RivWellDiskPartMgr.h"
|
||||||
#include "RivWellHeadPartMgr.h"
|
#include "RivWellHeadPartMgr.h"
|
||||||
#include "RivWellSpheresPartMgr.h"
|
#include "RivWellSpheresPartMgr.h"
|
||||||
|
|
||||||
@@ -63,6 +64,7 @@ void RivReservoirSimWellsPartMgr::clearGeometryCache()
|
|||||||
m_wellPipesPartMgrs.clear();
|
m_wellPipesPartMgrs.clear();
|
||||||
m_wellHeadPartMgrs.clear();
|
m_wellHeadPartMgrs.clear();
|
||||||
m_wellSpheresPartMgrs.clear();
|
m_wellSpheresPartMgrs.clear();
|
||||||
|
m_wellDiskPartMgrs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@@ -112,6 +114,25 @@ void RivReservoirSimWellsPartMgr::appendDynamicGeometryPartsToModel( cvf::ModelB
|
|||||||
m_reservoirView->displayCoordTransform().p() );
|
m_reservoirView->displayCoordTransform().p() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Well disks
|
||||||
|
if ( m_reservoirView->wellCollection()->wells.size() != m_wellDiskPartMgrs.size() )
|
||||||
|
{
|
||||||
|
clearGeometryCache();
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < m_reservoirView->wellCollection()->wells.size(); ++i )
|
||||||
|
{
|
||||||
|
RivWellDiskPartMgr* wellDiskMgr = new RivWellDiskPartMgr( m_reservoirView->wellCollection()->wells[i] );
|
||||||
|
m_wellDiskPartMgrs.push_back( wellDiskMgr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( size_t wIdx = 0; wIdx != m_wellDiskPartMgrs.size(); ++wIdx )
|
||||||
|
{
|
||||||
|
m_wellDiskPartMgrs[wIdx]->appendDynamicGeometryPartsToModel( model,
|
||||||
|
frameIndex,
|
||||||
|
m_reservoirView->displayCoordTransform().p() );
|
||||||
|
}
|
||||||
|
|
||||||
// Well spheres
|
// Well spheres
|
||||||
|
|
||||||
if ( m_reservoirView->wellCollection()->wells.size() != m_wellSpheresPartMgrs.size() )
|
if ( m_reservoirView->wellCollection()->wells.size() != m_wellSpheresPartMgrs.size() )
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class RimEclipseView;
|
|||||||
class RivSimWellPipesPartMgr;
|
class RivSimWellPipesPartMgr;
|
||||||
class RivWellHeadPartMgr;
|
class RivWellHeadPartMgr;
|
||||||
class RivWellSpheresPartMgr;
|
class RivWellSpheresPartMgr;
|
||||||
|
class RivWellDiskPartMgr;
|
||||||
class RivWellConnectionsPartMgr;
|
class RivWellConnectionsPartMgr;
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@@ -59,5 +60,6 @@ private:
|
|||||||
cvf::Collection<RivSimWellPipesPartMgr> m_wellPipesPartMgrs;
|
cvf::Collection<RivSimWellPipesPartMgr> m_wellPipesPartMgrs;
|
||||||
cvf::Collection<RivWellHeadPartMgr> m_wellHeadPartMgrs;
|
cvf::Collection<RivWellHeadPartMgr> m_wellHeadPartMgrs;
|
||||||
cvf::Collection<RivWellSpheresPartMgr> m_wellSpheresPartMgrs;
|
cvf::Collection<RivWellSpheresPartMgr> m_wellSpheresPartMgrs;
|
||||||
|
cvf::Collection<RivWellDiskPartMgr> m_wellDiskPartMgrs;
|
||||||
cvf::Collection<RivWellConnectionsPartMgr> m_wellConnPartMgrs;
|
cvf::Collection<RivWellConnectionsPartMgr> m_wellConnPartMgrs;
|
||||||
};
|
};
|
||||||
|
|||||||
568
ApplicationCode/ModelVisualization/RivWellDiskPartMgr.cpp
Normal file
568
ApplicationCode/ModelVisualization/RivWellDiskPartMgr.cpp
Normal file
@@ -0,0 +1,568 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019- 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 "RivWellDiskPartMgr.h"
|
||||||
|
|
||||||
|
#include "RiaColorTools.h"
|
||||||
|
#include "RiaGuiApplication.h"
|
||||||
|
|
||||||
|
#include "RigActiveCellInfo.h"
|
||||||
|
#include "RigCell.h"
|
||||||
|
#include "RigSimWellData.h"
|
||||||
|
|
||||||
|
#include "RimEclipseCase.h"
|
||||||
|
#include "RimEclipseView.h"
|
||||||
|
#include "RimSimWellInView.h"
|
||||||
|
#include "RimSimWellInViewCollection.h"
|
||||||
|
|
||||||
|
#include "RivDiskGeometryGenerator.h"
|
||||||
|
#include "RivPartPriority.h"
|
||||||
|
#include "RivSectionFlattner.h"
|
||||||
|
#include "RivSimWellPipeSourceInfo.h"
|
||||||
|
#include "RivTextLabelSourceInfo.h"
|
||||||
|
|
||||||
|
#include "cafDisplayCoordTransform.h"
|
||||||
|
#include "cafEffectGenerator.h"
|
||||||
|
|
||||||
|
#include "cvfDrawableGeo.h"
|
||||||
|
#include "cvfDrawableText.h"
|
||||||
|
#include "cvfEffect.h"
|
||||||
|
#include "cvfGeometryBuilderDrawableGeo.h"
|
||||||
|
#include "cvfGeometryBuilderFaceList.h"
|
||||||
|
#include "cvfGeometryBuilderTriangles.h"
|
||||||
|
#include "cvfGeometryUtils.h"
|
||||||
|
#include "cvfModelBasicList.h"
|
||||||
|
#include "cvfPart.h"
|
||||||
|
#include "cvfRenderState_FF.h"
|
||||||
|
#include "cvfShaderProgram.h"
|
||||||
|
#include "cvfShaderProgramGenerator.h"
|
||||||
|
#include "cvfShaderSourceProvider.h"
|
||||||
|
#include "cvfShaderSourceRepository.h"
|
||||||
|
#include "cvfTransform.h"
|
||||||
|
#include "cvfUniform.h"
|
||||||
|
#include "cvfqtUtils.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RivWellDiskPartMgr::RivWellDiskPartMgr( RimSimWellInView* well )
|
||||||
|
: m_rimWell( well )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RivWellDiskPartMgr::~RivWellDiskPartMgr() {}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RivWellDiskPartMgr::buildWellDiskParts( size_t frameIndex, const caf::DisplayCoordTransform* displayXf )
|
||||||
|
{
|
||||||
|
clearAllGeometry();
|
||||||
|
|
||||||
|
if ( !viewWithSettings() ) return;
|
||||||
|
|
||||||
|
RimSimWellInView* well = m_rimWell;
|
||||||
|
|
||||||
|
double characteristicCellSize = viewWithSettings()->ownerCase()->characteristicCellSize();
|
||||||
|
|
||||||
|
cvf::Vec3d whEndPos;
|
||||||
|
cvf::Vec3d whStartPos;
|
||||||
|
{
|
||||||
|
well->wellHeadTopBottomPosition( static_cast<int>( frameIndex ), &whEndPos, &whStartPos );
|
||||||
|
|
||||||
|
whEndPos = displayXf->transformToDisplayCoord( whEndPos );
|
||||||
|
whEndPos.z() += characteristicCellSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !well->simWellData()->hasWellResult( frameIndex ) ) return;
|
||||||
|
|
||||||
|
auto productionType = well->simWellData()->wellResultFrame( frameIndex ).m_productionType;
|
||||||
|
|
||||||
|
double pipeRadius = m_rimWell->pipeRadius();
|
||||||
|
unsigned int numSectors = 100;
|
||||||
|
|
||||||
|
// Upper part of simulation well pipe is defined to use branch index 0
|
||||||
|
cvf::ref<RivSimWellPipeSourceInfo> sourceInfo = new RivSimWellPipeSourceInfo( m_rimWell, 0 );
|
||||||
|
|
||||||
|
// Well disk geometry
|
||||||
|
double arrowLength = characteristicCellSize * simWellInViewCollection()->wellHeadScaleFactor() *
|
||||||
|
m_rimWell->wellHeadScaleFactor();
|
||||||
|
|
||||||
|
cvf::Vec3d diskPosition = whEndPos;
|
||||||
|
diskPosition.z() += pipeRadius + arrowLength * 2.0;
|
||||||
|
|
||||||
|
cvf::Vec3d textPosition = diskPosition;
|
||||||
|
textPosition.z() += 0.1;
|
||||||
|
|
||||||
|
double ijScaleFactor = arrowLength / 6;
|
||||||
|
|
||||||
|
cvf::ref<cvf::DrawableGeo> geo1 = new cvf::DrawableGeo;
|
||||||
|
{
|
||||||
|
cvf::Mat4f matr;
|
||||||
|
|
||||||
|
matr( 0, 0 ) *= ijScaleFactor;
|
||||||
|
matr( 1, 1 ) *= ijScaleFactor;
|
||||||
|
matr( 2, 2 ) *= ijScaleFactor;
|
||||||
|
|
||||||
|
matr.setTranslation( cvf::Vec3f( diskPosition ) );
|
||||||
|
|
||||||
|
cvf::GeometryBuilderFaceList builder;
|
||||||
|
{
|
||||||
|
RivDiskGeometryGenerator gen;
|
||||||
|
gen.setRelativeRadius( 2.5f * ( m_rimWell->diskScale() ) );
|
||||||
|
gen.setRelativeLength( 0.1f );
|
||||||
|
gen.setNumSlices( numSectors );
|
||||||
|
gen.generate( &builder );
|
||||||
|
}
|
||||||
|
|
||||||
|
cvf::ref<cvf::Vec3fArray> vertices = builder.vertices();
|
||||||
|
cvf::ref<cvf::UIntArray> faceList = builder.faceList();
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < vertices->size(); i++ )
|
||||||
|
{
|
||||||
|
cvf::Vec3f v = vertices->get( i );
|
||||||
|
v.transformPoint( matr );
|
||||||
|
vertices->set( i, v );
|
||||||
|
}
|
||||||
|
|
||||||
|
geo1->setVertexArray( vertices.p() );
|
||||||
|
geo1->setFromFaceList( *faceList );
|
||||||
|
geo1->computeNormals();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the fixed function effect
|
||||||
|
{
|
||||||
|
m_fixedFuncEffect = new cvf::Effect;
|
||||||
|
|
||||||
|
cvf::ref<cvf::RenderStateMaterial_FF> mat = new cvf::RenderStateMaterial_FF( cvf::Color3::BLUE );
|
||||||
|
mat->enableColorMaterial( true );
|
||||||
|
m_fixedFuncEffect->setRenderState( mat.p() );
|
||||||
|
|
||||||
|
cvf::ref<cvf::RenderStateLighting_FF> lighting = new cvf::RenderStateLighting_FF;
|
||||||
|
m_fixedFuncEffect->setRenderState( lighting.p() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create effect with shader program
|
||||||
|
{
|
||||||
|
m_shaderEffect = new cvf::Effect;
|
||||||
|
|
||||||
|
cvf::ShaderProgramGenerator gen( "PerVertexColor", cvf::ShaderSourceProvider::instance() );
|
||||||
|
gen.addVertexCode( cvf::ShaderSourceRepository::vs_Standard );
|
||||||
|
|
||||||
|
gen.addFragmentCode( cvf::ShaderSourceRepository::src_VaryingColorGlobalAlpha );
|
||||||
|
gen.addFragmentCode( cvf::ShaderSourceRepository::fs_Unlit );
|
||||||
|
m_shaderProg = gen.generate();
|
||||||
|
|
||||||
|
m_shaderProg->setDefaultUniform( new cvf::UniformFloat( "u_alpha", 1.0f ) );
|
||||||
|
|
||||||
|
m_shaderEffect->setShaderProgram( m_shaderProg.p() );
|
||||||
|
}
|
||||||
|
|
||||||
|
cvf::ref<cvf::Effect> effectToUse = RiaGuiApplication::instance()->useShaders() ? m_shaderEffect : m_fixedFuncEffect;
|
||||||
|
|
||||||
|
const cvf::Color3ub colorTable[] = {cvf::Color3ub( cvf::Color3::DARK_GREEN ),
|
||||||
|
cvf::Color3ub( cvf::Color3::DARK_RED ),
|
||||||
|
cvf::Color3ub( cvf::Color3::DARK_BLUE )};
|
||||||
|
|
||||||
|
size_t vertexCount = geo1->vertexCount();
|
||||||
|
cvf::ref<cvf::Color3ubArray> colorArray = new cvf::Color3ubArray;
|
||||||
|
colorArray->resize( vertexCount );
|
||||||
|
colorArray->setAll( cvf::Color3::WHITE );
|
||||||
|
CVF_ASSERT( vertexCount == numSectors * 3 );
|
||||||
|
|
||||||
|
std::vector<std::pair<cvf::String, cvf::Vec3f>> labelsWithPosition;
|
||||||
|
|
||||||
|
int numberPrecision = 2;
|
||||||
|
|
||||||
|
double accumulatedPropertyValue = 0.0;
|
||||||
|
|
||||||
|
QString labelText = m_rimWell->name();
|
||||||
|
RigWellDiskData diskData = m_rimWell->wellDiskData();
|
||||||
|
if ( diskData.isSingleProperty() )
|
||||||
|
{
|
||||||
|
// Set color for the triangle vertices
|
||||||
|
for ( size_t i = 0; i < numSectors * 3; i++ )
|
||||||
|
{
|
||||||
|
cvf::Color3ub c = cvf::Color3::OLIVE;
|
||||||
|
colorArray->set( i, c );
|
||||||
|
}
|
||||||
|
|
||||||
|
accumulatedPropertyValue = diskData.singlePropertyValue();
|
||||||
|
|
||||||
|
if ( simWellInViewCollection()->showWellDiskQuantityLables() )
|
||||||
|
{
|
||||||
|
const double singleProperty = diskData.singlePropertyValue();
|
||||||
|
labelText += QString( "\n%2" ).arg( singleProperty, 0, 'g', numberPrecision );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const double oil = diskData.oil();
|
||||||
|
const double gas = diskData.gas();
|
||||||
|
const double water = diskData.water();
|
||||||
|
|
||||||
|
const double total = diskData.total();
|
||||||
|
const double oilFraction = oil / total;
|
||||||
|
const double gasFraction = gas / total;
|
||||||
|
const double waterFraction = water / total;
|
||||||
|
|
||||||
|
accumulatedPropertyValue = total;
|
||||||
|
|
||||||
|
const double threshold = 1e-6;
|
||||||
|
if ( total > threshold )
|
||||||
|
{
|
||||||
|
double aggregatedFraction = 0.0;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = createTextAndLocation( oilFraction / 2.0, diskPosition, ijScaleFactor, oil, numberPrecision );
|
||||||
|
labelsWithPosition.push_back( p );
|
||||||
|
aggregatedFraction += oilFraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = createTextAndLocation( aggregatedFraction + gasFraction / 2.0,
|
||||||
|
diskPosition,
|
||||||
|
ijScaleFactor,
|
||||||
|
gas,
|
||||||
|
numberPrecision );
|
||||||
|
labelsWithPosition.push_back( p );
|
||||||
|
aggregatedFraction += gasFraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = createTextAndLocation( aggregatedFraction + waterFraction / 2.0,
|
||||||
|
diskPosition,
|
||||||
|
ijScaleFactor,
|
||||||
|
water,
|
||||||
|
numberPrecision );
|
||||||
|
|
||||||
|
labelsWithPosition.push_back( p );
|
||||||
|
aggregatedFraction += waterFraction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < numSectors; i++ )
|
||||||
|
{
|
||||||
|
int colorIdx = 0;
|
||||||
|
|
||||||
|
// Find the color for this sector
|
||||||
|
double lim = ( i + 1 ) / static_cast<double>( numSectors );
|
||||||
|
if ( lim <= oilFraction )
|
||||||
|
{
|
||||||
|
colorIdx = 0;
|
||||||
|
}
|
||||||
|
else if ( lim <= oilFraction + gasFraction )
|
||||||
|
{
|
||||||
|
colorIdx = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
colorIdx = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set color for the triangle vertices
|
||||||
|
for ( int t = 0; t < 3; t++ )
|
||||||
|
{
|
||||||
|
cvf::Color3ub c = colorTable[colorIdx];
|
||||||
|
colorArray->set( i * 3 + t, c );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
geo1->setColorArray( colorArray.p() );
|
||||||
|
|
||||||
|
double threshold = 0.1;
|
||||||
|
if ( accumulatedPropertyValue > threshold )
|
||||||
|
{
|
||||||
|
{
|
||||||
|
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||||
|
part->setName( "RivWellDiskPartMgr: disk " + cvfqt::Utils::toString( well->name() ) );
|
||||||
|
part->setDrawable( geo1.p() );
|
||||||
|
|
||||||
|
part->setEffect( effectToUse.p() );
|
||||||
|
part->setSourceInfo( sourceInfo.p() );
|
||||||
|
|
||||||
|
m_wellDiskPart = part;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add visual indicator for well type: producer or injector
|
||||||
|
if ( productionType == RigWellResultFrame::PRODUCER )
|
||||||
|
{
|
||||||
|
const uint numPolysZDir = 1;
|
||||||
|
float bottomRadius = 0.5f;
|
||||||
|
float topRadius = 0.5f;
|
||||||
|
float height = 0.1f;
|
||||||
|
float topOffsetX = 0.0f;
|
||||||
|
float topOffsetY = 0.0f;
|
||||||
|
|
||||||
|
cvf::GeometryBuilderFaceList builder;
|
||||||
|
cvf::GeometryUtils::createObliqueCylinder( bottomRadius,
|
||||||
|
topRadius,
|
||||||
|
height,
|
||||||
|
topOffsetX,
|
||||||
|
topOffsetY,
|
||||||
|
20,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
numPolysZDir,
|
||||||
|
&builder );
|
||||||
|
|
||||||
|
cvf::ref<cvf::Vec3fArray> vertices = builder.vertices();
|
||||||
|
cvf::ref<cvf::UIntArray> faceList = builder.faceList();
|
||||||
|
|
||||||
|
cvf::Mat4f matr;
|
||||||
|
matr( 0, 0 ) *= ijScaleFactor;
|
||||||
|
matr( 1, 1 ) *= ijScaleFactor;
|
||||||
|
matr( 2, 2 ) *= ijScaleFactor;
|
||||||
|
matr.setTranslation( cvf::Vec3f( diskPosition ) );
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < vertices->size(); i++ )
|
||||||
|
{
|
||||||
|
cvf::Vec3f v = vertices->get( i );
|
||||||
|
v.transformPoint( matr );
|
||||||
|
vertices->set( i, v );
|
||||||
|
}
|
||||||
|
|
||||||
|
caf::SurfaceEffectGenerator surfaceGen( cvf::Color4f( cvf::Color3::BLACK ), caf::PO_1 );
|
||||||
|
surfaceGen.enableLighting( false );
|
||||||
|
cvf::ref<cvf::Effect> eff = surfaceGen.generateCachedEffect();
|
||||||
|
|
||||||
|
cvf::ref<cvf::DrawableGeo> injectorGeo = new cvf::DrawableGeo;
|
||||||
|
injectorGeo->setVertexArray( vertices.p() );
|
||||||
|
injectorGeo->setFromFaceList( *faceList );
|
||||||
|
injectorGeo->computeNormals();
|
||||||
|
|
||||||
|
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||||
|
part->setName( "RivWellDiskPartMgr: producer " + cvfqt::Utils::toString( well->name() ) );
|
||||||
|
part->setDrawable( injectorGeo.p() );
|
||||||
|
|
||||||
|
part->setEffect( eff.p() );
|
||||||
|
part->setSourceInfo( sourceInfo.p() );
|
||||||
|
|
||||||
|
m_wellDiskInjectorPart = part;
|
||||||
|
}
|
||||||
|
else if ( productionType == RigWellResultFrame::OIL_INJECTOR ||
|
||||||
|
productionType == RigWellResultFrame::GAS_INJECTOR ||
|
||||||
|
productionType == RigWellResultFrame::WATER_INJECTOR )
|
||||||
|
{
|
||||||
|
cvf::GeometryBuilderFaceList builder;
|
||||||
|
cvf::Vec3f pos( 0.0, 0.0, 0.0 );
|
||||||
|
|
||||||
|
// Construct a cross using to "bars"
|
||||||
|
cvf::GeometryUtils::createBox( pos, 0.2f, 0.8f, 0.1f, &builder );
|
||||||
|
cvf::GeometryUtils::createBox( pos, 0.8f, 0.2f, 0.1f, &builder );
|
||||||
|
|
||||||
|
cvf::ref<cvf::Vec3fArray> vertices = builder.vertices();
|
||||||
|
cvf::ref<cvf::UIntArray> faceList = builder.faceList();
|
||||||
|
|
||||||
|
cvf::Mat4f matr;
|
||||||
|
matr( 0, 0 ) *= ijScaleFactor;
|
||||||
|
matr( 1, 1 ) *= ijScaleFactor;
|
||||||
|
matr( 2, 2 ) *= ijScaleFactor;
|
||||||
|
matr.setTranslation( cvf::Vec3f( diskPosition ) );
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < vertices->size(); i++ )
|
||||||
|
{
|
||||||
|
cvf::Vec3f v = vertices->get( i );
|
||||||
|
v.transformPoint( matr );
|
||||||
|
vertices->set( i, v );
|
||||||
|
}
|
||||||
|
|
||||||
|
cvf::Color4f injectorMarkerColor = getWellInjectionColor( productionType );
|
||||||
|
caf::SurfaceEffectGenerator surfaceGen( injectorMarkerColor, caf::PO_1 );
|
||||||
|
surfaceGen.enableLighting( false );
|
||||||
|
cvf::ref<cvf::Effect> eff = surfaceGen.generateCachedEffect();
|
||||||
|
|
||||||
|
cvf::ref<cvf::DrawableGeo> injectorGeo = new cvf::DrawableGeo;
|
||||||
|
injectorGeo->setVertexArray( vertices.p() );
|
||||||
|
injectorGeo->setFromFaceList( *faceList );
|
||||||
|
injectorGeo->computeNormals();
|
||||||
|
|
||||||
|
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||||
|
part->setName( "RivWellDiskPartMgr: injector " + cvfqt::Utils::toString( well->name() ) );
|
||||||
|
part->setDrawable( injectorGeo.p() );
|
||||||
|
|
||||||
|
part->setEffect( eff.p() );
|
||||||
|
part->setSourceInfo( sourceInfo.p() );
|
||||||
|
|
||||||
|
m_wellDiskInjectorPart = part;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showTextLabels = simWellInViewCollection()->showWellDiskQuantityLables() ||
|
||||||
|
( well->showWellLabel() && well->showWellDisks() && !well->name().isEmpty() );
|
||||||
|
|
||||||
|
if ( showTextLabels )
|
||||||
|
{
|
||||||
|
cvf::Font* font = RiaGuiApplication::instance()->defaultWellLabelFont();
|
||||||
|
|
||||||
|
cvf::ref<cvf::DrawableText> drawableText = new cvf::DrawableText;
|
||||||
|
drawableText->setFont( font );
|
||||||
|
drawableText->setCheckPosVisible( false );
|
||||||
|
drawableText->setDrawBorder( false );
|
||||||
|
|
||||||
|
drawableText->setDrawBackground( simWellInViewCollection()->showWellDiskLabelBackground() );
|
||||||
|
drawableText->setVerticalAlignment( cvf::TextDrawer::CENTER );
|
||||||
|
|
||||||
|
auto textColor = simWellInViewCollection()->wellLabelColor();
|
||||||
|
drawableText->setTextColor( textColor );
|
||||||
|
|
||||||
|
auto bgColor = RiaColorTools::contrastColor( textColor );
|
||||||
|
drawableText->setBackgroundColor( bgColor );
|
||||||
|
|
||||||
|
cvf::String cvfString = cvfqt::Utils::toString( labelText );
|
||||||
|
|
||||||
|
cvf::Vec3f textCoord( textPosition );
|
||||||
|
drawableText->addText( cvfString, textCoord );
|
||||||
|
|
||||||
|
if ( simWellInViewCollection()->showWellDiskQuantityLables() )
|
||||||
|
{
|
||||||
|
for ( const auto& t : labelsWithPosition )
|
||||||
|
{
|
||||||
|
drawableText->addText( t.first, t.second );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||||
|
part->setName( "RivWellDiskPartMgr: text " + cvfString );
|
||||||
|
part->setDrawable( drawableText.p() );
|
||||||
|
|
||||||
|
cvf::ref<cvf::Effect> eff = new cvf::Effect;
|
||||||
|
|
||||||
|
part->setEffect( eff.p() );
|
||||||
|
part->setPriority( RivPartPriority::PartType::Text );
|
||||||
|
|
||||||
|
m_wellDiskLabelPart = part;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::pair<cvf::String, cvf::Vec3f> RivWellDiskPartMgr::createTextAndLocation( const double aggregatedFraction,
|
||||||
|
cvf::Vec3d diskPosition,
|
||||||
|
double ijScaleFactor,
|
||||||
|
const double fraction,
|
||||||
|
int precision )
|
||||||
|
{
|
||||||
|
double sinA = cvf::Math::sin( aggregatedFraction * 2.0 * cvf::PI_F );
|
||||||
|
double cosA = cvf::Math::cos( aggregatedFraction * 2.0 * cvf::PI_F );
|
||||||
|
|
||||||
|
cvf::Vec3f v = cvf::Vec3f( diskPosition );
|
||||||
|
|
||||||
|
double radius = 2.5f * ( m_rimWell->diskScale() );
|
||||||
|
radius *= ijScaleFactor;
|
||||||
|
radius *= 1.1; // Put label outside the disk
|
||||||
|
|
||||||
|
v.x() = v.x() + static_cast<float>( -sinA * radius );
|
||||||
|
v.y() = v.y() + static_cast<float>( cosA * radius );
|
||||||
|
|
||||||
|
auto s = QString::number( fraction, 'g', precision );
|
||||||
|
cvf::String text = cvf::String( s.toStdString() );
|
||||||
|
|
||||||
|
auto p = std::make_pair( text, v );
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RivWellDiskPartMgr::clearAllGeometry()
|
||||||
|
{
|
||||||
|
m_wellDiskPart = nullptr;
|
||||||
|
m_wellDiskLabelPart = nullptr;
|
||||||
|
m_wellDiskInjectorPart = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RivWellDiskPartMgr::appendDynamicGeometryPartsToModel( cvf::ModelBasicList* model,
|
||||||
|
size_t frameIndex,
|
||||||
|
const caf::DisplayCoordTransform* displayXf )
|
||||||
|
{
|
||||||
|
if ( m_rimWell.isNull() ) return;
|
||||||
|
if ( !viewWithSettings() ) return;
|
||||||
|
|
||||||
|
if ( !m_rimWell->isWellPipeVisible( frameIndex ) ) return;
|
||||||
|
if ( !m_rimWell->isValidDisk() ) return;
|
||||||
|
|
||||||
|
buildWellDiskParts( frameIndex, displayXf );
|
||||||
|
|
||||||
|
if ( m_rimWell->showWellDisks() && m_wellDiskLabelPart.notNull() )
|
||||||
|
{
|
||||||
|
model->addPart( m_wellDiskLabelPart.p() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_rimWell->showWellDisks() && m_wellDiskPart.notNull() )
|
||||||
|
{
|
||||||
|
model->addPart( m_wellDiskPart.p() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_rimWell->showWellDisks() && m_wellDiskInjectorPart.notNull() )
|
||||||
|
{
|
||||||
|
model->addPart( m_wellDiskInjectorPart.p() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
Rim3dView* RivWellDiskPartMgr::viewWithSettings()
|
||||||
|
{
|
||||||
|
Rim3dView* view = nullptr;
|
||||||
|
if ( m_rimWell ) m_rimWell->firstAncestorOrThisOfType( view );
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RimSimWellInViewCollection* RivWellDiskPartMgr::simWellInViewCollection()
|
||||||
|
{
|
||||||
|
RimSimWellInViewCollection* wellCollection = nullptr;
|
||||||
|
if ( m_rimWell ) m_rimWell->firstAncestorOrThisOfType( wellCollection );
|
||||||
|
|
||||||
|
return wellCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
cvf::Color4f RivWellDiskPartMgr::getWellInjectionColor( RigWellResultFrame::WellProductionType productionType )
|
||||||
|
{
|
||||||
|
if ( productionType == RigWellResultFrame::OIL_INJECTOR )
|
||||||
|
{
|
||||||
|
return cvf::Color4f( cvf::Color3::ORANGE );
|
||||||
|
}
|
||||||
|
else if ( productionType == RigWellResultFrame::GAS_INJECTOR )
|
||||||
|
{
|
||||||
|
return cvf::Color4f( cvf::Color3::RED );
|
||||||
|
}
|
||||||
|
else if ( productionType == RigWellResultFrame::WATER_INJECTOR )
|
||||||
|
{
|
||||||
|
return cvf::Color4f( cvf::Color3::BLUE );
|
||||||
|
}
|
||||||
|
|
||||||
|
return cvf::Color4f( cvf::Color3::BLACK );
|
||||||
|
}
|
||||||
81
ApplicationCode/ModelVisualization/RivWellDiskPartMgr.h
Normal file
81
ApplicationCode/ModelVisualization/RivWellDiskPartMgr.h
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 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 "RigWellResultPoint.h"
|
||||||
|
|
||||||
|
#include "cafPdmPointer.h"
|
||||||
|
|
||||||
|
#include "cvfObject.h"
|
||||||
|
#include "cvfString.h"
|
||||||
|
|
||||||
|
namespace cvf
|
||||||
|
{
|
||||||
|
class Part;
|
||||||
|
class ModelBasicList;
|
||||||
|
class Effect;
|
||||||
|
class ShaderProgram;
|
||||||
|
class Color4f;
|
||||||
|
} // namespace cvf
|
||||||
|
|
||||||
|
namespace caf
|
||||||
|
{
|
||||||
|
class DisplayCoordTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Rim3dView;
|
||||||
|
class RimSimWellInView;
|
||||||
|
class RimSimWellInViewCollection;
|
||||||
|
|
||||||
|
class RivWellDiskPartMgr : public cvf::Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RivWellDiskPartMgr( RimSimWellInView* well );
|
||||||
|
~RivWellDiskPartMgr() override;
|
||||||
|
|
||||||
|
void appendDynamicGeometryPartsToModel( cvf::ModelBasicList* model,
|
||||||
|
size_t frameIndex,
|
||||||
|
const caf::DisplayCoordTransform* displayXf );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void buildWellDiskParts( size_t frameIndex, const caf::DisplayCoordTransform* displayXf );
|
||||||
|
|
||||||
|
std::pair<cvf::String, cvf::Vec3f> createTextAndLocation( const double aggregatedFraction,
|
||||||
|
cvf::Vec3d diskPosition,
|
||||||
|
double ijScaleFactor,
|
||||||
|
const double fraction,
|
||||||
|
int precision );
|
||||||
|
|
||||||
|
void clearAllGeometry();
|
||||||
|
Rim3dView* viewWithSettings();
|
||||||
|
RimSimWellInViewCollection* simWellInViewCollection();
|
||||||
|
|
||||||
|
static cvf::Color4f getWellInjectionColor( RigWellResultFrame::WellProductionType productionType );
|
||||||
|
|
||||||
|
private:
|
||||||
|
caf::PdmPointer<RimSimWellInView> m_rimWell;
|
||||||
|
|
||||||
|
cvf::ref<cvf::Part> m_wellDiskPart;
|
||||||
|
cvf::ref<cvf::Part> m_wellDiskLabelPart;
|
||||||
|
cvf::ref<cvf::Part> m_wellDiskInjectorPart;
|
||||||
|
|
||||||
|
cvf::ref<cvf::ShaderProgram> m_shaderProg;
|
||||||
|
cvf::ref<cvf::Effect> m_fixedFuncEffect;
|
||||||
|
cvf::ref<cvf::Effect> m_shaderEffect;
|
||||||
|
};
|
||||||
@@ -287,7 +287,9 @@ void RivWellHeadPartMgr::buildWellHeadParts( size_t f
|
|||||||
m_wellHeadArrowPart = part;
|
m_wellHeadArrowPart = part;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( well->showWellLabel() && !well->name().isEmpty() )
|
// Show labels for well heads only when well disks are disabled:
|
||||||
|
// well disk labels are prefered since they have more info.
|
||||||
|
if ( well->showWellLabel() && !well->name().isEmpty() && !well->showWellDisks() )
|
||||||
{
|
{
|
||||||
cvf::Font* font = RiaGuiApplication::instance()->defaultWellLabelFont();
|
cvf::Font* font = RiaGuiApplication::instance()->defaultWellLabelFont();
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimEclipseCellColors.h
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RimCellEdgeColors.h
|
${CMAKE_CURRENT_LIST_DIR}/RimCellEdgeColors.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimSimWellInView.h
|
${CMAKE_CURRENT_LIST_DIR}/RimSimWellInView.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimSimWellInViewCollection.h
|
${CMAKE_CURRENT_LIST_DIR}/RimSimWellInViewCollection.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RimSimWellInViewTools.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPath.h
|
${CMAKE_CURRENT_LIST_DIR}/RimWellPath.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimFileWellPath.h
|
${CMAKE_CURRENT_LIST_DIR}/RimFileWellPath.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPath.h
|
${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPath.h
|
||||||
@@ -149,6 +150,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementCurve.h
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementFilter.h
|
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementFilter.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementInViewCollection.h
|
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementInViewCollection.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementInView.h
|
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementInView.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RimWellDiskConfig.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -176,6 +178,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimEclipseCellColors.cpp
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RimCellEdgeColors.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimCellEdgeColors.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimSimWellInView.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimSimWellInView.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimSimWellInViewCollection.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimSimWellInViewCollection.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RimSimWellInViewTools.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPath.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimWellPath.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimFileWellPath.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimFileWellPath.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPath.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPath.cpp
|
||||||
@@ -302,6 +305,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementCurve.cpp
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementFilter.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementFilter.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementInViewCollection.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementInViewCollection.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementInView.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementInView.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RimWellDiskConfig.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND CODE_HEADER_FILES
|
list(APPEND CODE_HEADER_FILES
|
||||||
|
|||||||
@@ -716,6 +716,12 @@ QString Rim3dOverlayInfoConfig::resultInfoText( const HistogramData& histData,
|
|||||||
infoText += QString( "%1<br>" ).arg( diffResString );
|
infoText += QString( "%1<br>" ).arg( diffResString );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RimSimWellInViewCollection* wellCollection = eclipseView->wellCollection();
|
||||||
|
if ( wellCollection && wellCollection->isActive() && wellCollection->isWellDisksVisible() )
|
||||||
|
{
|
||||||
|
infoText += QString( "<b>Well Disk Property:</b> %1<br>" ).arg( wellCollection->wellDiskPropertyUiText() );
|
||||||
|
}
|
||||||
|
|
||||||
if ( eclipseView->cellResult()->hasDualPorFractureResult() )
|
if ( eclipseView->cellResult()->hasDualPorFractureResult() )
|
||||||
{
|
{
|
||||||
QString porosityModelText = caf::AppEnum<RiaDefines::PorosityModelType>::uiText(
|
QString porosityModelText = caf::AppEnum<RiaDefines::PorosityModelType>::uiText(
|
||||||
|
|||||||
@@ -633,6 +633,8 @@ void RimEclipseView::onUpdateDisplayModelForCurrentTimeStep()
|
|||||||
|
|
||||||
m_overlayInfoConfig()->update3DInfo();
|
m_overlayInfoConfig()->update3DInfo();
|
||||||
|
|
||||||
|
wellCollection()->updateWellDisks();
|
||||||
|
|
||||||
// Invisible Wells are marked as read only when "show wells intersecting visible cells" is enabled
|
// Invisible Wells are marked as read only when "show wells intersecting visible cells" is enabled
|
||||||
// Visibility of wells differ betweeen time steps, so trigger a rebuild of tree state items
|
// Visibility of wells differ betweeen time steps, so trigger a rebuild of tree state items
|
||||||
wellCollection()->updateConnectedEditors();
|
wellCollection()->updateConnectedEditors();
|
||||||
@@ -922,6 +924,8 @@ void RimEclipseView::onLoadDataAndUpdate()
|
|||||||
|
|
||||||
this->faultCollection()->syncronizeFaults();
|
this->faultCollection()->syncronizeFaults();
|
||||||
|
|
||||||
|
this->m_wellCollection->updateWellDisks();
|
||||||
|
|
||||||
scheduleReservoirGridGeometryRegen();
|
scheduleReservoirGridGeometryRegen();
|
||||||
m_simWellsPartManager->clearGeometryCache();
|
m_simWellsPartManager->clearGeometryCache();
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,8 @@
|
|||||||
#include "RimSimWellFracture.h"
|
#include "RimSimWellFracture.h"
|
||||||
#include "RimSimWellFractureCollection.h"
|
#include "RimSimWellFractureCollection.h"
|
||||||
#include "RimSimWellInViewCollection.h"
|
#include "RimSimWellInViewCollection.h"
|
||||||
|
#include "RimSimWellInViewTools.h"
|
||||||
|
#include "RimWellDiskConfig.h"
|
||||||
|
|
||||||
#include "RiuMainWindow.h"
|
#include "RiuMainWindow.h"
|
||||||
|
|
||||||
@@ -67,6 +69,7 @@ RimSimWellInView::RimSimWellInView()
|
|||||||
CAF_PDM_InitField( &showWellHead, "ShowWellHead", true, "Well Head", "", "", "" );
|
CAF_PDM_InitField( &showWellHead, "ShowWellHead", true, "Well Head", "", "", "" );
|
||||||
CAF_PDM_InitField( &showWellPipe, "ShowWellPipe", true, "Pipe", "", "", "" );
|
CAF_PDM_InitField( &showWellPipe, "ShowWellPipe", true, "Pipe", "", "", "" );
|
||||||
CAF_PDM_InitField( &showWellSpheres, "ShowWellSpheres", false, "Spheres", "", "", "" );
|
CAF_PDM_InitField( &showWellSpheres, "ShowWellSpheres", false, "Spheres", "", "", "" );
|
||||||
|
CAF_PDM_InitField( &showWellDisks, "ShowWellDisks", false, "Disks", "", "", "" );
|
||||||
|
|
||||||
CAF_PDM_InitField( &wellHeadScaleFactor, "WellHeadScaleFactor", 1.0, "Well Head Scale", "", "", "" );
|
CAF_PDM_InitField( &wellHeadScaleFactor, "WellHeadScaleFactor", 1.0, "Well Head Scale", "", "", "" );
|
||||||
CAF_PDM_InitField( &pipeScaleFactor, "WellPipeRadiusScale", 1.0, "Pipe Radius Scale", "", "", "" );
|
CAF_PDM_InitField( &pipeScaleFactor, "WellPipeRadiusScale", 1.0, "Pipe Radius Scale", "", "", "" );
|
||||||
@@ -113,7 +116,7 @@ void RimSimWellInView::fieldChangedByUi( const caf::PdmFieldHandle* changedField
|
|||||||
if ( reservoirView )
|
if ( reservoirView )
|
||||||
{
|
{
|
||||||
if ( &showWellLabel == changedField || &showWellHead == changedField || &showWellPipe == changedField ||
|
if ( &showWellLabel == changedField || &showWellHead == changedField || &showWellPipe == changedField ||
|
||||||
&showWellSpheres == changedField || &wellPipeColor == changedField )
|
&showWellSpheres == changedField || &showWellDisks == changedField || &wellPipeColor == changedField )
|
||||||
{
|
{
|
||||||
reservoirView->scheduleCreateDisplayModelAndRedraw();
|
reservoirView->scheduleCreateDisplayModelAndRedraw();
|
||||||
schedule2dIntersectionViewUpdate();
|
schedule2dIntersectionViewUpdate();
|
||||||
@@ -401,6 +404,7 @@ void RimSimWellInView::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderin
|
|||||||
appearanceGroup->add( &showWellHead );
|
appearanceGroup->add( &showWellHead );
|
||||||
appearanceGroup->add( &showWellPipe );
|
appearanceGroup->add( &showWellPipe );
|
||||||
appearanceGroup->add( &showWellSpheres );
|
appearanceGroup->add( &showWellSpheres );
|
||||||
|
appearanceGroup->add( &showWellDisks );
|
||||||
|
|
||||||
caf::PdmUiGroup* filterGroup = uiOrdering.addNewGroup( "Well Cells and Fence" );
|
caf::PdmUiGroup* filterGroup = uiOrdering.addNewGroup( "Well Cells and Fence" );
|
||||||
filterGroup->add( &showWellCells );
|
filterGroup->add( &showWellCells );
|
||||||
@@ -580,6 +584,14 @@ bool RimSimWellInView::isUsingCellCenterForPipe() const
|
|||||||
return ( wellColl && wellColl->wellPipeCoordType() == RimSimWellInViewCollection::WELLPIPE_CELLCENTER );
|
return ( wellColl && wellColl->wellPipeCoordType() == RimSimWellInViewCollection::WELLPIPE_CELLCENTER );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RigWellDiskData RimSimWellInView::wellDiskData() const
|
||||||
|
{
|
||||||
|
return m_wellDiskData;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@@ -613,6 +625,128 @@ size_t RimSimWellInView::resultWellIndex() const
|
|||||||
return m_resultWellIndex;
|
return m_resultWellIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RimSimWellInView::calculateInjectionProductionFractions( const RimWellDiskConfig& wellDiskConfig, bool* isOk )
|
||||||
|
{
|
||||||
|
const RimEclipseView* reservoirView = nullptr;
|
||||||
|
this->firstAncestorOrThisOfType( reservoirView );
|
||||||
|
if ( !reservoirView ) return false;
|
||||||
|
|
||||||
|
size_t timeStep = static_cast<size_t>( reservoirView->currentTimeStep() );
|
||||||
|
std::vector<QDateTime> caseTimeSteps = reservoirView->eclipseCase()->timeStepDates();
|
||||||
|
QDateTime currentDate;
|
||||||
|
if ( timeStep < caseTimeSteps.size() )
|
||||||
|
{
|
||||||
|
currentDate = caseTimeSteps[timeStep];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentDate = caseTimeSteps.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
RimGridSummaryCase* gridSummaryCase = RimSimWellInViewTools::gridSummaryCaseForWell( this );
|
||||||
|
|
||||||
|
if ( wellDiskConfig.isSingleProperty() )
|
||||||
|
{
|
||||||
|
double singleProperty = RimSimWellInViewTools::extractValueForTimeStep( gridSummaryCase,
|
||||||
|
name(),
|
||||||
|
wellDiskConfig.getSingleProperty(),
|
||||||
|
currentDate,
|
||||||
|
isOk );
|
||||||
|
if ( !( *isOk ) )
|
||||||
|
{
|
||||||
|
m_isValidDisk = false;
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_wellDiskData.setSinglePropertyValue( singleProperty );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_isInjector = RimSimWellInViewTools::gridSummaryCaseForWell( this );
|
||||||
|
|
||||||
|
double oil = RimSimWellInViewTools::extractValueForTimeStep( gridSummaryCase,
|
||||||
|
name(),
|
||||||
|
wellDiskConfig.getOilProperty(),
|
||||||
|
currentDate,
|
||||||
|
isOk );
|
||||||
|
if ( !( *isOk ) )
|
||||||
|
{
|
||||||
|
m_isValidDisk = false;
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double gas = RimSimWellInViewTools::extractValueForTimeStep( gridSummaryCase,
|
||||||
|
name(),
|
||||||
|
wellDiskConfig.getGasProperty(),
|
||||||
|
currentDate,
|
||||||
|
isOk ) /
|
||||||
|
1000.0;
|
||||||
|
if ( !( *isOk ) )
|
||||||
|
{
|
||||||
|
m_isValidDisk = false;
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double water = RimSimWellInViewTools::extractValueForTimeStep( gridSummaryCase,
|
||||||
|
name(),
|
||||||
|
wellDiskConfig.getWaterProperty(),
|
||||||
|
currentDate,
|
||||||
|
isOk );
|
||||||
|
if ( !( *isOk ) )
|
||||||
|
{
|
||||||
|
m_isValidDisk = false;
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_wellDiskData.setOilGasWater( oil, gas, water );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_isValidDisk = true;
|
||||||
|
|
||||||
|
return m_wellDiskData.total();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RimSimWellInView::scaleDisk( double minValue, double maxValue )
|
||||||
|
{
|
||||||
|
if ( m_isValidDisk )
|
||||||
|
{
|
||||||
|
m_diskScale = 1.0 + ( m_wellDiskData.total() - minValue ) / ( maxValue - minValue );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_diskScale = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RimSimWellInView::isValidDisk() const
|
||||||
|
{
|
||||||
|
return m_isValidDisk;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RimSimWellInView::diskScale() const
|
||||||
|
{
|
||||||
|
if ( m_isValidDisk )
|
||||||
|
{
|
||||||
|
return m_diskScale;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
/// Internal functions
|
/// Internal functions
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "RigWellDiskData.h"
|
||||||
|
|
||||||
#include "cafAppEnum.h"
|
#include "cafAppEnum.h"
|
||||||
#include "cafPdmChildField.h"
|
#include "cafPdmChildField.h"
|
||||||
#include "cafPdmField.h"
|
#include "cafPdmField.h"
|
||||||
@@ -38,6 +40,7 @@ struct RigWellResultPoint;
|
|||||||
|
|
||||||
class RimSimWellFractureCollection;
|
class RimSimWellFractureCollection;
|
||||||
class RigWellPath;
|
class RigWellPath;
|
||||||
|
class RimWellDiskConfig;
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
///
|
///
|
||||||
@@ -61,6 +64,10 @@ public:
|
|||||||
bool isWellSpheresVisible( size_t frameIndex ) const;
|
bool isWellSpheresVisible( size_t frameIndex ) const;
|
||||||
bool isUsingCellCenterForPipe() const;
|
bool isUsingCellCenterForPipe() const;
|
||||||
|
|
||||||
|
RigWellDiskData wellDiskData() const;
|
||||||
|
bool isValidDisk() const;
|
||||||
|
double diskScale() const;
|
||||||
|
|
||||||
caf::PdmFieldHandle* userDescriptionField() override;
|
caf::PdmFieldHandle* userDescriptionField() override;
|
||||||
caf::PdmFieldHandle* objectToggleField() override;
|
caf::PdmFieldHandle* objectToggleField() override;
|
||||||
|
|
||||||
@@ -83,6 +90,7 @@ public:
|
|||||||
caf::PdmField<bool> showWellHead;
|
caf::PdmField<bool> showWellHead;
|
||||||
caf::PdmField<bool> showWellPipe;
|
caf::PdmField<bool> showWellPipe;
|
||||||
caf::PdmField<bool> showWellSpheres;
|
caf::PdmField<bool> showWellSpheres;
|
||||||
|
caf::PdmField<bool> showWellDisks;
|
||||||
|
|
||||||
caf::PdmField<double> wellHeadScaleFactor;
|
caf::PdmField<double> wellHeadScaleFactor;
|
||||||
caf::PdmField<double> pipeScaleFactor;
|
caf::PdmField<double> pipeScaleFactor;
|
||||||
@@ -94,6 +102,9 @@ public:
|
|||||||
|
|
||||||
caf::PdmChildField<RimSimWellFractureCollection*> simwellFractureCollection;
|
caf::PdmChildField<RimSimWellFractureCollection*> simwellFractureCollection;
|
||||||
|
|
||||||
|
double calculateInjectionProductionFractions( const RimWellDiskConfig& wellDiskConfig, bool* isOk );
|
||||||
|
void scaleDisk( double minValue, double maxValue );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||||
const QVariant& oldValue,
|
const QVariant& oldValue,
|
||||||
@@ -110,4 +121,9 @@ private:
|
|||||||
private:
|
private:
|
||||||
cvf::ref<RigSimWellData> m_simWellData;
|
cvf::ref<RigSimWellData> m_simWellData;
|
||||||
size_t m_resultWellIndex;
|
size_t m_resultWellIndex;
|
||||||
|
bool m_isInjector;
|
||||||
|
|
||||||
|
RigWellDiskData m_wellDiskData;
|
||||||
|
bool m_isValidDisk;
|
||||||
|
double m_diskScale;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,19 +32,28 @@
|
|||||||
#include "RimEclipseContourMapView.h"
|
#include "RimEclipseContourMapView.h"
|
||||||
#include "RimEclipseResultCase.h"
|
#include "RimEclipseResultCase.h"
|
||||||
#include "RimEclipseView.h"
|
#include "RimEclipseView.h"
|
||||||
|
#include "RimGridSummaryCase.h"
|
||||||
#include "RimIntersectionCollection.h"
|
#include "RimIntersectionCollection.h"
|
||||||
#include "RimProject.h"
|
#include "RimProject.h"
|
||||||
#include "RimSimWellFractureCollection.h"
|
#include "RimSimWellFractureCollection.h"
|
||||||
#include "RimSimWellInView.h"
|
#include "RimSimWellInView.h"
|
||||||
|
#include "RimSimWellInViewTools.h"
|
||||||
#include "RimWellAllocationPlot.h"
|
#include "RimWellAllocationPlot.h"
|
||||||
|
#include "RimWellDiskConfig.h"
|
||||||
|
|
||||||
|
#include "RifSummaryReaderInterface.h"
|
||||||
|
|
||||||
#include "RiuMainWindow.h"
|
#include "RiuMainWindow.h"
|
||||||
|
#include "RiuSummaryQuantityNameInfoProvider.h"
|
||||||
|
|
||||||
#include "RivReservoirViewPartMgr.h"
|
#include "RivReservoirViewPartMgr.h"
|
||||||
|
|
||||||
#include "cafPdmUiCheckBoxTristateEditor.h"
|
#include "cafPdmUiCheckBoxTristateEditor.h"
|
||||||
|
#include "cafPdmUiListEditor.h"
|
||||||
#include "cafPdmUiPushButtonEditor.h"
|
#include "cafPdmUiPushButtonEditor.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace caf
|
namespace caf
|
||||||
{
|
{
|
||||||
// OBSOLETE enum
|
// OBSOLETE enum
|
||||||
@@ -117,6 +126,30 @@ void RimSimWellInViewCollection::WellPipeColorsEnum::setUp()
|
|||||||
}
|
}
|
||||||
} // namespace caf
|
} // namespace caf
|
||||||
|
|
||||||
|
namespace caf
|
||||||
|
{
|
||||||
|
template <>
|
||||||
|
void AppEnum<RimSimWellInViewCollection::WellDiskPropertyType>::setUp()
|
||||||
|
{
|
||||||
|
addItem( RimSimWellInViewCollection::PROPERTY_TYPE_PREDEFINED, " PROPERTY_TYPE_PREDEFINED", "Predefined" );
|
||||||
|
addItem( RimSimWellInViewCollection::PROPERTY_TYPE_SINGLE, "ANY_SINGLE_PROPERTY", "Single Property" );
|
||||||
|
setDefault( RimSimWellInViewCollection::PROPERTY_TYPE_PREDEFINED );
|
||||||
|
}
|
||||||
|
} // namespace caf
|
||||||
|
|
||||||
|
namespace caf
|
||||||
|
{
|
||||||
|
template <>
|
||||||
|
void AppEnum<RimSimWellInViewCollection::WellDiskPropertyConfigType>::setUp()
|
||||||
|
{
|
||||||
|
addItem( RimSimWellInViewCollection::PRODUCTION_RATES, "PRODUCTION_RATES", "Production Rates" );
|
||||||
|
addItem( RimSimWellInViewCollection::INJECTION_RATES, "INJECTION_RATES", "Injection Rates" );
|
||||||
|
addItem( RimSimWellInViewCollection::CUMULATIVE_PRODUCTION_RATES, "CUMULATIVE_PRODUCTION_RATES", "Production Total" );
|
||||||
|
addItem( RimSimWellInViewCollection::CUMULATIVE_INJECTION_RATES, "CUMULATIVE_INJECTION_RATES", "Injection Total" );
|
||||||
|
setDefault( RimSimWellInViewCollection::PRODUCTION_RATES );
|
||||||
|
}
|
||||||
|
} // namespace caf
|
||||||
|
|
||||||
CAF_PDM_SOURCE_INIT( RimSimWellInViewCollection, "Wells" );
|
CAF_PDM_SOURCE_INIT( RimSimWellInViewCollection, "Wells" );
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@@ -146,6 +179,7 @@ RimSimWellInViewCollection::RimSimWellInViewCollection()
|
|||||||
CAF_PDM_InitFieldNoDefault( &m_showWellLabel, "ShowWellLabelTristate", "Label", "", "", "" );
|
CAF_PDM_InitFieldNoDefault( &m_showWellLabel, "ShowWellLabelTristate", "Label", "", "", "" );
|
||||||
CAF_PDM_InitFieldNoDefault( &m_showWellPipe, "ShowWellPipe", "Pipe", "", "", "" );
|
CAF_PDM_InitFieldNoDefault( &m_showWellPipe, "ShowWellPipe", "Pipe", "", "", "" );
|
||||||
CAF_PDM_InitFieldNoDefault( &m_showWellSpheres, "ShowWellSpheres", "Spheres", "", "", "" );
|
CAF_PDM_InitFieldNoDefault( &m_showWellSpheres, "ShowWellSpheres", "Spheres", "", "", "" );
|
||||||
|
CAF_PDM_InitFieldNoDefault( &m_showWellDisks, "ShowWellDisks", "Disks", "", "", "" );
|
||||||
|
|
||||||
m_showWellHead.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName() );
|
m_showWellHead.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName() );
|
||||||
m_showWellHead.xmlCapability()->disableIO();
|
m_showWellHead.xmlCapability()->disableIO();
|
||||||
@@ -159,6 +193,9 @@ RimSimWellInViewCollection::RimSimWellInViewCollection()
|
|||||||
m_showWellSpheres.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName() );
|
m_showWellSpheres.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName() );
|
||||||
m_showWellSpheres.xmlCapability()->disableIO();
|
m_showWellSpheres.xmlCapability()->disableIO();
|
||||||
|
|
||||||
|
m_showWellDisks.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName() );
|
||||||
|
m_showWellDisks.xmlCapability()->disableIO();
|
||||||
|
|
||||||
// Scaling
|
// Scaling
|
||||||
CAF_PDM_InitField( &wellHeadScaleFactor, "WellHeadScale", 1.0, "Well Head Scale", "", "", "" );
|
CAF_PDM_InitField( &wellHeadScaleFactor, "WellHeadScale", 1.0, "Well Head Scale", "", "", "" );
|
||||||
CAF_PDM_InitField( &pipeScaleFactor, "WellPipeRadiusScale", 0.1, "Pipe Radius Scale ", "", "", "" );
|
CAF_PDM_InitField( &pipeScaleFactor, "WellPipeRadiusScale", 0.1, "Pipe Radius Scale ", "", "", "" );
|
||||||
@@ -220,6 +257,27 @@ RimSimWellInViewCollection::RimSimWellInViewCollection()
|
|||||||
m_showWellCellFence.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName() );
|
m_showWellCellFence.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName() );
|
||||||
m_showWellCellFence.xmlCapability()->disableIO();
|
m_showWellCellFence.xmlCapability()->disableIO();
|
||||||
|
|
||||||
|
CAF_PDM_InitField( &m_wellDiskQuantity, "WellDiskQuantity", QString( "WOPT" ), "Disk Quantity", "", "", "" );
|
||||||
|
m_wellDiskQuantity.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
|
||||||
|
m_wellDiskQuantity.uiCapability()->setAutoAddingOptionFromValue( false );
|
||||||
|
|
||||||
|
CAF_PDM_InitFieldNoDefault( &m_wellDiskPropertyType, "WellDiskPropertyType", "Property Type", "", "", "" );
|
||||||
|
CAF_PDM_InitFieldNoDefault( &m_wellDiskPropertyConfigType,
|
||||||
|
"WellDiskPropertyConfigType",
|
||||||
|
"Property Config Type",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"" );
|
||||||
|
|
||||||
|
CAF_PDM_InitField( &m_wellDiskShowQuantityLabels, "WellDiskShowQuantityLabels", true, "Show Quantity Labels", "", "", "" );
|
||||||
|
CAF_PDM_InitField( &m_wellDiskshowLabelsBackground,
|
||||||
|
"WellDiskShowLabelsBackground",
|
||||||
|
false,
|
||||||
|
"Show Label Background",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"" );
|
||||||
|
|
||||||
CAF_PDM_InitField( &obsoleteField_wellPipeVisibility,
|
CAF_PDM_InitField( &obsoleteField_wellPipeVisibility,
|
||||||
"GlobalWellPipeVisibility",
|
"GlobalWellPipeVisibility",
|
||||||
WellVisibilityEnum( PIPES_INDIVIDUALLY ),
|
WellVisibilityEnum( PIPES_INDIVIDUALLY ),
|
||||||
@@ -405,6 +463,15 @@ void RimSimWellInViewCollection::fieldChangedByUi( const caf::PdmFieldHandle* ch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( &m_showWellDisks == changedField )
|
||||||
|
{
|
||||||
|
for ( RimSimWellInView* w : wells )
|
||||||
|
{
|
||||||
|
w->showWellDisks = !( m_showWellDisks().isFalse() );
|
||||||
|
w->updateConnectedEditors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( &m_showWellCells == changedField )
|
if ( &m_showWellCells == changedField )
|
||||||
{
|
{
|
||||||
for ( RimSimWellInView* w : wells )
|
for ( RimSimWellInView* w : wells )
|
||||||
@@ -435,8 +502,16 @@ void RimSimWellInViewCollection::fieldChangedByUi( const caf::PdmFieldHandle* ch
|
|||||||
{
|
{
|
||||||
m_reservoirView->scheduleCreateDisplayModelAndRedraw();
|
m_reservoirView->scheduleCreateDisplayModelAndRedraw();
|
||||||
}
|
}
|
||||||
|
else if ( &m_wellDiskQuantity == changedField || &m_wellDiskPropertyType == changedField ||
|
||||||
|
&m_wellDiskPropertyConfigType == changedField || &m_wellDiskshowLabelsBackground == changedField ||
|
||||||
|
&m_wellDiskShowQuantityLabels == changedField )
|
||||||
|
{
|
||||||
|
RimWellDiskConfig wellDiskConfig = getActiveWellDiskConfig();
|
||||||
|
updateWellDisks( wellDiskConfig );
|
||||||
|
m_reservoirView->updateDisplayModelForCurrentTimeStepAndRedraw();
|
||||||
|
}
|
||||||
else if ( &spheresScaleFactor == changedField || &m_showWellSpheres == changedField ||
|
else if ( &spheresScaleFactor == changedField || &m_showWellSpheres == changedField ||
|
||||||
&showConnectionStatusColors == changedField )
|
&m_showWellDisks == changedField || &showConnectionStatusColors == changedField )
|
||||||
{
|
{
|
||||||
m_reservoirView->scheduleSimWellGeometryRegen();
|
m_reservoirView->scheduleSimWellGeometryRegen();
|
||||||
m_reservoirView->scheduleCreateDisplayModelAndRedraw();
|
m_reservoirView->scheduleCreateDisplayModelAndRedraw();
|
||||||
@@ -505,6 +580,64 @@ void RimSimWellInViewCollection::fieldChangedByUi( const caf::PdmFieldHandle* ch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QList<caf::PdmOptionItemInfo>
|
||||||
|
RimSimWellInViewCollection::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||||
|
bool* useOptionsOnly )
|
||||||
|
{
|
||||||
|
if ( fieldNeedingOptions == &m_wellDiskQuantity )
|
||||||
|
{
|
||||||
|
QList<caf::PdmOptionItemInfo> options;
|
||||||
|
if ( !wells.empty() )
|
||||||
|
{
|
||||||
|
// Assume that the wells share the grid summary case
|
||||||
|
RimGridSummaryCase* summaryCase = RimSimWellInViewTools::gridSummaryCaseForWell( wells[0] );
|
||||||
|
|
||||||
|
std::set<std::string> summaries;
|
||||||
|
if ( summaryCase )
|
||||||
|
{
|
||||||
|
auto addresses = summaryCase->summaryReader()->allResultAddresses();
|
||||||
|
for ( auto addr : addresses )
|
||||||
|
{
|
||||||
|
if ( addr.category() == RifEclipseSummaryAddress::SUMMARY_WELL )
|
||||||
|
{
|
||||||
|
summaries.insert( addr.quantityName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( const auto& itemName : summaries )
|
||||||
|
{
|
||||||
|
QString displayName;
|
||||||
|
|
||||||
|
std::string longVectorName = RiuSummaryQuantityNameInfoProvider::instance()->longNameFromQuantityName(
|
||||||
|
itemName );
|
||||||
|
|
||||||
|
if ( longVectorName.empty() )
|
||||||
|
{
|
||||||
|
displayName = QString::fromStdString( itemName );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
displayName = QString::fromStdString( longVectorName );
|
||||||
|
displayName += QString( " (%1)" ).arg( QString::fromStdString( itemName ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
auto optionItem = caf::PdmOptionItemInfo( displayName, QString::fromStdString( itemName ) );
|
||||||
|
options.push_back( optionItem );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( useOptionsOnly ) *useOptionsOnly = true;
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QList<caf::PdmOptionItemInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@@ -567,6 +700,7 @@ void RimSimWellInViewCollection::defineUiOrdering( QString uiConfigName, caf::Pd
|
|||||||
appearanceGroup->add( &m_showWellHead );
|
appearanceGroup->add( &m_showWellHead );
|
||||||
appearanceGroup->add( &m_showWellPipe );
|
appearanceGroup->add( &m_showWellPipe );
|
||||||
appearanceGroup->add( &m_showWellSpheres );
|
appearanceGroup->add( &m_showWellSpheres );
|
||||||
|
appearanceGroup->add( &m_showWellDisks );
|
||||||
appearanceGroup->add( &m_showWellCommunicationLines );
|
appearanceGroup->add( &m_showWellCommunicationLines );
|
||||||
|
|
||||||
if ( !isContourMap )
|
if ( !isContourMap )
|
||||||
@@ -604,6 +738,19 @@ void RimSimWellInViewCollection::defineUiOrdering( QString uiConfigName, caf::Pd
|
|||||||
advancedGroup->add( &wellHeadPosition );
|
advancedGroup->add( &wellHeadPosition );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
caf::PdmUiGroup* wellDiskGroup = uiOrdering.addNewGroup( "Well Disk" );
|
||||||
|
wellDiskGroup->add( &m_wellDiskPropertyType );
|
||||||
|
if ( m_wellDiskPropertyType() == PROPERTY_TYPE_PREDEFINED )
|
||||||
|
{
|
||||||
|
wellDiskGroup->add( &m_wellDiskPropertyConfigType );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wellDiskGroup->add( &m_wellDiskQuantity );
|
||||||
|
}
|
||||||
|
wellDiskGroup->add( &m_wellDiskShowQuantityLabels );
|
||||||
|
wellDiskGroup->add( &m_wellDiskshowLabelsBackground );
|
||||||
|
|
||||||
RimEclipseResultCase* ownerCase = nullptr;
|
RimEclipseResultCase* ownerCase = nullptr;
|
||||||
firstAncestorOrThisOfType( ownerCase );
|
firstAncestorOrThisOfType( ownerCase );
|
||||||
if ( ownerCase )
|
if ( ownerCase )
|
||||||
@@ -626,6 +773,7 @@ void RimSimWellInViewCollection::updateStateForVisibilityCheckboxes()
|
|||||||
size_t showWellHeadCount = 0;
|
size_t showWellHeadCount = 0;
|
||||||
size_t showPipeCount = 0;
|
size_t showPipeCount = 0;
|
||||||
size_t showSphereCount = 0;
|
size_t showSphereCount = 0;
|
||||||
|
size_t showDiskCount = 0;
|
||||||
size_t showWellCellsCount = 0;
|
size_t showWellCellsCount = 0;
|
||||||
size_t showWellCellFenceCount = 0;
|
size_t showWellCellFenceCount = 0;
|
||||||
|
|
||||||
@@ -635,6 +783,7 @@ void RimSimWellInViewCollection::updateStateForVisibilityCheckboxes()
|
|||||||
if ( w->showWellHead() ) showWellHeadCount++;
|
if ( w->showWellHead() ) showWellHeadCount++;
|
||||||
if ( w->showWellPipe() ) showPipeCount++;
|
if ( w->showWellPipe() ) showPipeCount++;
|
||||||
if ( w->showWellSpheres() ) showSphereCount++;
|
if ( w->showWellSpheres() ) showSphereCount++;
|
||||||
|
if ( w->showWellDisks() ) showDiskCount++;
|
||||||
if ( w->showWellCells() ) showWellCellsCount++;
|
if ( w->showWellCells() ) showWellCellsCount++;
|
||||||
if ( w->showWellCellFence() ) showWellCellFenceCount++;
|
if ( w->showWellCellFence() ) showWellCellFenceCount++;
|
||||||
}
|
}
|
||||||
@@ -643,6 +792,7 @@ void RimSimWellInViewCollection::updateStateForVisibilityCheckboxes()
|
|||||||
updateStateFromEnabledChildCount( showWellHeadCount, &m_showWellHead );
|
updateStateFromEnabledChildCount( showWellHeadCount, &m_showWellHead );
|
||||||
updateStateFromEnabledChildCount( showPipeCount, &m_showWellPipe );
|
updateStateFromEnabledChildCount( showPipeCount, &m_showWellPipe );
|
||||||
updateStateFromEnabledChildCount( showSphereCount, &m_showWellSpheres );
|
updateStateFromEnabledChildCount( showSphereCount, &m_showWellSpheres );
|
||||||
|
updateStateFromEnabledChildCount( showDiskCount, &m_showWellDisks );
|
||||||
updateStateFromEnabledChildCount( showWellCellsCount, &m_showWellCells );
|
updateStateFromEnabledChildCount( showWellCellsCount, &m_showWellCells );
|
||||||
updateStateFromEnabledChildCount( showWellCellFenceCount, &m_showWellCellFence );
|
updateStateFromEnabledChildCount( showWellCellFenceCount, &m_showWellCellFence );
|
||||||
}
|
}
|
||||||
@@ -805,3 +955,119 @@ void RimSimWellInViewCollection::sortWellsByName()
|
|||||||
{
|
{
|
||||||
std::sort( wells.begin(), wells.end(), lessEclipseWell );
|
std::sort( wells.begin(), wells.end(), lessEclipseWell );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QString RimSimWellInViewCollection::wellDiskPropertyUiText() const
|
||||||
|
{
|
||||||
|
if ( m_wellDiskPropertyType() == RimSimWellInViewCollection::PROPERTY_TYPE_PREDEFINED )
|
||||||
|
{
|
||||||
|
return m_wellDiskPropertyConfigType().uiText();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_wellDiskQuantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RimSimWellInViewCollection::isWellDisksVisible() const
|
||||||
|
{
|
||||||
|
return m_showWellDisks.v().isTrue() || m_showWellDisks.v().isPartiallyTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RimSimWellInViewCollection::showWellDiskLabelBackground() const
|
||||||
|
{
|
||||||
|
return m_wellDiskshowLabelsBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RimSimWellInViewCollection::showWellDiskQuantityLables() const
|
||||||
|
{
|
||||||
|
return m_wellDiskShowQuantityLabels();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RimSimWellInViewCollection::updateWellDisks()
|
||||||
|
{
|
||||||
|
RimWellDiskConfig wellDiskConfig = getActiveWellDiskConfig();
|
||||||
|
updateWellDisks( wellDiskConfig );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RimSimWellInViewCollection::updateWellDisks( const RimWellDiskConfig& wellDiskConfig )
|
||||||
|
{
|
||||||
|
double minValue = std::numeric_limits<double>::max();
|
||||||
|
double maxValue = -minValue;
|
||||||
|
for ( RimSimWellInView* w : wells )
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
double value = w->calculateInjectionProductionFractions( wellDiskConfig, &isOk );
|
||||||
|
if ( isOk )
|
||||||
|
{
|
||||||
|
minValue = std::min( minValue, value );
|
||||||
|
maxValue = std::max( maxValue, value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( maxValue > minValue )
|
||||||
|
{
|
||||||
|
for ( RimSimWellInView* w : wells )
|
||||||
|
{
|
||||||
|
w->scaleDisk( minValue, maxValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RimWellDiskConfig RimSimWellInViewCollection::getActiveWellDiskConfig() const
|
||||||
|
{
|
||||||
|
RimWellDiskConfig wellDiskConfig;
|
||||||
|
if ( m_wellDiskPropertyType() == RimSimWellInViewCollection::PROPERTY_TYPE_PREDEFINED )
|
||||||
|
{
|
||||||
|
WellDiskPropertyConfigType configType = m_wellDiskPropertyConfigType();
|
||||||
|
|
||||||
|
if ( configType == PRODUCTION_RATES )
|
||||||
|
{
|
||||||
|
wellDiskConfig.setOilProperty( "WOPR" );
|
||||||
|
wellDiskConfig.setGasProperty( "WGPR" );
|
||||||
|
wellDiskConfig.setWaterProperty( "WWPR" );
|
||||||
|
}
|
||||||
|
else if ( configType == INJECTION_RATES )
|
||||||
|
{
|
||||||
|
wellDiskConfig.setOilProperty( "" );
|
||||||
|
wellDiskConfig.setGasProperty( "WGIR" );
|
||||||
|
wellDiskConfig.setWaterProperty( "WWIR" );
|
||||||
|
}
|
||||||
|
else if ( configType == CUMULATIVE_PRODUCTION_RATES )
|
||||||
|
{
|
||||||
|
wellDiskConfig.setOilProperty( "WOPT" );
|
||||||
|
wellDiskConfig.setGasProperty( "WGPT" );
|
||||||
|
wellDiskConfig.setWaterProperty( "WWPT" );
|
||||||
|
}
|
||||||
|
else if ( configType == CUMULATIVE_INJECTION_RATES )
|
||||||
|
{
|
||||||
|
wellDiskConfig.setOilProperty( "" );
|
||||||
|
wellDiskConfig.setGasProperty( "WGIT" );
|
||||||
|
wellDiskConfig.setWaterProperty( "WWIT" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wellDiskConfig.setSingleProperty( m_wellDiskQuantity.v().toStdString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return wellDiskConfig;
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
class RimEclipseView;
|
class RimEclipseView;
|
||||||
class RimSimWellInView;
|
class RimSimWellInView;
|
||||||
|
class RimWellDiskConfig;
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
///
|
///
|
||||||
@@ -91,6 +92,20 @@ public:
|
|||||||
WELLPIPE_COLOR_UNIFORM
|
WELLPIPE_COLOR_UNIFORM
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum WellDiskPropertyType
|
||||||
|
{
|
||||||
|
PROPERTY_TYPE_PREDEFINED,
|
||||||
|
PROPERTY_TYPE_SINGLE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WellDiskPropertyConfigType
|
||||||
|
{
|
||||||
|
PRODUCTION_RATES,
|
||||||
|
INJECTION_RATES,
|
||||||
|
CUMULATIVE_PRODUCTION_RATES,
|
||||||
|
CUMULATIVE_INJECTION_RATES
|
||||||
|
};
|
||||||
|
|
||||||
typedef caf::AppEnum<RimSimWellInViewCollection::WellPipeColors> WellPipeColorsEnum;
|
typedef caf::AppEnum<RimSimWellInViewCollection::WellPipeColors> WellPipeColorsEnum;
|
||||||
|
|
||||||
caf::PdmField<bool> isActive;
|
caf::PdmField<bool> isActive;
|
||||||
@@ -121,6 +136,11 @@ public:
|
|||||||
|
|
||||||
caf::PdmField<bool> isAutoDetectingBranches;
|
caf::PdmField<bool> isAutoDetectingBranches;
|
||||||
|
|
||||||
|
QString wellDiskPropertyUiText() const;
|
||||||
|
bool isWellDisksVisible() const;
|
||||||
|
bool showWellDiskLabelBackground() const;
|
||||||
|
bool showWellDiskQuantityLables() const;
|
||||||
|
|
||||||
caf::PdmChildArrayField<RimSimWellInView*> wells;
|
caf::PdmChildArrayField<RimSimWellInView*> wells;
|
||||||
|
|
||||||
RimSimWellInView* findWell( QString name );
|
RimSimWellInView* findWell( QString name );
|
||||||
@@ -136,6 +156,8 @@ public:
|
|||||||
|
|
||||||
static void updateWellAllocationPlots();
|
static void updateWellAllocationPlots();
|
||||||
|
|
||||||
|
void updateWellDisks();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||||
const QVariant& oldValue,
|
const QVariant& oldValue,
|
||||||
@@ -143,12 +165,17 @@ protected:
|
|||||||
|
|
||||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||||
|
|
||||||
|
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||||
|
bool* useOptionsOnly );
|
||||||
|
|
||||||
caf::PdmFieldHandle* objectToggleField() override;
|
caf::PdmFieldHandle* objectToggleField() override;
|
||||||
void initAfterRead() override;
|
void initAfterRead() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void calculateWellGeometryVisibility( size_t frameIndex );
|
void calculateWellGeometryVisibility( size_t frameIndex );
|
||||||
void updateStateFromEnabledChildCount( size_t showLabelCount, caf::PdmField<caf::Tristate>* fieldToUpdate );
|
void updateStateFromEnabledChildCount( size_t showLabelCount, caf::PdmField<caf::Tristate>* fieldToUpdate );
|
||||||
|
void updateWellDisks( const RimWellDiskConfig& wellDiskConfig );
|
||||||
|
RimWellDiskConfig getActiveWellDiskConfig() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RimEclipseView* m_reservoirView;
|
RimEclipseView* m_reservoirView;
|
||||||
@@ -162,11 +189,19 @@ private:
|
|||||||
caf::PdmField<caf::Tristate> m_showWellHead;
|
caf::PdmField<caf::Tristate> m_showWellHead;
|
||||||
caf::PdmField<caf::Tristate> m_showWellPipe;
|
caf::PdmField<caf::Tristate> m_showWellPipe;
|
||||||
caf::PdmField<caf::Tristate> m_showWellSpheres;
|
caf::PdmField<caf::Tristate> m_showWellSpheres;
|
||||||
|
caf::PdmField<caf::Tristate> m_showWellDisks;
|
||||||
caf::PdmField<caf::Tristate> m_showWellCells;
|
caf::PdmField<caf::Tristate> m_showWellCells;
|
||||||
caf::PdmField<caf::Tristate> m_showWellCellFence;
|
caf::PdmField<caf::Tristate> m_showWellCellFence;
|
||||||
|
|
||||||
caf::PdmField<bool> m_showWellCommunicationLines;
|
caf::PdmField<bool> m_showWellCommunicationLines;
|
||||||
|
|
||||||
|
// Well Discs
|
||||||
|
caf::PdmField<caf::AppEnum<WellDiskPropertyType>> m_wellDiskPropertyType;
|
||||||
|
caf::PdmField<caf::AppEnum<WellDiskPropertyConfigType>> m_wellDiskPropertyConfigType;
|
||||||
|
caf::PdmField<QString> m_wellDiskQuantity;
|
||||||
|
caf::PdmField<bool> m_wellDiskShowQuantityLabels;
|
||||||
|
caf::PdmField<bool> m_wellDiskshowLabelsBackground;
|
||||||
|
|
||||||
// Obsolete fields
|
// Obsolete fields
|
||||||
caf::PdmField<WellVisibilityEnum> obsoleteField_wellPipeVisibility;
|
caf::PdmField<WellVisibilityEnum> obsoleteField_wellPipeVisibility;
|
||||||
caf::PdmField<WellCellsRangeFilterEnum> obsoleteField_wellCellsToRangeFilterMode;
|
caf::PdmField<WellCellsRangeFilterEnum> obsoleteField_wellCellsToRangeFilterMode;
|
||||||
|
|||||||
167
ApplicationCode/ProjectDataModel/RimSimWellInViewTools.cpp
Normal file
167
ApplicationCode/ProjectDataModel/RimSimWellInViewTools.cpp
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019- 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 "RimSimWellInViewTools.h"
|
||||||
|
|
||||||
|
#include "RiaApplication.h"
|
||||||
|
#include "RiaSummaryTools.h"
|
||||||
|
#include "RiaTimeHistoryCurveResampler.h"
|
||||||
|
|
||||||
|
#include "RifEclipseSummaryAddress.h"
|
||||||
|
#include "RifSummaryReaderInterface.h"
|
||||||
|
|
||||||
|
#include "RigSimWellData.h"
|
||||||
|
|
||||||
|
#include "Rim3dView.h"
|
||||||
|
#include "RimEclipseResultCase.h"
|
||||||
|
#include "RimGridSummaryCase.h"
|
||||||
|
#include "RimOilField.h"
|
||||||
|
#include "RimProject.h"
|
||||||
|
#include "RimSimWellInView.h"
|
||||||
|
#include "RimSimWellInViewCollection.h"
|
||||||
|
#include "RimSummaryCaseMainCollection.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RimGridSummaryCase* RimSimWellInViewTools::gridSummaryCaseForWell( RimSimWellInView* well )
|
||||||
|
{
|
||||||
|
RimProject* project = RiaApplication::instance()->project();
|
||||||
|
if ( !project ) return nullptr;
|
||||||
|
|
||||||
|
RimSummaryCaseMainCollection* sumCaseColl = project->activeOilField()
|
||||||
|
? project->activeOilField()->summaryCaseMainCollection()
|
||||||
|
: nullptr;
|
||||||
|
if ( !sumCaseColl ) return nullptr;
|
||||||
|
|
||||||
|
RimEclipseResultCase* eclCase = nullptr;
|
||||||
|
well->firstAncestorOrThisOfType( eclCase );
|
||||||
|
if ( eclCase )
|
||||||
|
{
|
||||||
|
RimGridSummaryCase* gridSummaryCase = dynamic_cast<RimGridSummaryCase*>(
|
||||||
|
sumCaseColl->findSummaryCaseFromEclipseResultCase( eclCase ) );
|
||||||
|
if ( gridSummaryCase )
|
||||||
|
{
|
||||||
|
return gridSummaryCase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RimSimWellInViewTools::isInjector( RimSimWellInView* well )
|
||||||
|
{
|
||||||
|
RigSimWellData* wRes = well->simWellData();
|
||||||
|
if ( wRes )
|
||||||
|
{
|
||||||
|
Rim3dView* rimView = nullptr;
|
||||||
|
well->firstAncestorOrThisOfTypeAsserted( rimView );
|
||||||
|
|
||||||
|
int currentTimeStep = rimView->currentTimeStep();
|
||||||
|
|
||||||
|
if ( wRes->hasWellResult( currentTimeStep ) )
|
||||||
|
{
|
||||||
|
const RigWellResultFrame& wrf = wRes->wellResultFrame( currentTimeStep );
|
||||||
|
|
||||||
|
if ( wrf.m_productionType == RigWellResultFrame::OIL_INJECTOR ||
|
||||||
|
wrf.m_productionType == RigWellResultFrame::GAS_INJECTOR ||
|
||||||
|
wrf.m_productionType == RigWellResultFrame::WATER_INJECTOR )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RimSimWellInViewTools::extractValueForTimeStep( RimGridSummaryCase* gridSummaryCase,
|
||||||
|
const QString& wellName,
|
||||||
|
const std::string& vectorName,
|
||||||
|
const QDateTime& currentDate,
|
||||||
|
bool* isOk )
|
||||||
|
|
||||||
|
{
|
||||||
|
if ( vectorName.empty() )
|
||||||
|
{
|
||||||
|
*isOk = true;
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RifEclipseSummaryAddress addr( RifEclipseSummaryAddress::SUMMARY_WELL,
|
||||||
|
vectorName,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
"",
|
||||||
|
wellName.toStdString(),
|
||||||
|
-1,
|
||||||
|
"",
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
false,
|
||||||
|
-1 );
|
||||||
|
|
||||||
|
RifSummaryReaderInterface* reader = gridSummaryCase->summaryReader();
|
||||||
|
if ( !gridSummaryCase->summaryReader()->hasAddress( addr ) )
|
||||||
|
{
|
||||||
|
// TODO: better error handling
|
||||||
|
std::cerr << "ERROR: no address found for well " << wellName.toStdString() << " " << vectorName << std::endl;
|
||||||
|
*isOk = false;
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> values;
|
||||||
|
reader->values( addr, &values );
|
||||||
|
std::vector<time_t> timeSteps = reader->timeSteps( addr );
|
||||||
|
|
||||||
|
RiaTimeHistoryCurveResampler resampler;
|
||||||
|
resampler.setCurveData( values, timeSteps );
|
||||||
|
if ( RiaSummaryTools::hasAccumulatedData( addr ) )
|
||||||
|
{
|
||||||
|
resampler.resampleAndComputePeriodEndValues( DateTimePeriod::DAY );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resampler.resampleAndComputeWeightedMeanValues( DateTimePeriod::DAY );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the data point which best matches the selected time step
|
||||||
|
std::vector<time_t> resampledTimeSteps = resampler.resampledTimeSteps();
|
||||||
|
std::vector<double> resampledValues = resampler.resampledValues();
|
||||||
|
for ( unsigned int i = 0; i < resampledTimeSteps.size(); i++ )
|
||||||
|
{
|
||||||
|
QDateTime t = QDateTime::fromTime_t( resampledTimeSteps[i] );
|
||||||
|
if ( t > currentDate )
|
||||||
|
{
|
||||||
|
*isOk = true;
|
||||||
|
return resampledValues[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "ERROR: no resampled value found for well " << wellName.toStdString() << " " << vectorName << std::endl;
|
||||||
|
*isOk = false;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
44
ApplicationCode/ProjectDataModel/RimSimWellInViewTools.h
Normal file
44
ApplicationCode/ProjectDataModel/RimSimWellInViewTools.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019- 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 <string>
|
||||||
|
|
||||||
|
class QString;
|
||||||
|
class QDateTime;
|
||||||
|
|
||||||
|
class RimSimWellInView;
|
||||||
|
class RimGridSummaryCase;
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
///
|
||||||
|
///
|
||||||
|
//==================================================================================================
|
||||||
|
class RimSimWellInViewTools
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static RimGridSummaryCase* gridSummaryCaseForWell( RimSimWellInView* well );
|
||||||
|
static bool isInjector( RimSimWellInView* well );
|
||||||
|
|
||||||
|
static double extractValueForTimeStep( RimGridSummaryCase* gridSummaryCase,
|
||||||
|
const QString& wellName,
|
||||||
|
const std::string& vectorName,
|
||||||
|
const QDateTime& currentDate,
|
||||||
|
bool* isOk );
|
||||||
|
};
|
||||||
75
ApplicationCode/ProjectDataModel/RimWellDiskConfig.cpp
Normal file
75
ApplicationCode/ProjectDataModel/RimWellDiskConfig.cpp
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019- 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 "RimWellDiskConfig.h"
|
||||||
|
|
||||||
|
RimWellDiskConfig::RimWellDiskConfig()
|
||||||
|
: m_isSingleProperty( false )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RimWellDiskConfig::~RimWellDiskConfig() {}
|
||||||
|
|
||||||
|
bool RimWellDiskConfig::isSingleProperty() const
|
||||||
|
{
|
||||||
|
return m_isSingleProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RimWellDiskConfig::getSingleProperty() const
|
||||||
|
{
|
||||||
|
return m_singleProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RimWellDiskConfig::setSingleProperty( const std::string& singleProperty )
|
||||||
|
{
|
||||||
|
m_isSingleProperty = true;
|
||||||
|
m_singleProperty = singleProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RimWellDiskConfig::setOilProperty( const std::string& oilProperty )
|
||||||
|
{
|
||||||
|
m_isSingleProperty = false;
|
||||||
|
m_oilProperty = oilProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RimWellDiskConfig::getOilProperty() const
|
||||||
|
{
|
||||||
|
return m_oilProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RimWellDiskConfig::setGasProperty( const std::string& gasProperty )
|
||||||
|
{
|
||||||
|
m_isSingleProperty = false;
|
||||||
|
m_gasProperty = gasProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RimWellDiskConfig::getGasProperty() const
|
||||||
|
{
|
||||||
|
return m_gasProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RimWellDiskConfig::setWaterProperty( const std::string& waterProperty )
|
||||||
|
{
|
||||||
|
m_isSingleProperty = false;
|
||||||
|
m_waterProperty = waterProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RimWellDiskConfig::getWaterProperty() const
|
||||||
|
{
|
||||||
|
return m_waterProperty;
|
||||||
|
}
|
||||||
52
ApplicationCode/ProjectDataModel/RimWellDiskConfig.h
Normal file
52
ApplicationCode/ProjectDataModel/RimWellDiskConfig.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019- 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 <string>
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
///
|
||||||
|
///
|
||||||
|
//==================================================================================================
|
||||||
|
class RimWellDiskConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RimWellDiskConfig();
|
||||||
|
~RimWellDiskConfig();
|
||||||
|
|
||||||
|
bool isSingleProperty() const;
|
||||||
|
std::string getSingleProperty() const;
|
||||||
|
void setSingleProperty( const std::string& singleProperty );
|
||||||
|
|
||||||
|
void setOilProperty( const std::string& oilProperty );
|
||||||
|
std::string getOilProperty() const;
|
||||||
|
|
||||||
|
void setGasProperty( const std::string& gasProperty );
|
||||||
|
std::string getGasProperty() const;
|
||||||
|
|
||||||
|
void setWaterProperty( const std::string& waterProperty );
|
||||||
|
std::string getWaterProperty() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_isSingleProperty;
|
||||||
|
std::string m_singleProperty;
|
||||||
|
std::string m_oilProperty;
|
||||||
|
std::string m_gasProperty;
|
||||||
|
std::string m_waterProperty;
|
||||||
|
};
|
||||||
@@ -77,6 +77,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigWbsParameter.h
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseAllenFaultsStatCalc.h
|
${CMAKE_CURRENT_LIST_DIR}/RigEclipseAllenFaultsStatCalc.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RigCellFaceGeometryTools.h
|
${CMAKE_CURRENT_LIST_DIR}/RigCellFaceGeometryTools.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RigNncConnection.h
|
${CMAKE_CURRENT_LIST_DIR}/RigNncConnection.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RigWellDiskData.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -151,6 +152,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigWbsParameter.cpp
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseAllenFaultsStatCalc.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RigEclipseAllenFaultsStatCalc.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RigCellFaceGeometryTools.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RigCellFaceGeometryTools.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RigNncConnection.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RigNncConnection.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RigWellDiskData.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND CODE_HEADER_FILES
|
list(APPEND CODE_HEADER_FILES
|
||||||
|
|||||||
107
ApplicationCode/ReservoirDataModel/RigWellDiskData.cpp
Normal file
107
ApplicationCode/ReservoirDataModel/RigWellDiskData.cpp
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019- 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 "RigWellDiskData.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RigWellDiskData::RigWellDiskData()
|
||||||
|
: m_isSingleProperty( false )
|
||||||
|
, m_singlePropertyValue( 0.0 )
|
||||||
|
, m_oilValue( 0.0 )
|
||||||
|
, m_waterValue( 0.0 )
|
||||||
|
, m_gasValue( 0.0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RigWellDiskData::setSinglePropertyValue( double value )
|
||||||
|
{
|
||||||
|
m_isSingleProperty = true;
|
||||||
|
m_singlePropertyValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RigWellDiskData::setOilGasWater( double oil, double gas, double water )
|
||||||
|
{
|
||||||
|
m_isSingleProperty = false;
|
||||||
|
|
||||||
|
m_oilValue = oil;
|
||||||
|
m_gasValue = gas;
|
||||||
|
m_waterValue = water;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RigWellDiskData::total() const
|
||||||
|
{
|
||||||
|
if ( m_isSingleProperty )
|
||||||
|
{
|
||||||
|
return m_singlePropertyValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return m_oilValue + m_gasValue + m_waterValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RigWellDiskData::oil() const
|
||||||
|
{
|
||||||
|
return m_oilValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RigWellDiskData::gas() const
|
||||||
|
{
|
||||||
|
return m_gasValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RigWellDiskData::water() const
|
||||||
|
{
|
||||||
|
return m_waterValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RigWellDiskData::singlePropertyValue() const
|
||||||
|
{
|
||||||
|
return m_singlePropertyValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RigWellDiskData::isSingleProperty() const
|
||||||
|
{
|
||||||
|
return m_isSingleProperty;
|
||||||
|
}
|
||||||
46
ApplicationCode/ReservoirDataModel/RigWellDiskData.h
Normal file
46
ApplicationCode/ReservoirDataModel/RigWellDiskData.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019- 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
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
///
|
||||||
|
///
|
||||||
|
//==================================================================================================
|
||||||
|
class RigWellDiskData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RigWellDiskData();
|
||||||
|
|
||||||
|
void setSinglePropertyValue( double value );
|
||||||
|
void setOilGasWater( double oil, double gas, double water );
|
||||||
|
|
||||||
|
double total() const;
|
||||||
|
double oil() const;
|
||||||
|
double gas() const;
|
||||||
|
double water() const;
|
||||||
|
double singlePropertyValue() const;
|
||||||
|
bool isSingleProperty() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_isSingleProperty;
|
||||||
|
double m_singlePropertyValue;
|
||||||
|
double m_oilValue;
|
||||||
|
double m_waterValue;
|
||||||
|
double m_gasValue;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user