Merge remote-tracking branch 'refs/remotes/origin/dev'

Conflicts:
	ApplicationCode/ModelVisualization/CMakeLists_files.cmake
	ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp
This commit is contained in:
Magne Sjaastad 2017-02-20 11:07:46 +01:00
commit bdbb110ca4
20 changed files with 382 additions and 211 deletions

View File

@ -458,16 +458,6 @@ if (RESINSIGHT_PRIVATE_INSTALL)
set_target_properties (ResInsight PROPERTIES INSTALL_RPATH "${RESINSIGHT_INSTALL_RPATH}") set_target_properties (ResInsight PROPERTIES INSTALL_RPATH "${RESINSIGHT_INSTALL_RPATH}")
# Find Qt libraries and sym links
file (GLOB RESINSIGHT_FILES
${QT_LIBRARY_DIR}/libQtCore.so*
${QT_LIBRARY_DIR}/libQtGui.so*
${QT_LIBRARY_DIR}/libQtOpenGL.so*
${QT_LIBRARY_DIR}/libQtNetwork.so*
${QT_LIBRARY_DIR}/libQtScript.so*
${QT_LIBRARY_DIR}/libQtScriptTools.so*
)
endif() endif()
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")

View File

@ -36,6 +36,7 @@
#include "RimLegendConfig.h" #include "RimLegendConfig.h"
#include "RivFemPickSourceInfo.h" #include "RivFemPickSourceInfo.h"
#include "RivPartPriority.h"
#include "RivResultToTextureMapper.h" #include "RivResultToTextureMapper.h"
#include "RivScalarMapperUtils.h" #include "RivScalarMapperUtils.h"
#include "RivSourceInfo.h" #include "RivSourceInfo.h"
@ -159,8 +160,7 @@ void RivFemPartPartMgr::generatePartGeometry(RivFemPartGeometryGenerator& geoBui
caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors());
eff = effGen.generateCachedEffect(); eff = effGen.generateCachedEffect();
// Set priority to make sure fault lines are rendered first part->setPriority(RivPartPriority::PartType::MeshLines);
part->setPriority(10);
part->setEnableMask(meshSurfaceBit); part->setEnableMask(meshSurfaceBit);
part->setEffect(eff.p()); part->setEffect(eff.p());
@ -196,7 +196,7 @@ void RivFemPartPartMgr::updateCellColor(cvf::Color4f color)
if (color.a() < 1.0f) if (color.a() < 1.0f)
{ {
// Set priority to make sure this transparent geometry are rendered last // Set priority to make sure this transparent geometry are rendered last
if (m_surfaceFaces.notNull()) m_surfaceFaces->setPriority(100); if (m_surfaceFaces.notNull()) m_surfaceFaces->setPriority(RivPartPriority::PartType::Transparent);
} }
m_opacityLevel = color.a(); m_opacityLevel = color.a();

View File

@ -35,6 +35,7 @@ ${CEE_CURRENT_LIST_DIR}RivPipeQuadToSegmentMapper.h
${CEE_CURRENT_LIST_DIR}RivSingleCellPartGenerator.h ${CEE_CURRENT_LIST_DIR}RivSingleCellPartGenerator.h
${CEE_CURRENT_LIST_DIR}RivSimWellPipeSourceInfo.h ${CEE_CURRENT_LIST_DIR}RivSimWellPipeSourceInfo.h
${CEE_CURRENT_LIST_DIR}RivWellSpheresPartMgr.h ${CEE_CURRENT_LIST_DIR}RivWellSpheresPartMgr.h
${CEE_CURRENT_LIST_DIR}RivPartPriority.h
${CEE_CURRENT_LIST_DIR}RivWellFracturePartMgr.h ${CEE_CURRENT_LIST_DIR}RivWellFracturePartMgr.h
) )

View File

@ -22,6 +22,7 @@
#include "RiaApplication.h" #include "RiaApplication.h"
#include "RivPartPriority.h"
#include "RivPatchGenerator.h" #include "RivPatchGenerator.h"
#include "cafEffectGenerator.h" #include "cafEffectGenerator.h"
@ -620,7 +621,7 @@ void RivGridBoxGenerator::createLegend(EdgeType edge, cvf::Collection<cvf::Part>
depth->enableDepthTest(false); depth->enableDepthTest(false);
eff->setRenderState(depth.p()); eff->setRenderState(depth.p());
part->setPriority(1500); part->setPriority(RivPartPriority::PartType::Text);
part->setEffect(eff.p()); part->setEffect(eff.p());
parts->push_back(part.p()); parts->push_back(part.p());

View File

@ -37,6 +37,7 @@
#include "RivIntersectionBoxSourceInfo.h" #include "RivIntersectionBoxSourceInfo.h"
#include "RivIntersectionPartMgr.h" #include "RivIntersectionPartMgr.h"
#include "RivPartPriority.h"
#include "RivResultToTextureMapper.h" #include "RivResultToTextureMapper.h"
#include "RivScalarMapperUtils.h" #include "RivScalarMapperUtils.h"
#include "RivTernaryScalarMapper.h" #include "RivTernaryScalarMapper.h"
@ -213,10 +214,6 @@ void RivIntersectionBoxPartMgr::updateCellResultColor(size_t timeStepIndex)
} }
const int priCrossSectionGeo = 1;
const int priNncGeo = 2;
const int priMesh = 3;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -246,7 +243,7 @@ void RivIntersectionBoxPartMgr::generatePartGeometry()
part->updateBoundingBox(); part->updateBoundingBox();
part->setEnableMask(faultBit); part->setEnableMask(faultBit);
part->setPriority(priCrossSectionGeo); part->setPriority(RivPartPriority::PartType::Intersection);
m_intersectionBoxFaces = part; m_intersectionBoxFaces = part;
} }
@ -268,7 +265,7 @@ void RivIntersectionBoxPartMgr::generatePartGeometry()
part->updateBoundingBox(); part->updateBoundingBox();
part->setEnableMask(meshFaultBit); part->setEnableMask(meshFaultBit);
part->setPriority(priMesh); part->setPriority(RivPartPriority::PartType::MeshLines);
m_intersectionBoxGridLines = part; m_intersectionBoxGridLines = part;
} }

View File

@ -39,6 +39,7 @@
#include "RivHexGridIntersectionTools.h" #include "RivHexGridIntersectionTools.h"
#include "RivIntersectionGeometryGenerator.h" #include "RivIntersectionGeometryGenerator.h"
#include "RivIntersectionSourceInfo.h" #include "RivIntersectionSourceInfo.h"
#include "RivPartPriority.h"
#include "RivResultToTextureMapper.h" #include "RivResultToTextureMapper.h"
#include "RivScalarMapperUtils.h" #include "RivScalarMapperUtils.h"
#include "RivTernaryScalarMapper.h" #include "RivTernaryScalarMapper.h"
@ -382,10 +383,6 @@ void RivIntersectionPartMgr::calculateEclipseTextureCoordinates(cvf::Vec2fArray*
} }
} }
const int priCrossSectionGeo = 1;
const int priNncGeo = 2;
const int priMesh = 3;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -416,7 +413,7 @@ void RivIntersectionPartMgr::generatePartGeometry()
part->updateBoundingBox(); part->updateBoundingBox();
part->setEnableMask(faultBit); part->setEnableMask(faultBit);
part->setPriority(priCrossSectionGeo); part->setPriority(RivPartPriority::PartType::Intersection);
m_crossSectionFaces = part; m_crossSectionFaces = part;
} }
@ -438,7 +435,7 @@ void RivIntersectionPartMgr::generatePartGeometry()
part->updateBoundingBox(); part->updateBoundingBox();
part->setEnableMask(meshFaultBit); part->setEnableMask(meshFaultBit);
part->setPriority(priMesh); part->setPriority(RivPartPriority::PartType::MeshLines);
m_crossSectionGridLines = part; m_crossSectionGridLines = part;
} }
@ -478,7 +475,7 @@ void RivIntersectionPartMgr::createPolyLineParts(bool useBufferObjects)
part->setDrawable(polylineGeo.p()); part->setDrawable(polylineGeo.p());
part->updateBoundingBox(); part->updateBoundingBox();
part->setPriority(10000); part->setPriority(RivPartPriority::PartType::Highlight);
// Always show this part, also when mesh is turned off // Always show this part, also when mesh is turned off
//part->setEnableMask(meshFaultBit); //part->setEnableMask(meshFaultBit);
@ -510,7 +507,7 @@ void RivIntersectionPartMgr::createPolyLineParts(bool useBufferObjects)
part->setDrawable(polylinePointsGeo.p()); part->setDrawable(polylinePointsGeo.p());
part->updateBoundingBox(); part->updateBoundingBox();
part->setPriority(10000); part->setPriority(RivPartPriority::PartType::Highlight);
// Always show this part, also when mesh is turned off // Always show this part, also when mesh is turned off
//part->setEnableMask(meshFaultBit); //part->setEnableMask(meshFaultBit);
@ -558,7 +555,7 @@ void RivIntersectionPartMgr::createExtrusionDirParts(bool useBufferObjects)
part->setDrawable(polylineGeo.p()); part->setDrawable(polylineGeo.p());
part->updateBoundingBox(); part->updateBoundingBox();
part->setPriority(10000); part->setPriority(RivPartPriority::PartType::Highlight);
// Always show this part, also when mesh is turned off // Always show this part, also when mesh is turned off
//part->setEnableMask(meshFaultBit); //part->setEnableMask(meshFaultBit);
@ -590,7 +587,7 @@ void RivIntersectionPartMgr::createExtrusionDirParts(bool useBufferObjects)
part->setDrawable(polylinePointsGeo.p()); part->setDrawable(polylinePointsGeo.p());
part->updateBoundingBox(); part->updateBoundingBox();
part->setPriority(10000); part->setPriority(RivPartPriority::PartType::Highlight);
// Always show this part, also when mesh is turned off // Always show this part, also when mesh is turned off
//part->setEnableMask(meshFaultBit); //part->setEnableMask(meshFaultBit);

View File

@ -33,6 +33,7 @@
#include "RimLegendConfig.h" #include "RimLegendConfig.h"
#include "RimTernaryLegendConfig.h" #include "RimTernaryLegendConfig.h"
#include "RivPartPriority.h"
#include "RivResultToTextureMapper.h" #include "RivResultToTextureMapper.h"
#include "RivScalarMapperUtils.h" #include "RivScalarMapperUtils.h"
#include "RivSourceInfo.h" #include "RivSourceInfo.h"
@ -206,10 +207,6 @@ void RivFaultPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimEclipse
} }
} }
const int priFaultGeo = 1;
const int priNncGeo = 2;
const int priMesh = 3;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -240,7 +237,7 @@ void RivFaultPartMgr::generatePartGeometry()
part->updateBoundingBox(); part->updateBoundingBox();
part->setEnableMask(faultBit); part->setEnableMask(faultBit);
part->setPriority(priFaultGeo); part->setPriority(RivPartPriority::PartType::Fault);
m_nativeFaultFaces = part; m_nativeFaultFaces = part;
} }
@ -262,7 +259,7 @@ void RivFaultPartMgr::generatePartGeometry()
part->updateBoundingBox(); part->updateBoundingBox();
part->setEnableMask(meshFaultBit); part->setEnableMask(meshFaultBit);
part->setPriority(priMesh); part->setPriority(RivPartPriority::PartType::MeshLines);
m_nativeFaultGridLines = part; m_nativeFaultGridLines = part;
} }
@ -292,7 +289,7 @@ void RivFaultPartMgr::generatePartGeometry()
part->updateBoundingBox(); part->updateBoundingBox();
part->setEnableMask(faultBit); part->setEnableMask(faultBit);
part->setPriority(priFaultGeo); part->setPriority(RivPartPriority::PartType::Fault);
m_oppositeFaultFaces = part; m_oppositeFaultFaces = part;
} }
@ -314,7 +311,7 @@ void RivFaultPartMgr::generatePartGeometry()
part->updateBoundingBox(); part->updateBoundingBox();
part->setEnableMask(meshFaultBit); part->setEnableMask(meshFaultBit);
part->setPriority(priMesh); part->setPriority(RivPartPriority::PartType::MeshLines);
m_oppositeFaultGridLines = part; m_oppositeFaultGridLines = part;
} }
@ -342,7 +339,7 @@ void RivFaultPartMgr::generatePartGeometry()
part->updateBoundingBox(); part->updateBoundingBox();
part->setEnableMask(faultBit); part->setEnableMask(faultBit);
part->setPriority(priNncGeo); part->setPriority(RivPartPriority::PartType::Nnc);
m_NNCFaces = part; m_NNCFaces = part;
} }
@ -397,18 +394,18 @@ void RivFaultPartMgr::updatePartEffect()
if (m_opacityLevel < 1.0f) if (m_opacityLevel < 1.0f)
{ {
// Set priority to make sure this transparent geometry are rendered last // Set priority to make sure this transparent geometry are rendered last
if (m_nativeFaultFaces.notNull()) m_nativeFaultFaces->setPriority(100 + priFaultGeo); if (m_nativeFaultFaces.notNull()) m_nativeFaultFaces->setPriority(RivPartPriority::PartType::TransparentFault);
if (m_oppositeFaultFaces.notNull()) m_oppositeFaultFaces->setPriority(100 + priFaultGeo); if (m_oppositeFaultFaces.notNull()) m_oppositeFaultFaces->setPriority(RivPartPriority::PartType::TransparentFault);
if (m_NNCFaces.notNull()) m_NNCFaces->setPriority(100 + priNncGeo); if (m_NNCFaces.notNull()) m_NNCFaces->setPriority(RivPartPriority::PartType::TransparentNnc);
if (m_nativeFaultGridLines.notNull()) if (m_nativeFaultGridLines.notNull())
{ {
m_nativeFaultGridLines->setPriority(100 + priMesh); m_nativeFaultGridLines->setPriority(RivPartPriority::PartType::TransparentMeshLines);
} }
if (m_oppositeFaultGridLines.notNull()) if (m_oppositeFaultGridLines.notNull())
{ {
m_oppositeFaultGridLines->setPriority(100 + priMesh); m_oppositeFaultGridLines->setPriority(RivPartPriority::PartType::TransparentMeshLines);
} }
} }
} }
@ -481,7 +478,7 @@ void RivFaultPartMgr::createLabelWithAnchorLine(const cvf::Part* part)
cvf::ref<cvf::Effect> eff = new cvf::Effect; cvf::ref<cvf::Effect> eff = new cvf::Effect;
part->setEffect(eff.p()); part->setEffect(eff.p());
part->setPriority(1000); part->setPriority(RivPartPriority::PartType::Text);
m_faultLabelPart = part; m_faultLabelPart = part;
} }

View File

@ -37,6 +37,7 @@
#include "RimTernaryLegendConfig.h" #include "RimTernaryLegendConfig.h"
#include "RivCellEdgeEffectGenerator.h" #include "RivCellEdgeEffectGenerator.h"
#include "RivPartPriority.h"
#include "RivResultToTextureMapper.h" #include "RivResultToTextureMapper.h"
#include "RivScalarMapperUtils.h" #include "RivScalarMapperUtils.h"
#include "RivSourceInfo.h" #include "RivSourceInfo.h"
@ -164,8 +165,7 @@ void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoB
caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors());
eff = effGen.generateCachedEffect(); eff = effGen.generateCachedEffect();
// Set priority to make sure fault lines are rendered first part->setPriority(RivPartPriority::PartType::MeshLines);
part->setPriority(10);
part->setEnableMask(meshSurfaceBit); part->setEnableMask(meshSurfaceBit);
part->setEffect(eff.p()); part->setEffect(eff.p());
@ -200,8 +200,7 @@ void RivGridPartMgr::updateCellColor(cvf::Color4f color)
if (color.a() < 1.0f) if (color.a() < 1.0f)
{ {
// Set priority to make sure this transparent geometry are rendered last if (m_surfaceFaces.notNull()) m_surfaceFaces->setPriority(RivPartPriority::PartType::Transparent);
if (m_surfaceFaces.notNull()) m_surfaceFaces->setPriority(100);
} }
m_opacityLevel = color.a(); m_opacityLevel = color.a();

View File

@ -0,0 +1,51 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
//--------------------------------------------------------------------------------------------------
/// Class used to manage part render priorities
///
/// The render priority determines the order in which parts get rendered. Parts with lower priorities
/// get rendered first. The default priority is 0.
///
/// See also cvf::Part::setPriority()
///
//--------------------------------------------------------------------------------------------------
class RivPartPriority
{
public:
enum PartType
{
BaseLevel,
Fault,
Nnc,
Intersection,
CrossSectionNnc,
MeshLines,
Transparent,
TransparentFault,
TransparentNnc,
TransparentMeshLines,
Highlight,
Text
};
};

View File

@ -27,6 +27,7 @@
#include "RimGeoMechCase.h" #include "RimGeoMechCase.h"
#include "RivFemPartGeometryGenerator.h" #include "RivFemPartGeometryGenerator.h"
#include "RivPartPriority.h"
#include "cafEffectGenerator.h" #include "cafEffectGenerator.h"
#include "cvfPart.h" #include "cvfPart.h"
@ -75,7 +76,7 @@ cvf::ref<cvf::Part> RivSingleCellPartGenerator::createPart(const cvf::Color3f co
part->setEffect(eff.p()); part->setEffect(eff.p());
part->setPriority(10000); part->setPriority(RivPartPriority::PartType::Highlight);
return part; return part;
} }

View File

@ -35,6 +35,7 @@
#include "RimEclipseWellCollection.h" #include "RimEclipseWellCollection.h"
#include "RivPipeGeometryGenerator.h" #include "RivPipeGeometryGenerator.h"
#include "RivPartPriority.h"
#include "RivSimWellPipeSourceInfo.h" #include "RivSimWellPipeSourceInfo.h"
#include "cafEffectGenerator.h" #include "cafEffectGenerator.h"
@ -142,11 +143,18 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex)
whEndPos.z() = activeCellsBoundingBoxMax.z(); whEndPos.z() = activeCellsBoundingBoxMax.z();
} }
double pipeRadius = m_rimReservoirView->wellCollection()->pipeScaleFactor() * m_rimWell->pipeScaleFactor() * characteristicCellSize;
if (wellResultFrame.m_isOpen)
{
// Use slightly larger well head arrow when well is open
pipeRadius *= 1.1;
}
// Upper part of simulation well pipe is defined to use branch index 0 // Upper part of simulation well pipe is defined to use branch index 0
cvf::ref<RivSimWellPipeSourceInfo> sourceInfo = new RivSimWellPipeSourceInfo(m_rimWell, 0); cvf::ref<RivSimWellPipeSourceInfo> sourceInfo = new RivSimWellPipeSourceInfo(m_rimWell, 0);
cvf::Vec3d arrowPosition = whEndPos; cvf::Vec3d arrowPosition = whEndPos;
arrowPosition.z() += 2.0; arrowPosition.z() += pipeRadius;
// Well head pipe geometry // Well head pipe geometry
{ {
@ -160,12 +168,6 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex)
pipeGeomGenerator->setPipeColor(well->wellPipeColor()); pipeGeomGenerator->setPipeColor(well->wellPipeColor());
pipeGeomGenerator->setCrossSectionVertexCount(m_rimReservoirView->wellCollection()->pipeCrossSectionVertexCount()); pipeGeomGenerator->setCrossSectionVertexCount(m_rimReservoirView->wellCollection()->pipeCrossSectionVertexCount());
double pipeRadius = m_rimReservoirView->wellCollection()->pipeScaleFactor() * m_rimWell->pipeScaleFactor() * characteristicCellSize;
if (wellResultFrame.m_isOpen)
{
// Use slightly larger well head arrow when well is open
pipeRadius *= 1.1;
}
pipeGeomGenerator->setRadius(pipeRadius); pipeGeomGenerator->setRadius(pipeRadius);
@ -343,7 +345,7 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex)
cvf::ref<cvf::Effect> eff = new cvf::Effect; cvf::ref<cvf::Effect> eff = new cvf::Effect;
part->setEffect(eff.p()); part->setEffect(eff.p());
part->setPriority(11); part->setPriority(RivPartPriority::PartType::Text);
part->setSourceInfo(sourceInfo.p()); part->setSourceInfo(sourceInfo.p());
m_wellHeadLabelPart = part; m_wellHeadLabelPart = part;

View File

@ -30,6 +30,7 @@
#include "RimWellPathFractureCollection.h" #include "RimWellPathFractureCollection.h"
#include "RivPipeGeometryGenerator.h" #include "RivPipeGeometryGenerator.h"
#include "RivPartPriority.h"
#include "RivWellFracturePartMgr.h" #include "RivWellFracturePartMgr.h"
#include "RivWellPathPartMgr.h" #include "RivWellPathPartMgr.h"
#include "RivWellPathSourceInfo.h" #include "RivWellPathSourceInfo.h"
@ -239,7 +240,7 @@ void RivWellPathPartMgr::buildWellPathParts(cvf::Vec3d displayModelOffset, doubl
cvf::ref<cvf::Effect> eff = new cvf::Effect; cvf::ref<cvf::Effect> eff = new cvf::Effect;
part->setEffect(eff.p()); part->setEffect(eff.p());
part->setPriority(1000); part->setPriority(RivPartPriority::Text);
m_wellLabelPart = part; m_wellLabelPart = part;
} }

View File

@ -312,7 +312,11 @@ cvf::Color3f RimFlowDiagSolution::tracerColor(QString tracerName)
} }
} }
return cvf::Color3f::DARK_GRAY; if (tracerName == RIG_FLOW_TOTAL_NAME) return cvf::Color3f::LIGHT_GRAY;
if (tracerName == RIG_RESERVOIR_TRACER_NAME) return cvf::Color3f::LIGHT_GRAY;
if (tracerName == RIG_TINY_TRACER_GROUP_NAME) return cvf::Color3f::DARK_GRAY;
return cvf::Color3f::LIGHT_GRAY;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -20,7 +20,10 @@
#include "RiaApplication.h" #include "RiaApplication.h"
#include "RigAccWellFlowCalculator.h"
#include "RigEclipseCaseData.h" #include "RigEclipseCaseData.h"
#include "RigFlowDiagResultAddress.h"
#include "RigFlowDiagResults.h"
#include "RigSimulationWellCenterLineCalculator.h" #include "RigSimulationWellCenterLineCalculator.h"
#include "RigSimulationWellCoordsAndMD.h" #include "RigSimulationWellCoordsAndMD.h"
#include "RigSingleWellResultsData.h" #include "RigSingleWellResultsData.h"
@ -32,26 +35,36 @@
#include "RimEclipseWell.h" #include "RimEclipseWell.h"
#include "RimEclipseWellCollection.h" #include "RimEclipseWellCollection.h"
#include "RimFlowDiagSolution.h" #include "RimFlowDiagSolution.h"
#include "RimProject.h"
#include "RimTotalWellAllocationPlot.h" #include "RimTotalWellAllocationPlot.h"
#include "RimWellFlowRateCurve.h" #include "RimWellFlowRateCurve.h"
#include "RimWellLogPlot.h" #include "RimWellLogPlot.h"
#include "RimWellLogTrack.h" #include "RimWellLogTrack.h"
#include "RimWellAllocationPlotLegend.h"
#include "RiuMainPlotWindow.h" #include "RiuMainPlotWindow.h"
#include "RiuWellAllocationPlot.h" #include "RiuWellAllocationPlot.h"
#include "RigAccWellFlowCalculator.h"
#include "RimProject.h"
#include "RiuWellLogTrack.h" #include "RiuWellLogTrack.h"
#include "RimWellAllocationPlotLegend.h"
CAF_PDM_SOURCE_INIT(RimWellAllocationPlot, "WellAllocationPlot"); CAF_PDM_SOURCE_INIT(RimWellAllocationPlot, "WellAllocationPlot");
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
namespace caf
{
template<>
void AppEnum<RimWellAllocationPlot::FlowType>::setUp()
{
addItem(RimWellAllocationPlot::ACCUMULATED, "ACCUMULATED", "Well Flow");
addItem(RimWellAllocationPlot::INFLOW, "INFLOW", "In Flow");
setDefault(RimWellAllocationPlot::ACCUMULATED);
}
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -70,6 +83,8 @@ RimWellAllocationPlot::RimWellAllocationPlot()
CAF_PDM_InitField(&m_timeStep, "PlotTimeStep", 0, "Time Step", "", "", ""); CAF_PDM_InitField(&m_timeStep, "PlotTimeStep", 0, "Time Step", "", "", "");
CAF_PDM_InitField(&m_wellName, "WellName", QString("None"), "Well", "", "", ""); CAF_PDM_InitField(&m_wellName, "WellName", QString("None"), "Well", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_flowDiagSolution, "FlowDiagSolution", "Flow Diag Solution", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_flowDiagSolution, "FlowDiagSolution", "Flow Diag Solution", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_flowType, "FlowType", "Flow Type", "", "", "");
CAF_PDM_InitField(&m_groupSmallContributions, "GroupSmallContributions", true, "Group Small Contributions", "", "", ""); CAF_PDM_InitField(&m_groupSmallContributions, "GroupSmallContributions", true, "Group Small Contributions", "", "", "");
CAF_PDM_InitField(&m_smallContributionsThreshold, "SmallContributionsThreshold", 0.005, "Threshold", "", "", ""); CAF_PDM_InitField(&m_smallContributionsThreshold, "SmallContributionsThreshold", 0.005, "Threshold", "", "", "");
@ -183,20 +198,20 @@ void RimWellAllocationPlot::updateFromWell()
pipeBranchesCLCoords, pipeBranchesCLCoords,
pipeBranchesCellIds); pipeBranchesCellIds);
std::map<QString, const std::vector<double>* > tracerCellFractionValues = findRelevantTracerCellFractions(wellResults); std::map<QString, const std::vector<double>* > tracerFractionCellValues = findRelevantTracerCellFractions(wellResults);
std::unique_ptr< RigAccWellFlowCalculator > wfCalculator; std::unique_ptr< RigAccWellFlowCalculator > wfCalculator;
double smallContributionThreshold = 0.0; double smallContributionThreshold = 0.0;
if (m_groupSmallContributions()) smallContributionThreshold = m_smallContributionsThreshold; if (m_groupSmallContributions()) smallContributionThreshold = m_smallContributionsThreshold;
if ( tracerCellFractionValues.size() ) if ( tracerFractionCellValues.size() )
{ {
bool isProducer = wellResults->wellProductionType(m_timeStep) == RigWellResultFrame::PRODUCER ; bool isProducer = wellResults->wellProductionType(m_timeStep) == RigWellResultFrame::PRODUCER ;
RigEclCellIndexCalculator cellIdxCalc(m_case->reservoirData()->mainGrid(), m_case->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)); RigEclCellIndexCalculator cellIdxCalc(m_case->reservoirData()->mainGrid(), m_case->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS));
wfCalculator.reset(new RigAccWellFlowCalculator(pipeBranchesCLCoords, wfCalculator.reset(new RigAccWellFlowCalculator(pipeBranchesCLCoords,
pipeBranchesCellIds, pipeBranchesCellIds,
tracerCellFractionValues, tracerFractionCellValues,
cellIdxCalc, cellIdxCalc,
smallContributionThreshold, smallContributionThreshold,
isProducer)); isProducer));
@ -231,24 +246,26 @@ void RimWellAllocationPlot::updateFromWell()
accumulatedWellFlowPlot()->addTrack(plotTrack); accumulatedWellFlowPlot()->addTrack(plotTrack);
std::vector<double> connNumbers; std::vector<double> connNumbers = wfCalculator->connectionNumbersFromTop(brIdx);
{
const std::vector<size_t>& connNumbersSize_t = wfCalculator->connectionNumbersFromTop(brIdx);
for ( size_t conNumb : connNumbersSize_t ) connNumbers.push_back(static_cast<double>(conNumb));
}
if ( m_flowDiagSolution ) if ( m_flowDiagSolution )
{ {
std::vector<QString> tracerNames = wfCalculator->tracerNames(); std::vector<QString> tracerNames = wfCalculator->tracerNames();
for (const QString& tracerName: tracerNames) for (const QString& tracerName: tracerNames)
{ {
const std::vector<double>& accFlow = wfCalculator->accumulatedTracerFlowPrConnection(tracerName, brIdx); const std::vector<double>& accFlow = m_flowType == ACCUMULATED ?
wfCalculator->accumulatedTracerFlowPrConnection(tracerName, brIdx):
wfCalculator->tracerFlowPrConnection(tracerName, brIdx);
addStackedCurve(tracerName, connNumbers, accFlow, plotTrack); addStackedCurve(tracerName, connNumbers, accFlow, plotTrack);
} }
} }
else else
{ {
const std::vector<double>& accFlow = wfCalculator->accumulatedTotalFlowPrConnection(brIdx); const std::vector<double>& accFlow = m_flowType == ACCUMULATED ?
wfCalculator->accumulatedFlowPrConnection(brIdx):
wfCalculator->flowPrConnection(brIdx);
addStackedCurve("Total", connNumbers, accFlow, plotTrack); addStackedCurve("Total", connNumbers, accFlow, plotTrack);
} }
@ -601,7 +618,8 @@ void RimWellAllocationPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedF
|| changedField == &m_timeStep || changedField == &m_timeStep
|| changedField == &m_flowDiagSolution || changedField == &m_flowDiagSolution
|| changedField == &m_groupSmallContributions || changedField == &m_groupSmallContributions
|| changedField == &m_smallContributionsThreshold ) || changedField == &m_smallContributionsThreshold
|| changedField == &m_flowType )
{ {
loadDataAndUpdate(); loadDataAndUpdate();
} }

View File

@ -49,6 +49,8 @@ namespace caf {
class RimWellAllocationPlot : public RimViewWindow class RimWellAllocationPlot : public RimViewWindow
{ {
CAF_PDM_HEADER_INIT; CAF_PDM_HEADER_INIT;
public:
enum FlowType { ACCUMULATED, INFLOW};
public: public:
RimWellAllocationPlot(); RimWellAllocationPlot();
@ -115,6 +117,7 @@ private:
caf::PdmPtrField<RimFlowDiagSolution*> m_flowDiagSolution; caf::PdmPtrField<RimFlowDiagSolution*> m_flowDiagSolution;
caf::PdmField<bool> m_groupSmallContributions; caf::PdmField<bool> m_groupSmallContributions;
caf::PdmField<double> m_smallContributionsThreshold; caf::PdmField<double> m_smallContributionsThreshold;
caf::PdmField<caf::AppEnum<FlowType> > m_flowType;
QPointer<RiuWellAllocationPlot> m_wellAllocationPlotWidget; QPointer<RiuWellAllocationPlot> m_wellAllocationPlotWidget;

View File

@ -19,27 +19,48 @@
#include "RigAccWellFlowCalculator.h" #include "RigAccWellFlowCalculator.h"
#include "RigSingleWellResultsData.h" #include "RigSingleWellResultsData.h"
#include "RigMainGrid.h"
#include "RigActiveCellInfo.h"
#include "RigFlowDiagResults.h"
#define RIG_FLOW_TOTAL_NAME "Total" //==================================================================================================
#define RIG_RESERVOIR_TRACER_NAME "Reservoir" ///
#define RIG_TINY_TRACER_GROUP_NAME "Other" ///
//==================================================================================================
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords, size_t RigEclCellIndexCalculator::resultCellIndex(size_t gridIndex, size_t gridCellIndex) const
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds, {
const std::map<QString, const std::vector<double>* >& tracerCellFractionValues, const RigGridBase* grid = m_mainGrid->gridByIndex(gridIndex);
size_t reservoirCellIndex = grid->reservoirCellIndex(gridCellIndex);
return m_activeCellInfo->cellResultIndex(reservoirCellIndex);
}
//==================================================================================================
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords,
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
const std::map<QString, const std::vector<double>* >& tracerCellFractionValues,
const RigEclCellIndexCalculator cellIndexCalculator, const RigEclCellIndexCalculator cellIndexCalculator,
double smallContribThreshold, double smallContribThreshold,
bool isProducer): bool isProducer)
m_pipeBranchesCLCoords(pipeBranchesCLCoords), : m_pipeBranchesCLCoords(pipeBranchesCLCoords),
m_pipeBranchesCellIds(pipeBranchesCellIds), m_pipeBranchesCellIds(pipeBranchesCellIds),
m_tracerCellFractionValues(&tracerCellFractionValues), m_tracerCellFractionValues(&tracerCellFractionValues),
m_cellIndexCalculator(cellIndexCalculator), m_cellIndexCalculator(cellIndexCalculator),
m_smallContributionsThreshold(smallContribThreshold) m_smallContributionsThreshold(smallContribThreshold)
{ {
m_accConnectionFlowPrBranch.resize(m_pipeBranchesCellIds.size()); m_connectionFlowPrBranch.resize(m_pipeBranchesCellIds.size());
if (isWellFlowConsistent(isProducer)) if (isWellFlowConsistent(isProducer))
{ {
@ -66,15 +87,15 @@ RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vecto
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords, RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords,
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds, const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
double smallContribThreshold ): double smallContribThreshold)
m_pipeBranchesCLCoords(pipeBranchesCLCoords), : m_pipeBranchesCLCoords(pipeBranchesCLCoords),
m_pipeBranchesCellIds(pipeBranchesCellIds), m_pipeBranchesCellIds(pipeBranchesCellIds),
m_tracerCellFractionValues(nullptr), m_tracerCellFractionValues(nullptr),
m_cellIndexCalculator(RigEclCellIndexCalculator(nullptr, nullptr)), m_cellIndexCalculator(RigEclCellIndexCalculator(nullptr, nullptr)),
m_smallContributionsThreshold(smallContribThreshold) m_smallContributionsThreshold(smallContribThreshold)
{ {
m_accConnectionFlowPrBranch.resize(m_pipeBranchesCellIds.size()); m_connectionFlowPrBranch.resize(m_pipeBranchesCellIds.size());
m_tracerNames.push_back(RIG_FLOW_TOTAL_NAME); m_tracerNames.push_back(RIG_FLOW_TOTAL_NAME);
@ -84,35 +105,67 @@ RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vecto
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
const std::vector<double>& RigAccWellFlowCalculator::accumulatedTotalFlowPrConnection(size_t branchIdx) const std::vector<double>& RigAccWellFlowCalculator::accumulatedFlowPrConnection(size_t branchIdx) const
{ {
CVF_ASSERT(m_accConnectionFlowPrBranch[branchIdx].accConnFlowFractionsPrTracer.find(RIG_FLOW_TOTAL_NAME) != m_accConnectionFlowPrBranch[branchIdx].accConnFlowFractionsPrTracer.end()); return accumulatedTracerFlowPrConnection(RIG_FLOW_TOTAL_NAME, branchIdx);
return m_accConnectionFlowPrBranch[branchIdx].accConnFlowFractionsPrTracer[RIG_FLOW_TOTAL_NAME];
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
const std::vector<double>& RigAccWellFlowCalculator::accumulatedTracerFlowPrConnection(const QString& tracerName, size_t branchIdx) const std::vector<double>& RigAccWellFlowCalculator::accumulatedTracerFlowPrConnection(const QString& tracerName, size_t branchIdx) const
{ {
CVF_ASSERT(m_accConnectionFlowPrBranch[branchIdx].accConnFlowFractionsPrTracer.find(tracerName) != m_accConnectionFlowPrBranch[branchIdx].accConnFlowFractionsPrTracer.end()); auto flowPrTracerIt = m_connectionFlowPrBranch[branchIdx].accFlowPrTracer.find(tracerName);
if ( flowPrTracerIt != m_connectionFlowPrBranch[branchIdx].accFlowPrTracer.end())
return m_accConnectionFlowPrBranch[branchIdx].accConnFlowFractionsPrTracer[tracerName]; {
return flowPrTracerIt->second;
}
else
{
CVF_ASSERT(false);
static std::vector<double> dummy;
return dummy;
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
const std::vector<size_t>& RigAccWellFlowCalculator::connectionNumbersFromTop(size_t branchIdx) const const std::vector<double>& RigAccWellFlowCalculator::flowPrConnection(size_t branchIdx) const
{ {
return m_accConnectionFlowPrBranch[branchIdx].connectionNumbersFromTop; return tracerFlowPrConnection(RIG_FLOW_TOTAL_NAME, branchIdx);
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<std::pair<QString, double> > RigAccWellFlowCalculator::totalWellFlowPrTracer() const std::vector<double>& RigAccWellFlowCalculator::tracerFlowPrConnection(const QString& tracerName, size_t branchIdx) const
{
auto flowPrTracerIt = m_connectionFlowPrBranch[branchIdx].flowPrTracer.find(tracerName);
if ( flowPrTracerIt != m_connectionFlowPrBranch[branchIdx].flowPrTracer.end())
{
return flowPrTracerIt->second;
}
else
{
CVF_ASSERT(false);
static std::vector<double> dummy;
return dummy;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>& RigAccWellFlowCalculator::connectionNumbersFromTop(size_t branchIdx) const
{
return m_connectionFlowPrBranch[branchIdx].depthValuesFromTop;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::pair<QString, double> > RigAccWellFlowCalculator::totalWellFlowPrTracer() const
{ {
std::vector<QString> tracerNames = this->tracerNames(); std::vector<QString> tracerNames = this->tracerNames();
std::vector<std::pair<QString, double> > tracerWithValues; std::vector<std::pair<QString, double> > tracerWithValues;
@ -130,7 +183,7 @@ std::vector<std::pair<QString, double> > RigAccWellFlowCalculator::totalWellFlow
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<std::pair<QString, double> > RigAccWellFlowCalculator::totalTracerFractions() std::vector<std::pair<QString, double> > RigAccWellFlowCalculator::totalTracerFractions() const
{ {
std::vector<std::pair<QString, double> > totalFlows = totalWellFlowPrTracer(); std::vector<std::pair<QString, double> > totalFlows = totalWellFlowPrTracer();
@ -150,7 +203,10 @@ std::vector<std::pair<QString, double> > RigAccWellFlowCalculator::totalTracerFr
return totalFlows; return totalFlows;
} }
bool RigAccWellFlowCalculator::isWellFlowConsistent( bool isProducer) //--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigAccWellFlowCalculator::isWellFlowConsistent( bool isProducer) const
{ {
bool isConsistent = true; bool isConsistent = true;
for (const std::vector <RigWellResultPoint> & branch : m_pipeBranchesCellIds) for (const std::vector <RigWellResultPoint> & branch : m_pipeBranchesCellIds)
@ -181,11 +237,7 @@ void RigAccWellFlowCalculator::calculateAccumulatedFlowPrConnection(size_t branc
size_t prevConnIndx = -1; size_t prevConnIndx = -1;
int clSegIdx = static_cast<int>(branchCells.size()) - 1; int clSegIdx = static_cast<int>(branchCells.size()) - 1;
std::map<QString, std::vector<double> >& accConnFlowFractionsPrTracer = m_accConnectionFlowPrBranch[branchIdx].accConnFlowFractionsPrTracer; std::vector<double> accFlowPrTracer(m_tracerNames.size(), 0.0);
std::vector<size_t>& connNumbersFromTop = m_accConnectionFlowPrBranch[branchIdx].connectionNumbersFromTop;
std::vector<double> accFlow;
accFlow.resize(m_tracerNames.size(), 0.0);
while ( clSegIdx >= 0 ) while ( clSegIdx >= 0 )
{ {
@ -201,6 +253,7 @@ void RigAccWellFlowCalculator::calculateAccumulatedFlowPrConnection(size_t branc
} }
// Accumulate the connection-cell's fraction flows // Accumulate the connection-cell's fraction flows
std::vector<double> flowPrTracer(m_tracerNames.size(), 0.0);
if ( m_tracerCellFractionValues ) if ( m_tracerCellFractionValues )
{ {
@ -215,19 +268,25 @@ void RigAccWellFlowCalculator::calculateAccumulatedFlowPrConnection(size_t branc
double cellTracerFraction = (*tracerFractionIt.second)[resCellIndex]; double cellTracerFraction = (*tracerFractionIt.second)[resCellIndex];
if (cellTracerFraction != HUGE_VAL && cellTracerFraction == cellTracerFraction) if (cellTracerFraction != HUGE_VAL && cellTracerFraction == cellTracerFraction)
{ {
accFlow[tracerIdx] += cellTracerFraction * branchCells[clSegIdx].flowRate(); double tracerFlow = cellTracerFraction * branchCells[clSegIdx].flowRate();
flowPrTracer[tracerIdx] = tracerFlow;
accFlowPrTracer[tracerIdx] += tracerFlow;
totalTracerFractionInCell += cellTracerFraction; totalTracerFractionInCell += cellTracerFraction;
} }
tracerIdx++; tracerIdx++;
} }
double reservoirFraction = 1.0 - totalTracerFractionInCell; double reservoirFraction = 1.0 - totalTracerFractionInCell;
accFlow[tracerIdx] += reservoirFraction * branchCells[clSegIdx].flowRate(); double reservoirTracerFlow = reservoirFraction * branchCells[clSegIdx].flowRate();
flowPrTracer[tracerIdx] = reservoirTracerFlow;
accFlowPrTracer[tracerIdx] += reservoirTracerFlow;
} }
} }
else else
{ {
accFlow[0] += branchCells[clSegIdx].flowRate(); accFlowPrTracer[0] += branchCells[clSegIdx].flowRate();
flowPrTracer[0] = branchCells[clSegIdx].flowRate();
} }
// Add the total accumulated (fraction) flows from any branches connected to this cell // Add the total accumulated (fraction) flows from any branches connected to this cell
@ -237,39 +296,47 @@ void RigAccWellFlowCalculator::calculateAccumulatedFlowPrConnection(size_t branc
std::vector<size_t> downstreamBranches = findDownstreamBranchIdxs(branchCells[clSegIdx]); std::vector<size_t> downstreamBranches = findDownstreamBranchIdxs(branchCells[clSegIdx]);
for ( size_t dsBidx : downstreamBranches ) for ( size_t dsBidx : downstreamBranches )
{ {
if ( dsBidx != branchIdx && m_accConnectionFlowPrBranch[dsBidx].connectionNumbersFromTop.size() == 0 ) // Not this branch or already calculated if ( dsBidx != branchIdx && m_connectionFlowPrBranch[dsBidx].depthValuesFromTop.size() == 0 ) // Not this branch or already calculated
{ {
calculateAccumulatedFlowPrConnection(dsBidx, connNumFromTop); calculateAccumulatedFlowPrConnection(dsBidx, connNumFromTop);
BranchResult& accConnFlowFractionsDsBranch = m_accConnectionFlowPrBranch[dsBidx]; BranchFlow& accConnFlowFractionsDsBranch = m_connectionFlowPrBranch[dsBidx];
size_t tracerIdx = 0; size_t tracerIdx = 0;
for ( const auto & tracerName: m_tracerNames ) for ( const auto & tracerName: m_tracerNames )
{ {
accFlow[tracerIdx] += accConnFlowFractionsDsBranch.accConnFlowFractionsPrTracer[tracerName].back(); accFlowPrTracer[tracerIdx] += accConnFlowFractionsDsBranch.accFlowPrTracer[tracerName].back();
tracerIdx++; tracerIdx++;
} }
} }
} }
// Push back the accumulated result into the storage // Push back the accumulated result into the storage
size_t tracerIdx = 0;
for ( const auto & tracerName: m_tracerNames )
{ {
accConnFlowFractionsPrTracer[tracerName].push_back(accFlow[tracerIdx]); std::vector<double>& connNumbersFromTop = m_connectionFlowPrBranch[branchIdx].depthValuesFromTop;
tracerIdx++; std::map<QString, std::vector<double> >& branchAccFlowPrTracer = m_connectionFlowPrBranch[branchIdx].accFlowPrTracer;
std::map<QString, std::vector<double> >& branchFlowPrTracer = m_connectionFlowPrBranch[branchIdx].flowPrTracer;
size_t tracerIdx = 0;
for ( const auto & tracerName: m_tracerNames )
{
branchAccFlowPrTracer[tracerName].push_back(accFlowPrTracer[tracerIdx]);
branchFlowPrTracer[tracerName].push_back(flowPrTracer[tracerIdx]);
tracerIdx++;
}
connNumbersFromTop.push_back(connNumFromTop);
} }
connNumbersFromTop.push_back(connNumFromTop);
--clSegIdx; --clSegIdx;
} }
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<size_t> RigAccWellFlowCalculator::wrpToConnectionIndexFromBottom(const std::vector<RigWellResultPoint> &branchCells) std::vector<size_t> RigAccWellFlowCalculator::wrpToConnectionIndexFromBottom(const std::vector<RigWellResultPoint> &branchCells) const
{ {
std::vector<size_t> resPointToConnectionIndexFromBottom; std::vector<size_t> resPointToConnectionIndexFromBottom;
resPointToConnectionIndexFromBottom.resize(branchCells.size(), -1); resPointToConnectionIndexFromBottom.resize(branchCells.size(), -1);
@ -311,7 +378,7 @@ std::vector<size_t> RigAccWellFlowCalculator::wrpToConnectionIndexFromBottom(con
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
size_t RigAccWellFlowCalculator::connectionIndexFromTop(const std::vector<size_t>& resPointToConnectionIndexFromBottom, size_t clSegIdx) size_t RigAccWellFlowCalculator::connectionIndexFromTop(const std::vector<size_t>& resPointToConnectionIndexFromBottom, size_t clSegIdx)
{ {
return resPointToConnectionIndexFromBottom.front() - resPointToConnectionIndexFromBottom[clSegIdx]; return resPointToConnectionIndexFromBottom.front() - resPointToConnectionIndexFromBottom[clSegIdx];
} }
@ -319,7 +386,7 @@ size_t RigAccWellFlowCalculator::connectionIndexFromTop(const std::vector<size_t
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<size_t> RigAccWellFlowCalculator::findDownstreamBranchIdxs(const RigWellResultPoint& connectionPoint) std::vector<size_t> RigAccWellFlowCalculator::findDownstreamBranchIdxs(const RigWellResultPoint& connectionPoint) const
{ {
std::vector<size_t> downStreamBranchIdxs; std::vector<size_t> downStreamBranchIdxs;
@ -346,8 +413,11 @@ void RigAccWellFlowCalculator::sortTracers()
for (const QString& tracerName: m_tracerNames) for (const QString& tracerName: m_tracerNames)
{ {
const std::vector<double>& mainBranchAccFlow = accumulatedTracerFlowPrConnection(tracerName, 0); const std::vector<double>& mainBranchAccFlow = accumulatedTracerFlowPrConnection(tracerName, 0);
double totalFlow = 0.0; double totalFlow = 0.0;
if (mainBranchAccFlow.size()) totalFlow = - abs( mainBranchAccFlow.back() ); // Based on size in reverse order (biggest to least) if (mainBranchAccFlow.size()) totalFlow = - abs( mainBranchAccFlow.back() ); // Based on size in reverse order (biggest to least)
sortedTracers.insert({totalFlow, tracerName}); sortedTracers.insert({totalFlow, tracerName});
} }
@ -359,61 +429,83 @@ void RigAccWellFlowCalculator::sortTracers()
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// /// Concatenate small tracers into an "Other" group
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RigAccWellFlowCalculator::groupSmallContributions() void RigAccWellFlowCalculator::groupSmallContributions()
{ {
// Concatenate small tracers into an "Other" group
if ( m_smallContributionsThreshold > 0.0 ) if ( ! (m_smallContributionsThreshold > 0.0) ) return;
// Find the tracers we need to group
std::vector<QString> tracersToGroup;
{ {
std::vector<std::pair<QString, double> > totalTracerFractions = this->totalTracerFractions(); std::vector<std::pair<QString, double> > totalTracerFractions = this->totalTracerFractions();
if ( totalTracerFractions.size() < 5 ) return; // No grouping for few legend items if ( totalTracerFractions.size() < 5 ) return; // No grouping for few legend items
std::vector<QString> tracersToGroup;
for ( const auto& tracerPair : totalTracerFractions ) for ( const auto& tracerPair : totalTracerFractions )
{ {
if ( abs(tracerPair.second) <= m_smallContributionsThreshold ) tracersToGroup.push_back(tracerPair.first); if ( abs(tracerPair.second) <= m_smallContributionsThreshold ) tracersToGroup.push_back(tracerPair.first);
} }
if ( tracersToGroup.size() < 2 ) return; // Must at least group two ...
for ( BranchResult& brRes : m_accConnectionFlowPrBranch )
{
std::vector<double> groupedConnectionValues(brRes.connectionNumbersFromTop.size(), 0.0);
for ( const QString& tracername:tracersToGroup )
{
auto it = brRes.accConnFlowFractionsPrTracer.find(tracername);
if ( it != brRes.accConnFlowFractionsPrTracer.end() )
{
const std::vector<double>& tracerVals = it->second;
for ( size_t cIdx = 0; cIdx < groupedConnectionValues.size(); ++cIdx )
{
groupedConnectionValues[cIdx] += tracerVals[cIdx];
}
}
brRes.accConnFlowFractionsPrTracer.erase(it);
}
brRes.accConnFlowFractionsPrTracer[RIG_TINY_TRACER_GROUP_NAME] = groupedConnectionValues;
}
std::vector<QString> filteredTracernames;
for ( const QString& tracerName: m_tracerNames )
{
bool isDeleted = false;
for ( const QString& deletedTracerName: tracersToGroup )
{
if ( tracerName == deletedTracerName ) { isDeleted = true; break; }
}
if ( !isDeleted ) filteredTracernames.push_back(tracerName);
}
m_tracerNames.swap(filteredTracernames);
m_tracerNames.push_back(RIG_TINY_TRACER_GROUP_NAME);
} }
if ( tracersToGroup.size() < 2 ) return; // Must at least group two ...
// Concatenate the values for each branch, erasing the tracers being grouped, replaced with the concatenated values
for ( BranchFlow& brRes : m_connectionFlowPrBranch )
{
groupSmallTracers( brRes.accFlowPrTracer, tracersToGroup);
groupSmallTracers( brRes.flowPrTracer, tracersToGroup);
}
// Remove the grouped tracer names from the tracerName list, and replace with the "Others" name
std::vector<QString> filteredTracernames;
for ( const QString& tracerName: m_tracerNames )
{
bool isDeleted = false;
for ( const QString& deletedTracerName: tracersToGroup )
{
if ( tracerName == deletedTracerName ) { isDeleted = true; break; }
}
if ( !isDeleted ) filteredTracernames.push_back(tracerName);
}
m_tracerNames.swap(filteredTracernames);
m_tracerNames.push_back(RIG_TINY_TRACER_GROUP_NAME);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigAccWellFlowCalculator::groupSmallTracers(std::map<QString, std::vector<double>> &branchFlowSet, std::vector<QString> tracersToGroup)
{
if ( branchFlowSet.empty() ) return;
size_t depthCount = branchFlowSet.begin()->second.size();
std::vector<double> groupedAccFlowValues(depthCount, 0.0);
for ( const QString& tracername:tracersToGroup )
{
auto it = branchFlowSet.find(tracername);
if ( it != branchFlowSet.end() )
{
const std::vector<double>& tracerVals = it->second;
for ( size_t cIdx = 0; cIdx < groupedAccFlowValues.size(); ++cIdx )
{
groupedAccFlowValues[cIdx] += tracerVals[cIdx];
}
}
branchFlowSet.erase(it);
}
branchFlowSet[RIG_TINY_TRACER_GROUP_NAME] = groupedAccFlowValues;
} }

View File

@ -17,16 +17,15 @@
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
#pragma once #pragma once
#include <vector>
#include <map>
//================================================================================================== //==================================================================================================
/// ///
/// ///
//================================================================================================== //==================================================================================================
#include "RigActiveCellInfo.h"
#include "RigMainGrid.h"
#include "RigFlowDiagResults.h"
struct RigWellResultPoint; class RigMainGrid;
class RigActiveCellInfo;
class RigEclCellIndexCalculator class RigEclCellIndexCalculator
{ {
@ -35,13 +34,7 @@ public:
: m_mainGrid(mainGrid), m_activeCellInfo(activeCellInfo) : m_mainGrid(mainGrid), m_activeCellInfo(activeCellInfo)
{} {}
size_t resultCellIndex(size_t gridIndex, size_t gridCellIndex) const size_t resultCellIndex(size_t gridIndex, size_t gridCellIndex) const;
{
const RigGridBase* grid = m_mainGrid->gridByIndex(gridIndex);
size_t reservoirCellIndex = grid->reservoirCellIndex(gridCellIndex);
return m_activeCellInfo->cellResultIndex(reservoirCellIndex);
}
private: private:
const RigMainGrid* m_mainGrid; const RigMainGrid* m_mainGrid;
@ -53,6 +46,12 @@ private:
/// ///
//================================================================================================== //==================================================================================================
#include <QString>
#include "cvfBase.h"
#include "cvfVector3.h"
struct RigWellResultPoint;
class RigAccWellFlowCalculator class RigAccWellFlowCalculator
{ {
@ -68,39 +67,51 @@ public:
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds, const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
double smallContribThreshold); double smallContribThreshold);
const std::vector<double>& accumulatedTotalFlowPrConnection( size_t branchIdx);// const; const std::vector<double>& accumulatedFlowPrConnection( size_t branchIdx) const;
const std::vector<double>& accumulatedTracerFlowPrConnection(const QString& tracerName, size_t branchIdx);// const; const std::vector<double>& accumulatedTracerFlowPrConnection(const QString& tracerName, size_t branchIdx) const;
const std::vector<size_t>& connectionNumbersFromTop(size_t branchIdx) const; const std::vector<double>& flowPrConnection( size_t branchIdx) const;
const std::vector<QString>& tracerNames() const { return m_tracerNames;} const std::vector<double>& tracerFlowPrConnection(const QString& tracerName, size_t branchIdx) const;
const std::vector<double>& connectionNumbersFromTop(size_t branchIdx) const;
const std::vector<QString>& tracerNames() const { return m_tracerNames;}
std::vector<std::pair<QString, double> > totalTracerFractions() const;
std::vector<std::pair<QString, double> > totalTracerFractions();
private: private:
bool isWellFlowConsistent(bool isProducer); void calculateAccumulatedFlowPrConnection( size_t branchIdx, size_t startConnectionNumberFromTop);
void calculateAccumulatedFlowPrConnection( size_t branchIdx, size_t startConnectionNumberFromTop); void calculateFlowPrPseudoLength(size_t branchIdx, double startPseudoLengthFromTop);
std::vector<size_t> wrpToConnectionIndexFromBottom( const std::vector<RigWellResultPoint> &branchCells); void sortTracers();
static size_t connectionIndexFromTop( const std::vector<size_t>& resPointToConnectionIndexFromBottom, size_t clSegIdx); void groupSmallContributions();
std::vector<size_t> findDownstreamBranchIdxs( const RigWellResultPoint& connectionPoint);
std::vector<std::pair<QString, double> > totalWellFlowPrTracer() ; void groupSmallTracers(std::map<QString, std::vector<double>> &branchFlowSet,
void sortTracers(); std::vector<QString> tracersToGroup);
void groupSmallContributions(); bool isWellFlowConsistent(bool isProducer) const;
std::vector<size_t> wrpToConnectionIndexFromBottom( const std::vector<RigWellResultPoint> &branchCells) const;
static size_t connectionIndexFromTop( const std::vector<size_t>& resPointToConnectionIndexFromBottom, size_t clSegIdx) ;
std::vector<size_t> findDownstreamBranchIdxs( const RigWellResultPoint& connectionPoint) const;
const std::vector< std::vector <cvf::Vec3d> >& m_pipeBranchesCLCoords; std::vector<std::pair<QString, double> > totalWellFlowPrTracer() const;
const std::vector< std::vector <RigWellResultPoint> >& m_pipeBranchesCellIds;
const std::map<QString, const std::vector<double>* >* m_tracerCellFractionValues;
RigEclCellIndexCalculator m_cellIndexCalculator;
std::vector<QString> m_tracerNames;
double m_smallContributionsThreshold;
struct BranchResult
const std::vector< std::vector <cvf::Vec3d> >& m_pipeBranchesCLCoords;
const std::vector< std::vector <RigWellResultPoint> >& m_pipeBranchesCellIds;
const std::map<QString, const std::vector<double>* >* m_tracerCellFractionValues;
RigEclCellIndexCalculator m_cellIndexCalculator;
std::vector<QString> m_tracerNames;
double m_smallContributionsThreshold;
struct BranchFlow
{ {
std::vector<size_t> connectionNumbersFromTop; std::vector<double> depthValuesFromTop;
std::map<QString, std::vector<double> > accConnFlowFractionsPrTracer; std::map<QString, std::vector<double> > accFlowPrTracer;
}; std::map<QString, std::vector<double> > flowPrTracer;
};
std::vector< BranchFlow > m_connectionFlowPrBranch;
std::vector< BranchFlow > m_pseudoLengthFlowPrBranch;
std::vector< BranchFlow > m_tvdFlowPrBranch;
std::vector< BranchResult > m_accConnectionFlowPrBranch;
}; };

View File

@ -25,6 +25,10 @@
#define RIG_FLD_MAX_FRACTION_TRACER_RESNAME "MaxFractionTracer" #define RIG_FLD_MAX_FRACTION_TRACER_RESNAME "MaxFractionTracer"
#define RIG_FLD_COMMUNICATION_RESNAME "Communication" #define RIG_FLD_COMMUNICATION_RESNAME "Communication"
#define RIG_FLOW_TOTAL_NAME "Total"
#define RIG_RESERVOIR_TRACER_NAME "Reservoir"
#define RIG_TINY_TRACER_GROUP_NAME "Other"
class RigFlowDiagResultAddress class RigFlowDiagResultAddress
{ {

View File

@ -26,6 +26,8 @@
#include "RimEclipseCase.h" #include "RimEclipseCase.h"
#include "RimEclipseResultCase.h" #include "RimEclipseResultCase.h"
#include "RimFlowDiagSolution.h" #include "RimFlowDiagSolution.h"
#include "RigFlowDiagResultFrames.h"
#include "RigStatisticsDataCache.h"
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///

View File

@ -26,11 +26,11 @@
#include <map> #include <map>
#include <string> #include <string>
#include "RigFlowDiagResultFrames.h"
#include "RigStatisticsDataCache.h"
#include "cafPdmPointer.h" #include "cafPdmPointer.h"
#include "RimFlowDiagSolution.h" #include "RimFlowDiagSolution.h"
class RigFlowDiagResultFrames;
class RigStatisticsDataCache;
class RigFlowDiagSolverInterface; class RigFlowDiagSolverInterface;
class RigActiveCellInfo; class RigActiveCellInfo;