#2544 Well CF Viz : Add basiz viz with spheres, add legend to view

This commit is contained in:
Magne Sjaastad 2018-03-14 09:35:48 +01:00
parent b7e8834b4c
commit 108ef5eecc
18 changed files with 600 additions and 172 deletions

View File

@ -54,13 +54,6 @@ CAF_PDM_SOURCE_INIT(RicExportCompletionDataSettingsUi, "RicExportCompletionDataS
///
//--------------------------------------------------------------------------------------------------
RicExportCompletionDataSettingsUi::RicExportCompletionDataSettingsUi()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicExportCompletionDataSettingsUi::RicExportCompletionDataSettingsUi(bool onlyWellPathCollectionSelected)
{
CAF_PDM_InitObject("RimExportCompletionDataSettings", "", "", "");
@ -71,7 +64,7 @@ RicExportCompletionDataSettingsUi::RicExportCompletionDataSettingsUi(bool onlyWe
CAF_PDM_InitFieldNoDefault(&compdatExport, "compdatExport", "Export", "", " ", "");
CAF_PDM_InitField(&timeStep, "TimeStepIndex", 0, "Time Step", "", "", "");
CAF_PDM_InitField(&useLateralNTG, "UseLateralNTG", false, "Use NTG Horizontally", "", "", "");
CAF_PDM_InitField(&includePerforations, "IncludePerforations", true, "Include Perforations", "", "", "");
@ -79,10 +72,20 @@ RicExportCompletionDataSettingsUi::RicExportCompletionDataSettingsUi(bool onlyWe
CAF_PDM_InitField(&includeFractures, "IncludeFractures", true, "Include Fractures", "", "", "");
CAF_PDM_InitField(&excludeMainBoreForFishbones, "ExcludeMainBoreForFishbones", false, "Exclude Main Bore Transmissibility For Fishbones", "", "", "");
m_onlyWellPathCollectionSelected = onlyWellPathCollectionSelected;
m_onlyWellPathCollectionSelected = false;
m_displayForSimWell = true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicExportCompletionDataSettingsUi::RicExportCompletionDataSettingsUi(bool onlyWellPathCollectionSelected)
{
RicExportCompletionDataSettingsUi();
setOnlyWellPathCollectionSelected(onlyWellPathCollectionSelected);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -319,105 +319,21 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions(const std::ve
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
/*
void RicWellPathExportCompletionDataFeatureImpl::computeVirtualPerfTrans(
RigVirtualPerforationTransmissibilities* virtualPerfTrans,
RimEclipseCase* eclipseCase,
const std::vector<RimWellPath*>& inputWellPaths)
{
CVF_ASSERT(eclipseCase);
std::vector<RimWellPath*> usedWellPaths;
{
for (RimWellPath* wellPath : inputWellPaths)
{
if (wellPath->unitSystem() == eclipseCase->eclipseCaseData()->unitsType())
{
usedWellPaths.push_back(wellPath);
}
else
{
RiaLogging::error("Well path unit systems must match unit system of chosen eclipse case.");
}
}
}
RicExportCompletionDataSettingsUi exportSettings;
exportSettings.caseToApply = eclipseCase;
exportSettings.includeFishbones = true;
exportSettings.includePerforations = true;
exportSettings.includeFractures = true;
bool anyPerforationsPresent = false;
for (const auto& w : usedWellPaths)
{
if (!w->perforationIntervalCollection()->perforations().empty())
{
anyPerforationsPresent = true;
}
}
for (auto wellPath : usedWellPaths)
{
std::vector<RigCompletionData> completionsPerEclipseCell;
// Compute completions that do not change between time steps
if (exportSettings.includeFishbones)
{
std::vector<RigCompletionData> completionData =
RicFishbonesTransmissibilityCalculationFeatureImp::generateFishboneCompdatValuesUsingAdjustedCellVolume(
wellPath, exportSettings);
std::copy(completionData.begin(), completionData.end(), std::back_inserter(completionsPerEclipseCell));
}
if (exportSettings.includeFractures())
{
std::vector<RigCompletionData> completionData =
RicExportFractureCompletionsImpl::generateCompdatValuesForWellPath(wellPath, exportSettings, nullptr);
std::copy(completionData.begin(), completionData.end(), std::back_inserter(completionsPerEclipseCell));
}
if (!anyPerforationsPresent)
{
virtualPerfTrans->appendCompletionDataForWellPath(wellPath, completionsPerEclipseCell);
}
else
{
for (size_t i = 0; i < eclipseCase->timeStepDates().size(); i++)
{
// Update time step in export settings
exportSettings.timeStep = static_cast<int>(i);
if (exportSettings.includePerforations)
{
std::vector<RigCompletionData> completionData = generatePerforationsCompdatValues(wellPath, exportSettings);
std::copy(completionData.begin(), completionData.end(), std::back_inserter(completionsPerEclipseCell));
}
//virtualPerfTrans->appendCompletionDataForWellPath(wellPath, completionsPerEclipseCell);
}
}
}
}
*/
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigCompletionData> RicWellPathExportCompletionDataFeatureImpl::computeCompletionsForWellPath(
RimWellPath* wellPath,
const RicExportCompletionDataSettingsUi& exportSettings)
std::vector<RigCompletionData>
RicWellPathExportCompletionDataFeatureImpl::computeStaticCompletionsForWellPath(RimWellPath* wellPath,
RimEclipseCase* eclipseCase)
{
std::vector<RigCompletionData> completionsPerEclipseCell;
{
// Compute completions that do not change between time steps
if (exportSettings.includeFishbones)
if (eclipseCase && eclipseCase->eclipseCaseData())
{
RicExportCompletionDataSettingsUi exportSettings;
exportSettings.caseToApply = eclipseCase;
exportSettings.timeStep = 0;
exportSettings.includeFishbones = true;
exportSettings.includePerforations = true;
exportSettings.includeFractures = true;
{
std::vector<RigCompletionData> completionData =
RicFishbonesTransmissibilityCalculationFeatureImp::generateFishboneCompdatValuesUsingAdjustedCellVolume(
@ -426,33 +342,39 @@ std::vector<RigCompletionData> RicWellPathExportCompletionDataFeatureImpl::compu
std::copy(completionData.begin(), completionData.end(), std::back_inserter(completionsPerEclipseCell));
}
if (exportSettings.includeFractures())
{
std::vector<RigCompletionData> completionData =
RicExportFractureCompletionsImpl::generateCompdatValuesForWellPath(wellPath, exportSettings, nullptr);
std::copy(completionData.begin(), completionData.end(), std::back_inserter(completionsPerEclipseCell));
}
{
/*
for (size_t i = 0; i < exportSettings.caseToApply()->timeStepDates().size(); i++)
{
// Update time step in export settings
exportSettings.timeStep = static_cast<int>(i);
if (exportSettings.includePerforations)
{
std::vector<RigCompletionData> completionData = generatePerforationsCompdatValues(wellPath, exportSettings);
std::copy(completionData.begin(), completionData.end(), std::back_inserter(completionsPerEclipseCell));
}
// virtualPerfTrans->appendCompletionDataForWellPath(wellPath, completionsPerEclipseCell);
}
*/
}
}
return completionsPerEclipseCell;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigCompletionData>
RicWellPathExportCompletionDataFeatureImpl::computeDynamicCompletionsForWellPath(RimWellPath* wellPath,
RimEclipseCase* eclipseCase,
size_t timeStepIndex)
{
std::vector<RigCompletionData> completionsPerEclipseCell;
if (eclipseCase && eclipseCase->eclipseCaseData())
{
RicExportCompletionDataSettingsUi exportSettings;
exportSettings.caseToApply = eclipseCase;
exportSettings.timeStep = static_cast<int>(timeStepIndex);
exportSettings.includeFishbones = true;
exportSettings.includePerforations = true;
exportSettings.includeFractures = true;
completionsPerEclipseCell = generatePerforationsCompdatValues(wellPath, exportSettings);
}
return completionsPerEclipseCell;
}

View File

@ -146,8 +146,12 @@ public:
const std::vector<RimSimWellInView*>& simWells,
const RicExportCompletionDataSettingsUi& exportSettings);
static std::vector<RigCompletionData> computeCompletionsForWellPath(RimWellPath* wellPath,
const RicExportCompletionDataSettingsUi& exportSettings);
static std::vector<RigCompletionData> computeStaticCompletionsForWellPath(RimWellPath* wellPath,
RimEclipseCase* eclipseCase);
static std::vector<RigCompletionData> computeDynamicCompletionsForWellPath(RimWellPath* wellPath,
RimEclipseCase* eclipseCase,
size_t timeStepIndex);
private:
static double calculateTransmissibilityAsEclipseDoes(RimEclipseCase* eclipseCase,

View File

@ -39,6 +39,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RivTensorResultPartMgr.h
${CMAKE_CURRENT_LIST_DIR}/RivWellFracturePartMgr.h
${CMAKE_CURRENT_LIST_DIR}/Riv3dWellLogPlanePartMgr.h
${CMAKE_CURRENT_LIST_DIR}/Riv3dWellLogCurveGeomertyGenerator.h
${CMAKE_CURRENT_LIST_DIR}/RivVirtualConnFactorPartMgr.h
)
set (SOURCE_GROUP_SOURCE_FILES
@ -76,6 +77,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RivTensorResultPartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/RivWellFracturePartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/Riv3dWellLogPlanePartMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/Riv3dWellLogCurveGeomertyGenerator.cpp
${CMAKE_CURRENT_LIST_DIR}/RivVirtualConnFactorPartMgr.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@ -0,0 +1,184 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RivVirtualConnFactorPartMgr.h"
#include "RiaApplication.h"
#include "RigMainGrid.h"
#include "RigVirtualPerforationTransmissibilities.h"
#include "RimEclipseCase.h"
#include "RimEclipseView.h"
#include "RimLegendConfig.h"
#include "RimSimWellInViewCollection.h"
#include "RimVirtualPerforationResults.h"
#include "RimWellPath.h"
#include "RiuViewer.h"
#include "cafDisplayCoordTransform.h"
#include "cafEffectGenerator.h"
#include "cafPdmFieldCvfColor.h"
#include "cafPdmFieldCvfMat4d.h"
#include "cvfDrawableGeo.h"
#include "cvfGeometryBuilderFaceList.h"
#include "cvfGeometryBuilderTriangles.h"
#include "cvfGeometryUtils.h"
#include "cvfModelBasicList.h"
#include "cvfObject.h"
#include "cvfPart.h"
#include "cvfPrimitiveSetIndexedUInt.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivVirtualConnFactorPartMgr::RivVirtualConnFactorPartMgr(RimWellPath* well,
RimVirtualPerforationResults* virtualPerforationResult)
: m_rimWell(well)
, m_virtualPerforationResult(virtualPerforationResult)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivVirtualConnFactorPartMgr::~RivVirtualConnFactorPartMgr() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivVirtualConnFactorPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex)
{
RimEclipseView* eclView = nullptr;
m_virtualPerforationResult->firstAncestorOrThisOfTypeAsserted(eclView);
auto coordTransform = eclView->displayCoordTransform();
RimEclipseCase* eclipseCase = nullptr;
m_virtualPerforationResult->firstAncestorOrThisOfTypeAsserted(eclipseCase);
const RigMainGrid* mainGrid = eclipseCase->mainGrid();
const RigVirtualPerforationTransmissibilities* trans = eclipseCase->computeAndGetVirtualPerforationTransmissibilities();
if (!trans) return;
auto conn = trans->multipleCompletionsPerEclipseCell(m_rimWell, frameIndex);
std::vector<std::pair<cvf::Vec3f, double>> centerColorPairs;
for (const auto& cell : conn)
{
size_t gridIndex = cell.first.globalCellIndex();
const RigCell& rigCell = mainGrid->cell(gridIndex);
cvf::Vec3d center = rigCell.center();
cvf::Vec3d displayCoord = coordTransform->transformToDisplayCoord(center);
cvf::Color3f color = cvf::Color3f::BLUE;
double transmissibility = HUGE_VAL;
if (!cell.second.empty())
{
transmissibility = cell.second.front().transmissibility();
}
centerColorPairs.push_back(std::make_pair(cvf::Vec3f(displayCoord), transmissibility));
}
if (!centerColorPairs.empty())
{
double radius = mainGrid->characteristicIJCellSize() * m_virtualPerforationResult->geometryScaleFactor();
auto scalarMapper = m_virtualPerforationResult->legendConfig()->scalarMapper();
cvf::ref<cvf::Part> part = RivVirtualConnFactorPartMgr::createPart(centerColorPairs, radius, scalarMapper);
model->addPart(part.p());
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> RivVirtualConnFactorPartMgr::createPart(std::vector<std::pair<cvf::Vec3f, double>>& centerColorPairs,
double radius,
cvf::ScalarMapper* scalarMapper)
{
cvf::GeometryBuilderTriangles builder;
cvf::GeometryUtils::createSphere(radius, 5, 5, &builder);
auto sphereVertices = builder.vertices();
auto sphereIndices = builder.triangles();
cvf::ref<cvf::Vec3fArray> vertices = new cvf::Vec3fArray;
cvf::ref<cvf::UIntArray> indices = new cvf::UIntArray;
cvf::ref<cvf::Vec2fArray> textureCoords = new cvf::Vec2fArray();
auto indexCount = centerColorPairs.size() * sphereIndices->size();
auto vertexCount = centerColorPairs.size() * sphereVertices->size();
indices->reserve(indexCount);
vertices->reserve(vertexCount);
textureCoords->reserve(vertexCount);
textureCoords->setAll(cvf::Vec2f(0.5f, 1.0f));
for (const auto& centerColorPair : centerColorPairs)
{
cvf::uint indexOffset = static_cast<cvf::uint>(vertices->size());
for (const auto& v : *sphereVertices)
{
vertices->add(centerColorPair.first + v);
if (centerColorPair.second == HUGE_VAL)
{
textureCoords->add(cvf::Vec2f(0.5f, 1.0f));
}
else
{
textureCoords->add(scalarMapper->mapToTextureCoord(centerColorPair.second));
}
}
for (const auto& i : *sphereIndices)
{
indices->add(i + indexOffset);
}
}
cvf::ref<cvf::DrawableGeo> drawable = new cvf::DrawableGeo();
drawable->setVertexArray(vertices.p());
drawable->addPrimitiveSet(new cvf::PrimitiveSetIndexedUInt(cvf::PT_TRIANGLES, indices.p()));
drawable->computeNormals();
drawable->setTextureCoordArray(textureCoords.p());
cvf::ref<cvf::Part> part = new cvf::Part;
part->setDrawable(drawable.p());
caf::ScalarMapperEffectGenerator effGen(scalarMapper, caf::PO_1);
bool disableLighting = false;
effGen.disableLighting(disableLighting);
cvf::ref<cvf::Effect> eff = effGen.generateCachedEffect();
part->setEffect(eff.p());
return part;
}

View File

@ -0,0 +1,67 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfVector3.h"
#include "cafPdmPointer.h"
#include <list>
#include <utility>
#include <vector>
namespace cvf
{
class Part;
class ModelBasicList;
class ScalarMapper;
} // namespace cvf
class RimWellPath;
class RimVirtualPerforationResults;
namespace caf
{
class DisplayCoordTransform;
}
//--------------------------------------------------------------------------------------------------
///
/// Based on RivWellSpheresPartMgr
///
//--------------------------------------------------------------------------------------------------
class RivVirtualConnFactorPartMgr : public cvf::Object
{
public:
RivVirtualConnFactorPartMgr(RimWellPath* well, RimVirtualPerforationResults* virtualPerforationResult);
~RivVirtualConnFactorPartMgr();
void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex);
private:
static cvf::ref<cvf::Part> createPart(std::vector<std::pair<cvf::Vec3f, double>>& centerColorPairs,
double radius,
cvf::ScalarMapper* scalarMapper);
private:
caf::PdmPointer<RimWellPath> m_rimWell;
caf::PdmPointer<RimVirtualPerforationResults> m_virtualPerforationResult;
};

View File

@ -51,6 +51,8 @@
#include "RivWellPathPartMgr.h"
#include "RivWellPathSourceInfo.h"
#include "RiuViewer.h"
#include "cafDisplayCoordTransform.h"
#include "cafEffectGenerator.h"
#include "cvfDrawableGeo.h"
@ -61,6 +63,7 @@
#include "cvfScalarMapperDiscreteLinear.h"
#include "cvfTransform.h"
#include "cvfqtUtils.h"
#include "RivVirtualConnFactorPartMgr.h"
//--------------------------------------------------------------------------------------------------
@ -212,18 +215,21 @@ void RivWellPathPartMgr::appendVirtualTransmissibilitiesToModel(cvf::ModelBasicL
const caf::DisplayCoordTransform* displayCoordTransform,
double characteristicCellSize)
{
RimEclipseView* eclView = dynamic_cast<RimEclipseView*>(m_rimView.p());
if (!eclView) return;
if (!eclView->isVirtualConnectionFactorGeometryVisible()) return;
RimEclipseCase* eclipseCase = nullptr;
m_rimView->firstAncestorOrThisOfType(eclipseCase);
eclView->firstAncestorOrThisOfType(eclipseCase);
if (!eclipseCase) return;
if (!eclipseCase->eclipseCaseData()) return;
RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData();
const RigVirtualPerforationTransmissibilities* trans = eclipseCaseData->virtualPerforationTransmissibilities();
const RigVirtualPerforationTransmissibilities* trans = eclipseCase->computeAndGetVirtualPerforationTransmissibilities();
if (trans)
{
m_virtualConnectionFactorPartMgr = new RivVirtualConnFactorPartMgr(m_rimWellPath, eclView->virtualPerforationResult());
m_virtualConnectionFactorPartMgr->appendDynamicGeometryPartsToModel(model, 0);
}
}
@ -416,6 +422,7 @@ void RivWellPathPartMgr::appendStaticGeometryPartsToModel(cvf::ModelBasicList* m
appendFishboneSubsPartsToModel(model, displayCoordTransform, characteristicCellSize);
appendImportedFishbonesToModel(model, displayCoordTransform, characteristicCellSize);
appendVirtualTransmissibilitiesToModel(model, displayCoordTransform, characteristicCellSize);
}
//--------------------------------------------------------------------------------------------------

View File

@ -46,6 +46,7 @@ class RivFishbonesSubsPartMgr;
class RimWellPathCollection;
class Rim3dView;
class Riv3dWellLogPlanePartMgr;
class RivVirtualConnFactorPartMgr;
class QDateTime;
@ -111,5 +112,6 @@ private:
cvf::ref<cvf::DrawableGeo> m_centerLineDrawable;
cvf::ref<cvf::Part> m_wellLabelPart;
cvf::ref<Riv3dWellLogPlanePartMgr> m_3dWellLogCurvePartMgr;
cvf::ref<Riv3dWellLogPlanePartMgr> m_3dWellLogCurvePartMgr;
cvf::ref<RivVirtualConnFactorPartMgr> m_virtualConnectionFactorPartMgr;
};

View File

@ -24,11 +24,15 @@
#include "RiaColorTables.h"
#include "RiaPreferences.h"
#include "CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h"
#include "CompletionExportCommands/RicExportCompletionDataSettingsUi.h"
#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
#include "RigMainGrid.h"
#include "RigSimWellData.h"
#include "RigVirtualPerforationTransmissibilities.h"
#include "Rim2dIntersectionViewCollection.h"
#include "RimCaseCollection.h"
@ -43,8 +47,10 @@
#include "RimFlowPlotCollection.h"
#include "RimFormationNames.h"
#include "RimIntersectionCollection.h"
#include "RimLegendConfig.h"
#include "RimMainPlotCollection.h"
#include "RimOilField.h"
#include "RimPerforationCollection.h"
#include "RimProject.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimStimPlanColors.h"
@ -53,6 +59,7 @@
#include "RimSummaryPlot.h"
#include "RimSummaryPlotCollection.h"
#include "RimTools.h"
#include "RimVirtualPerforationResults.h"
#include "RimWellAllocationPlot.h"
#include "RimWellLogPlot.h"
#include "RimWellLogPlotCollection.h"
@ -307,6 +314,120 @@ void RimEclipseCase::recalculateCompletionTypeAndRedrawAllViews()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseCase::deleteVirtualConnectionFactorDataAndRedrawRequiredViews()
{
RigEclipseCaseData* rigEclipseCase = eclipseCaseData();
if (rigEclipseCase)
{
rigEclipseCase->setVirtualPerforationTransmissibilities(nullptr);
}
for (Rim3dView* view : views())
{
RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>(view);
if (eclipseView && eclipseView->isVirtualConnectionFactorGeometryVisible())
{
eclipseView->scheduleCreateDisplayModelAndRedraw();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigVirtualPerforationTransmissibilities* RimEclipseCase::computeAndGetVirtualPerforationTransmissibilities()
{
RigEclipseCaseData* rigEclipseCase = eclipseCaseData();
// TODO: Remove
rigEclipseCase->setVirtualPerforationTransmissibilities(nullptr);
if (rigEclipseCase->virtualPerforationTransmissibilities() == nullptr)
{
cvf::ref<RigVirtualPerforationTransmissibilities> perfTrans = new RigVirtualPerforationTransmissibilities;
std::vector<RimWellPath*> visibleWellPaths;
bool anyPerforationsPresent = false;
{
RimProject* proj = RiaApplication::instance()->project();
std::vector<RimWellPath*> wellPaths = proj->allWellPaths();
for (auto w : wellPaths)
{
if (w->showWellPath())
{
visibleWellPaths.push_back(w);
if (!w->perforationIntervalCollection()->perforations().empty())
{
anyPerforationsPresent = true;
}
}
}
}
for (auto w : visibleWellPaths)
{
std::vector<RigCompletionData> staticCompletionData = RicWellPathExportCompletionDataFeatureImpl::computeStaticCompletionsForWellPath(w, this);
if (anyPerforationsPresent)
{
std::vector<std::vector<RigCompletionData>> allCompletionData;
for (size_t i = 0; i < timeStepDates().size(); i++)
{
std::vector<RigCompletionData> dynamicCompletionDataOneTimeStep = RicWellPathExportCompletionDataFeatureImpl::computeDynamicCompletionsForWellPath(w, this, i);
std::copy(staticCompletionData.begin(), staticCompletionData.end(), std::back_inserter(dynamicCompletionDataOneTimeStep));
allCompletionData.push_back(dynamicCompletionDataOneTimeStep);
}
perfTrans->setCompletionDataForWellPath(w, allCompletionData);
}
else
{
std::vector<std::vector<RigCompletionData>> allCompletionData;
allCompletionData.push_back(staticCompletionData);
perfTrans->setCompletionDataForWellPath(w, allCompletionData);
}
}
rigEclipseCase->setVirtualPerforationTransmissibilities(perfTrans.p());
{
double minValue = HUGE_VAL;
double maxValue = -HUGE_VAL;
double posClosestToZero = HUGE_VAL;
double negClosestToZero = -HUGE_VAL;
perfTrans->computeMinMax(&minValue, &maxValue, &posClosestToZero, &negClosestToZero);
if (minValue != HUGE_VAL)
{
for (const auto& v : views())
{
RimEclipseView* eclView = dynamic_cast<RimEclipseView*>(v);
if (eclView)
{
RimLegendConfig* legendConfig = eclView->virtualPerforationResult()->legendConfig();
legendConfig->setAutomaticRanges(minValue, maxValue, minValue, maxValue);
legendConfig->setClosestToZeroValues(posClosestToZero, negClosestToZero, posClosestToZero, negClosestToZero);
}
}
}
}
}
return rigEclipseCase->virtualPerforationTransmissibilities();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -44,6 +44,7 @@ class RimCaseCollection;
class RimIdenticalGridCaseGroup;
class RimReservoirCellResultsStorage;
class RimEclipseView;
class RigVirtualPerforationTransmissibilities;
//==================================================================================================
@ -87,6 +88,9 @@ public:
RimEclipseView* createCopyAndAddView(const RimEclipseView* sourceView);
void recalculateCompletionTypeAndRedrawAllViews();
void deleteVirtualConnectionFactorDataAndRedrawRequiredViews();
const RigVirtualPerforationTransmissibilities* computeAndGetVirtualPerforationTransmissibilities();
virtual QString locationOnDisc() const { return QString(); }
virtual QString gridFileName() const { return QString(); }

View File

@ -227,6 +227,14 @@ RimFaultInViewCollection* RimEclipseView::faultCollection() const
return m_faultCollection;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimVirtualPerforationResults* RimEclipseView::virtualPerforationResult() const
{
return m_virtualPerforationResult();
}
//--------------------------------------------------------------------------------------------------
/// Clamp the current timestep to actual possibilities
//--------------------------------------------------------------------------------------------------
@ -1070,6 +1078,13 @@ void RimEclipseView::updateLegends()
m_viewer->addColorLegendToBottomLeftCorner(stimPlanLegend->legend());
}
}
if (m_virtualPerforationResult->isActive())
{
RimLegendConfig* virtLegend = m_virtualPerforationResult->legendConfig();
m_viewer->addColorLegendToBottomLeftCorner(virtLegend->legend());
}
}
//--------------------------------------------------------------------------------------------------
@ -1373,6 +1388,20 @@ void RimEclipseView::calculateCompletionTypeAndRedrawIfRequired()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseView::isVirtualConnectionFactorGeometryVisible() const
{
if (!m_showWindow()) return false;
if (!m_virtualPerforationResult->isActive()) return false;
// TODO: Consider check if no well paths are visible
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -85,7 +85,8 @@ public:
RimStimPlanColors* fractureColors() const;
RimSimWellInViewCollection* wellCollection() const;
RimFaultInViewCollection* faultCollection() const;
RimVirtualPerforationResults* virtualPerforationResult() const;
bool showInvalidCells() const;
bool showInactiveCells() const;
bool showMainGrid() const;
@ -118,6 +119,9 @@ public:
void calculateCompletionTypeAndRedrawIfRequired();
bool isVirtualConnectionFactorGeometryVisible() const;
const std::vector<RivCellSetEnum>& visibleGridParts() const;
const RivReservoirViewPartMgr* reservoirGridPartManager() const;
RivReservoirViewPartMgr* reservoirGridPartManager();

View File

@ -19,6 +19,7 @@
#include "RimVirtualPerforationResults.h"
#include "RimLegendConfig.h"
#include "RimEclipseView.h"
@ -32,11 +33,14 @@ RimVirtualPerforationResults::RimVirtualPerforationResults()
{
CAF_PDM_InitObject("Virtual Perforation Results", ":/CellResult.png", "", "");
CAF_PDM_InitFieldNoDefault(&legendConfig, "LegendDefinition", "Legend Definition", "", "", "");
this->legendConfig = new RimLegendConfig();
legendConfig.uiCapability()->setUiHidden(true);
CAF_PDM_InitField(&m_isActive, "ShowConnectionFactors", true, "", "", "", "");
CAF_PDM_InitField(&m_geometryScaleFactor, "GeometryScaleFactor", 0.2, "Geometry Scale Factor", "", "", "");
CAF_PDM_InitField(&m_showTensors, "ShowTensors", true, "", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_legendConfig, "LegendDefinition", "Legend Definition", "", "", "");
m_legendConfig.uiCapability()->setUiHidden(true);
m_legendConfig = new RimLegendConfig();
m_legendConfig->setTitle("Virtual Connection Factor");
}
//--------------------------------------------------------------------------------------------------
@ -47,12 +51,39 @@ RimVirtualPerforationResults::~RimVirtualPerforationResults()
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimVirtualPerforationResults::isActive() const
{
return m_isActive();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimVirtualPerforationResults::geometryScaleFactor() const
{
return m_geometryScaleFactor();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimLegendConfig* RimVirtualPerforationResults::legendConfig() const
{
return m_legendConfig();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimVirtualPerforationResults::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
RimEclipseView* eclView = nullptr;
this->firstAncestorOrThisOfTypeAsserted(eclView);
eclView->scheduleCreateDisplayModelAndRedraw();
}
//--------------------------------------------------------------------------------------------------
@ -60,7 +91,7 @@ void RimVirtualPerforationResults::fieldChangedByUi(const caf::PdmFieldHandle* c
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimVirtualPerforationResults::objectToggleField()
{
return &m_showTensors;
return &m_isActive;
}
//--------------------------------------------------------------------------------------------------
@ -79,6 +110,8 @@ QList<caf::PdmOptionItemInfo> RimVirtualPerforationResults::calculateValueOption
//--------------------------------------------------------------------------------------------------
void RimVirtualPerforationResults::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
uiOrdering.add(&m_geometryScaleFactor);
uiOrdering.skipRemainingFields(true);
}

View File

@ -35,11 +35,14 @@ class RimVirtualPerforationResults : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimVirtualPerforationResults();
virtual ~RimVirtualPerforationResults();
bool isActive() const;
double geometryScaleFactor() const;
RimLegendConfig* legendConfig() const;
private:
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
virtual caf::PdmFieldHandle* objectToggleField() override;
@ -47,7 +50,8 @@ private:
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
private:
caf::PdmField<bool> m_showTensors;
caf::PdmField<bool> m_isActive;
caf::PdmField<double> m_geometryScaleFactor;
caf::PdmChildField<RimLegendConfig*> legendConfig;
caf::PdmChildField<RimLegendConfig*> m_legendConfig;
};

View File

@ -17,6 +17,7 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RigVirtualPerforationTransmissibilities.h"
#include "RigStatisticsMath.h"
//--------------------------------------------------------------------------------------------------
///
@ -44,9 +45,10 @@ void CompletionDataFrame::setCompletionData(const std::vector<RigCompletionData>
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
const std::map<RigCompletionDataGridCell, std::vector<RigCompletionData>>& CompletionDataFrame::multipleCompletionsPerEclipseCell() const
const std::map<RigCompletionDataGridCell, std::vector<RigCompletionData>>&
CompletionDataFrame::multipleCompletionsPerEclipseCell() const
{
return m_multipleCompletionsPerEclipseCell;
}
@ -64,29 +66,28 @@ RigVirtualPerforationTransmissibilities::~RigVirtualPerforationTransmissibilitie
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigVirtualPerforationTransmissibilities::appendCompletionDataForWellPath(
RimWellPath* wellPath,
const std::vector<RigCompletionData>& completions)
void RigVirtualPerforationTransmissibilities::setCompletionDataForWellPath(
RimWellPath* wellPath,
std::vector<std::vector<RigCompletionData>>& completionsPerTimeStep)
{
/*
auto item = m_mapFromWellToCompletionData.find(wellPath);
if (item != m_mapFromWellToCompletionData.end())
{
item->second.setCompletionData
}
auto it = m_multipleCompletionsPerEclipseCell.find(completion.completionDataGridCell());
if (it != m_multipleCompletionsPerEclipseCell.end())
{
it->second.push_back(completion);
}
else
{
m_multipleCompletionsPerEclipseCell.insert(std::pair<RigCompletionDataGridCell, std::vector<RigCompletionData>>(
completion.completionDataGridCell(), std::vector<RigCompletionData>{completion}));
}
*/
CVF_ASSERT(item == m_mapFromWellToCompletionData.end());
{
std::vector<CompletionDataFrame> values;
for (const auto& c : completionsPerTimeStep)
{
CompletionDataFrame oneTimeStep;
oneTimeStep.setCompletionData(c);
values.push_back(oneTimeStep);
}
auto pair = std::pair<RimWellPath*, std::vector<CompletionDataFrame>>(wellPath, values);
m_mapFromWellToCompletionData.insert(pair);
}
}
//--------------------------------------------------------------------------------------------------
@ -100,8 +101,50 @@ const std::map<RigCompletionDataGridCell, std::vector<RigCompletionData>>&
auto item = m_mapFromWellToCompletionData.find(wellPath);
if (item != m_mapFromWellToCompletionData.end())
{
return item->second[timeStepIndex].multipleCompletionsPerEclipseCell();
size_t indexToUse = timeStepIndex;
if (item->second.size() == 1)
{
indexToUse = 0;
}
return item->second[indexToUse].multipleCompletionsPerEclipseCell();
}
return dummy;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigVirtualPerforationTransmissibilities::computeMinMax(double* minValue, double* maxValue, double* posClosestToZero, double* negClosestToZero) const
{
MinMaxAccumulator minMaxAccumulator;
PosNegAccumulator posNegAccumulator;
for (const auto& item : m_mapFromWellToCompletionData)
{
auto completionDataFrame = item.second;
for (const auto& data : completionDataFrame)
{
for (const auto& data : completionDataFrame)
{
auto compl = data.multipleCompletionsPerEclipseCell();
for (const auto& c : compl)
{
for (const auto& d : c.second)
{
double trans = d.transmissibility();
minMaxAccumulator.addValue(trans);
posNegAccumulator.addValue(trans);
}
}
}
}
}
if (*minValue) *minValue = minMaxAccumulator.min;
if (*maxValue) *maxValue = minMaxAccumulator.max;
if (*posClosestToZero) *posClosestToZero = posNegAccumulator.pos;
if (*negClosestToZero) *negClosestToZero = posNegAccumulator.neg;
}

View File

@ -40,8 +40,7 @@ public:
void setCompletionData(const std::vector<RigCompletionData>& completions);
const std::map<RigCompletionDataGridCell, std::vector<RigCompletionData>>&
multipleCompletionsPerEclipseCell() const;
const std::map<RigCompletionDataGridCell, std::vector<RigCompletionData>>& multipleCompletionsPerEclipseCell() const;
private:
std::map<RigCompletionDataGridCell, std::vector<RigCompletionData>> m_multipleCompletionsPerEclipseCell;
@ -56,12 +55,12 @@ public:
RigVirtualPerforationTransmissibilities();
~RigVirtualPerforationTransmissibilities();
void appendCompletionDataForWellPath(RimWellPath* wellPath,
const std::vector<RigCompletionData>& completions);
void setCompletionDataForWellPath(RimWellPath* wellPath, std::vector<std::vector<RigCompletionData>>& completionsPerTimeStep);
const std::map<RigCompletionDataGridCell, std::vector<RigCompletionData>>&
multipleCompletionsPerEclipseCell(RimWellPath* wellPath, size_t timeStepIndex) const;
void computeMinMax(double* minValue, double* maxValue, double* posClosestToZero, double* negClosestToZero) const;
private:
std::map<RimWellPath*, std::vector<CompletionDataFrame>> m_mapFromWellToCompletionData;
};

View File

@ -533,7 +533,7 @@ void RigEclipseCaseData::setVirtualPerforationTransmissibilities(RigVirtualPerfo
//--------------------------------------------------------------------------------------------------
const RigVirtualPerforationTransmissibilities* RigEclipseCaseData::virtualPerforationTransmissibilities() const
{
return m_virtualPerforationTransmissibilities;
return m_virtualPerforationTransmissibilities.p();
}
//--------------------------------------------------------------------------------------------------

View File

@ -131,7 +131,7 @@ private:
cvf::ref<RigFormationNames> m_activeFormationNamesData;
RigVirtualPerforationTransmissibilities* m_virtualPerforationTransmissibilities;
cvf::ref<RigVirtualPerforationTransmissibilities> m_virtualPerforationTransmissibilities;
cvf::Collection<RigSimWellData> m_simWellData; //< A WellResults object for each well in the reservoir
cvf::Collection<cvf::UByteArray> m_wellCellsInGrid; //< A bool array pr grid with one bool pr cell telling whether the cell is a well cell or not