Merge branch 'dev' into hdf-prototype

This commit is contained in:
Magne Sjaastad
2017-08-14 10:47:44 +02:00
443 changed files with 20467 additions and 3429 deletions

View File

@@ -15,8 +15,10 @@ ${CEE_CURRENT_LIST_DIR}RigResultAccessorFactory.h
${CEE_CURRENT_LIST_DIR}RigAllGridCellsResultAccessor.h
${CEE_CURRENT_LIST_DIR}RigActiveCellsResultAccessor.h
${CEE_CURRENT_LIST_DIR}RigCellEdgeResultAccessor.h
${CEE_CURRENT_LIST_DIR}RigCellGeometryTools.h
${CEE_CURRENT_LIST_DIR}RigCombTransResultAccessor.h
${CEE_CURRENT_LIST_DIR}RigCombMultResultAccessor.h
${CEE_CURRENT_LIST_DIR}RigCompletionData.h
${CEE_CURRENT_LIST_DIR}RigResultModifier.h
${CEE_CURRENT_LIST_DIR}RigResultModifierFactory.h
${CEE_CURRENT_LIST_DIR}RigFormationNames.h
@@ -46,11 +48,20 @@ ${CEE_CURRENT_LIST_DIR}RigEclipseNativeStatCalc.h
${CEE_CURRENT_LIST_DIR}RigEclipseNativeVisibleCellsStatCalc.h
${CEE_CURRENT_LIST_DIR}RigEclipseMultiPropertyStatCalc.h
${CEE_CURRENT_LIST_DIR}RigWellLogCurveData.h
${CEE_CURRENT_LIST_DIR}RigWellLogExtractionTools.h
${CEE_CURRENT_LIST_DIR}RigHexIntersectionTools.h
${CEE_CURRENT_LIST_DIR}RigTimeHistoryResultAccessor.h
${CEE_CURRENT_LIST_DIR}RigCurveDataTools.h
${CEE_CURRENT_LIST_DIR}RigSummaryCaseData.h
${CEE_CURRENT_LIST_DIR}RigLasFileExporter.h
${CEE_CURRENT_LIST_DIR}RigSimulationWellCoordsAndMD.h
${CEE_CURRENT_LIST_DIR}RigFishbonesGeometry.h
${CEE_CURRENT_LIST_DIR}RigWellPathIntersectionTools.h
${CEE_CURRENT_LIST_DIR}RigTransmissibilityEquations.h
${CEE_CURRENT_LIST_DIR}RigEclipseResultInfo.h
${CEE_CURRENT_LIST_DIR}RigTofAccumulatedPhaseFractionsCalculator.h
)
set (SOURCE_GROUP_SOURCE_FILES
@@ -64,8 +75,10 @@ ${CEE_CURRENT_LIST_DIR}RigResultAccessorFactory.cpp
${CEE_CURRENT_LIST_DIR}RigAllGridCellsResultAccessor.cpp
${CEE_CURRENT_LIST_DIR}RigActiveCellsResultAccessor.cpp
${CEE_CURRENT_LIST_DIR}RigCellEdgeResultAccessor.cpp
${CEE_CURRENT_LIST_DIR}RigCellGeometryTools.cpp
${CEE_CURRENT_LIST_DIR}RigCombTransResultAccessor.cpp
${CEE_CURRENT_LIST_DIR}RigCombMultResultAccessor.cpp
${CEE_CURRENT_LIST_DIR}RigCompletionData.cpp
${CEE_CURRENT_LIST_DIR}RigResultModifierFactory.cpp
${CEE_CURRENT_LIST_DIR}RigFormationNames.cpp
${CEE_CURRENT_LIST_DIR}RigFlowDiagResultAddress.cpp
@@ -91,11 +104,18 @@ ${CEE_CURRENT_LIST_DIR}RigEclipseNativeStatCalc.cpp
${CEE_CURRENT_LIST_DIR}RigEclipseNativeVisibleCellsStatCalc.cpp
${CEE_CURRENT_LIST_DIR}RigEclipseMultiPropertyStatCalc.cpp
${CEE_CURRENT_LIST_DIR}RigWellLogCurveData.cpp
${CEE_CURRENT_LIST_DIR}RigHexIntersectionTools.cpp
${CEE_CURRENT_LIST_DIR}RigTimeHistoryResultAccessor.cpp
${CEE_CURRENT_LIST_DIR}RigCurveDataTools.cpp
${CEE_CURRENT_LIST_DIR}RigSummaryCaseData.cpp
${CEE_CURRENT_LIST_DIR}RigLasFileExporter.cpp
${CEE_CURRENT_LIST_DIR}RigSimulationWellCoordsAndMD.cpp
${CEE_CURRENT_LIST_DIR}RigFishbonesGeometry.cpp
${CEE_CURRENT_LIST_DIR}RigWellPathIntersectionTools.cpp
${CEE_CURRENT_LIST_DIR}RigTransmissibilityEquations.cpp
${CEE_CURRENT_LIST_DIR}RigEclipseResultInfo.cpp
${CEE_CURRENT_LIST_DIR}RigTofAccumulatedPhaseFractionsCalculator.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@@ -11,6 +11,7 @@ set (SOURCE_GROUP_HEADER_FILES
${CEE_CURRENT_LIST_DIR}RigCaseToCaseRangeFilterMapper.h
${CEE_CURRENT_LIST_DIR}RigSimulationWellCenterLineCalculator.h
${CEE_CURRENT_LIST_DIR}RigWellLogFile.h
${CEE_CURRENT_LIST_DIR}RigReservoirGridTools.h
)
set (SOURCE_GROUP_SOURCE_FILES
@@ -20,6 +21,7 @@ set (SOURCE_GROUP_SOURCE_FILES
${CEE_CURRENT_LIST_DIR}RigCaseToCaseRangeFilterMapper.cpp
${CEE_CURRENT_LIST_DIR}RigSimulationWellCenterLineCalculator.cpp
${CEE_CURRENT_LIST_DIR}RigWellLogFile.cpp
${CEE_CURRENT_LIST_DIR}RigReservoirGridTools.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@@ -20,13 +20,15 @@
#include "RigCaseCellResultsData.h"
#include "RigMainGrid.h"
#include "RigStatisticsDataCache.h"
#include "RigStatisticsMath.h"
#include "RigEclipseMultiPropertyStatCalc.h"
#include "RigEclipseNativeStatCalc.h"
#include "RigMainGrid.h"
#include "RigEclipseResultInfo.h"
#include "RigStatisticsDataCache.h"
#include "RigStatisticsMath.h"
#include <QDateTime>
#include <math.h>
@@ -203,9 +205,9 @@ std::vector<double>& RigCaseCellResultsData::cellScalarResults(size_t scalarResu
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigCaseCellResultsData::findScalarResultIndex(RimDefines::ResultCatType type, const QString& resultName) const
size_t RigCaseCellResultsData::findScalarResultIndex(RiaDefines::ResultCatType type, const QString& resultName) const
{
std::vector<ResultInfo>::const_iterator it;
std::vector<RigEclipseResultInfo>::const_iterator it;
for (it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it)
{
if (it->m_resultType == type && it->m_resultName == resultName)
@@ -222,31 +224,31 @@ size_t RigCaseCellResultsData::findScalarResultIndex(RimDefines::ResultCatType t
//--------------------------------------------------------------------------------------------------
size_t RigCaseCellResultsData::findScalarResultIndex(const QString& resultName) const
{
size_t scalarResultIndex = this->findScalarResultIndex(RimDefines::STATIC_NATIVE, resultName);
size_t scalarResultIndex = this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, resultName);
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{
scalarResultIndex = this->findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, resultName);
scalarResultIndex = this->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, resultName);
}
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{
scalarResultIndex = this->findScalarResultIndex(RimDefines::SOURSIMRL, resultName);
scalarResultIndex = this->findScalarResultIndex(RiaDefines::SOURSIMRL, resultName);
}
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{
scalarResultIndex = this->findScalarResultIndex(RimDefines::GENERATED, resultName);
scalarResultIndex = this->findScalarResultIndex(RiaDefines::GENERATED, resultName);
}
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{
scalarResultIndex = this->findScalarResultIndex(RimDefines::INPUT_PROPERTY, resultName);
scalarResultIndex = this->findScalarResultIndex(RiaDefines::INPUT_PROPERTY, resultName);
}
if(scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{
scalarResultIndex = this->findScalarResultIndex(RimDefines::FORMATION_NAMES, resultName);
scalarResultIndex = this->findScalarResultIndex(RiaDefines::FORMATION_NAMES, resultName);
}
return scalarResultIndex;
@@ -256,7 +258,7 @@ size_t RigCaseCellResultsData::findScalarResultIndex(const QString& resultName)
/// Adds an empty scalar set, and returns the scalarResultIndex to it.
/// if resultName already exists, it just returns the scalarResultIndex to the existing result.
//--------------------------------------------------------------------------------------------------
size_t RigCaseCellResultsData::addEmptyScalarResult(RimDefines::ResultCatType type, const QString& resultName, bool needsToBeStored)
size_t RigCaseCellResultsData::addEmptyScalarResult(RiaDefines::ResultCatType type, const QString& resultName, bool needsToBeStored)
{
size_t scalarResultIndex = this->findScalarResultIndex(type, resultName);
@@ -271,7 +273,7 @@ size_t RigCaseCellResultsData::addEmptyScalarResult(RimDefines::ResultCatType ty
scalarResultIndex = this->resultCount();
m_cellScalarResults.push_back(std::vector<std::vector<double> >());
ResultInfo resInfo(type, needsToBeStored, false, resultName, scalarResultIndex);
RigEclipseResultInfo resInfo(type, needsToBeStored, false, resultName, scalarResultIndex);
m_resultInfos.push_back(resInfo);
// Create statistics calculator and add statistics cache object
@@ -279,84 +281,84 @@ size_t RigCaseCellResultsData::addEmptyScalarResult(RimDefines::ResultCatType ty
cvf::ref<RigStatisticsCalculator> statisticsCalculator;
if (resultName == RimDefines::combinedTransmissibilityResultName())
if (resultName == RiaDefines::combinedTransmissibilityResultName())
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANX"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANY"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANZ"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, "TRANX"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, "TRANY"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, "TRANZ"));
statisticsCalculator = calc;
}
else if (resultName == RimDefines::combinedMultResultName())
else if (resultName == RiaDefines::combinedMultResultName())
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "MULTX"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "MULTX-"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "MULTY"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "MULTY-"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "MULTZ"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "MULTZ-"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, "MULTX"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, "MULTX-"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, "MULTY"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, "MULTY-"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, "MULTZ"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, "MULTZ-"));
statisticsCalculator = calc;
}
else if (resultName == RimDefines::combinedRiTranResultName())
else if (resultName == RiaDefines::combinedRiTranResultName())
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riTranXResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riTranYResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riTranZResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranXResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranYResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranZResultName()));
statisticsCalculator = calc;
}
else if (resultName == RimDefines::combinedRiMultResultName())
else if (resultName == RiaDefines::combinedRiMultResultName())
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riMultXResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riMultYResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riMultZResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riMultXResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riMultYResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riMultZResultName()));
statisticsCalculator = calc;
}
else if (resultName == RimDefines::combinedRiAreaNormTranResultName())
else if (resultName == RiaDefines::combinedRiAreaNormTranResultName())
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riAreaNormTranXResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riAreaNormTranYResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riAreaNormTranZResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranXResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranYResultName()));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranZResultName()));
statisticsCalculator = calc;
}
else if (resultName == RimDefines::combinedWaterFluxResultName())
else if (resultName == RiaDefines::combinedWaterFluxResultName())
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLRWATI+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLRWATJ+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLRWATK+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRWATI+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRWATJ+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRWATK+"));
statisticsCalculator = calc;
}
else if (resultName == RimDefines::combinedOilFluxResultName())
else if (resultName == RiaDefines::combinedOilFluxResultName())
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLROILI+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLROILJ+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLROILK+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLROILI+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLROILJ+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLROILK+"));
statisticsCalculator = calc;
}
else if (resultName == RimDefines::combinedGasFluxResultName())
else if (resultName == RiaDefines::combinedGasFluxResultName())
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLRGASI+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLRGASJ+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLRGASK+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRGASI+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRGASJ+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRGASK+"));
statisticsCalculator = calc;
}
else if (resultName.endsWith("IJK"))
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
QString baseName = resultName.left(resultName.size() - 3);
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::GENERATED, QString("%1I").arg(baseName)));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::GENERATED, QString("%1J").arg(baseName)));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::GENERATED, QString("%1K").arg(baseName)));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::GENERATED, QString("%1I").arg(baseName)));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::GENERATED, QString("%1J").arg(baseName)));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::GENERATED, QString("%1K").arg(baseName)));
statisticsCalculator = calc;
}
else
@@ -374,10 +376,10 @@ size_t RigCaseCellResultsData::addEmptyScalarResult(RimDefines::ResultCatType ty
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QStringList RigCaseCellResultsData::resultNames(RimDefines::ResultCatType resType) const
QStringList RigCaseCellResultsData::resultNames(RiaDefines::ResultCatType resType) const
{
QStringList varList;
std::vector<ResultInfo>::const_iterator it;
std::vector<RigEclipseResultInfo>::const_iterator it;
for (it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it)
{
if (it->m_resultType == resType )
@@ -416,7 +418,7 @@ bool RigCaseCellResultsData::isUsingGlobalActiveIndex(size_t scalarResultIndex)
//--------------------------------------------------------------------------------------------------
bool RigCaseCellResultsData::hasFlowDiagUsableFluxes() const
{
QStringList dynResVarNames = resultNames(RimDefines::DYNAMIC_NATIVE);
QStringList dynResVarNames = resultNames(RiaDefines::DYNAMIC_NATIVE);
bool hasFlowFluxes = true;
hasFlowFluxes = dynResVarNames.contains("FLRWATI+");
@@ -430,8 +432,8 @@ bool RigCaseCellResultsData::hasFlowDiagUsableFluxes() const
//--------------------------------------------------------------------------------------------------
QDateTime RigCaseCellResultsData::timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const
{
if (scalarResultIndex < m_resultInfos.size() && m_resultInfos[scalarResultIndex].m_timeStepDates.size() > timeStepIndex)
return m_resultInfos[scalarResultIndex].m_timeStepDates[timeStepIndex];
if (scalarResultIndex < m_resultInfos.size() && m_resultInfos[scalarResultIndex].m_timeStepInfos.size() > timeStepIndex)
return m_resultInfos[scalarResultIndex].m_timeStepInfos[timeStepIndex].m_date;
else
return QDateTime();
}
@@ -442,7 +444,9 @@ QDateTime RigCaseCellResultsData::timeStepDate(size_t scalarResultIndex, size_t
std::vector<QDateTime> RigCaseCellResultsData::timeStepDates(size_t scalarResultIndex) const
{
if (scalarResultIndex < m_resultInfos.size())
return m_resultInfos[scalarResultIndex].m_timeStepDates;
{
return m_resultInfos[scalarResultIndex].dates();
}
else
return std::vector<QDateTime>();
}
@@ -476,7 +480,7 @@ std::vector<double> RigCaseCellResultsData::daysSinceSimulationStart(size_t scal
{
if (scalarResultIndex < m_resultInfos.size())
{
return m_resultInfos[scalarResultIndex].m_daysSinceSimulationStart;
return m_resultInfos[scalarResultIndex].daysSinceSimulationStarts();
}
else
{
@@ -489,8 +493,8 @@ std::vector<double> RigCaseCellResultsData::daysSinceSimulationStart(size_t scal
//--------------------------------------------------------------------------------------------------
int RigCaseCellResultsData::reportStepNumber(size_t scalarResultIndex, size_t timeStepIndex) const
{
if (scalarResultIndex < m_resultInfos.size() && m_resultInfos[scalarResultIndex].m_timeStepReportNumbers.size() > timeStepIndex)
return m_resultInfos[scalarResultIndex].m_timeStepReportNumbers[timeStepIndex];
if (scalarResultIndex < m_resultInfos.size() && m_resultInfos[scalarResultIndex].m_timeStepInfos.size() > timeStepIndex)
return m_resultInfos[scalarResultIndex].m_timeStepInfos[timeStepIndex].m_reportNumber;
else
return -1;
}
@@ -501,25 +505,33 @@ int RigCaseCellResultsData::reportStepNumber(size_t scalarResultIndex, size_t ti
std::vector<int> RigCaseCellResultsData::reportStepNumbers(size_t scalarResultIndex) const
{
if (scalarResultIndex < m_resultInfos.size() )
return m_resultInfos[scalarResultIndex].m_timeStepReportNumbers;
return m_resultInfos[scalarResultIndex].reportNumbers();
else
return std::vector<int>();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigCaseCellResultsData::setTimeStepDates(size_t scalarResultIndex, const std::vector<QDateTime>& dates, const std::vector<double>& daysSinceSimulationStart, const std::vector<int>& reportStepNumbers)
std::vector<RigEclipseTimeStepInfo> RigCaseCellResultsData::timeStepInfos(size_t scalarResultIndex) const
{
if (scalarResultIndex < m_resultInfos.size())
return m_resultInfos[scalarResultIndex].m_timeStepInfos;
else
return std::vector<RigEclipseTimeStepInfo>();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigCaseCellResultsData::setTimeStepInfos(size_t scalarResultIndex, const std::vector<RigEclipseTimeStepInfo>& timeStepInfos)
{
CVF_ASSERT(scalarResultIndex < m_resultInfos.size() );
m_resultInfos[scalarResultIndex].m_timeStepDates = dates;
m_resultInfos[scalarResultIndex].m_daysSinceSimulationStart = daysSinceSimulationStart;
m_resultInfos[scalarResultIndex].m_timeStepReportNumbers = reportStepNumbers;
m_resultInfos[scalarResultIndex].m_timeStepInfos = timeStepInfos;
std::vector< std::vector<double> >& dataValues = this->cellScalarResults(scalarResultIndex);
dataValues.resize(dates.size());
dataValues.resize(timeStepInfos.size());
}
//--------------------------------------------------------------------------------------------------
@@ -532,9 +544,9 @@ size_t RigCaseCellResultsData::maxTimeStepCount(size_t* scalarResultIndexWithMos
for (size_t i = 0; i < m_resultInfos.size(); i++)
{
if (m_resultInfos[i].m_timeStepDates.size() > maxTsCount)
if (m_resultInfos[i].m_timeStepInfos.size() > maxTsCount)
{
maxTsCount = m_resultInfos[i].m_timeStepDates.size();
maxTsCount = m_resultInfos[i].m_timeStepInfos.size();
scalarResultIndexWithMaxTsCount = i;
}
}
@@ -579,7 +591,7 @@ void RigCaseCellResultsData::removeResult(const QString& resultName)
m_cellScalarResults[resultIdx].clear();
m_resultInfos[resultIdx].m_resultType = RimDefines::REMOVED;
m_resultInfos[resultIdx].m_resultType = RiaDefines::REMOVED;
}
//--------------------------------------------------------------------------------------------------
@@ -613,7 +625,7 @@ void RigCaseCellResultsData::freeAllocatedResultsData()
/// Make sure we have a result with given type and name, and make sure one "timestep" result vector
// for the static result values are allocated
//--------------------------------------------------------------------------------------------------
size_t RigCaseCellResultsData::addStaticScalarResult(RimDefines::ResultCatType type, const QString& resultName, bool needsToBeStored, size_t resultValueCount)
size_t RigCaseCellResultsData::addStaticScalarResult(RiaDefines::ResultCatType type, const QString& resultName, bool needsToBeStored, size_t resultValueCount)
{
size_t resultIdx = addEmptyScalarResult(type, resultName, needsToBeStored);
@@ -626,17 +638,7 @@ size_t RigCaseCellResultsData::addStaticScalarResult(RimDefines::ResultCatType t
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifReaderInterface::PorosityModelResultType RigCaseCellResultsData::convertFromProjectModelPorosityModel(RimDefines::PorosityModelType porosityModel)
{
if (porosityModel == RimDefines::MATRIX_MODEL) return RifReaderInterface::MATRIX_RESULTS;
return RifReaderInterface::FRACTURE_RESULTS;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigCaseCellResultsData::updateResultName(RimDefines::ResultCatType resultType, QString& oldName, const QString& newName)
bool RigCaseCellResultsData::updateResultName(RiaDefines::ResultCatType resultType, QString& oldName, const QString& newName)
{
bool anyNameUpdated = false;
@@ -657,7 +659,7 @@ bool RigCaseCellResultsData::updateResultName(RimDefines::ResultCatType resultTy
//--------------------------------------------------------------------------------------------------
bool RigCaseCellResultsData::mustBeCalculated(size_t scalarResultIndex) const
{
std::vector<ResultInfo>::const_iterator it;
std::vector<RigEclipseResultInfo>::const_iterator it;
for (it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it)
{
if (it->m_gridScalarResultIndex == scalarResultIndex)
@@ -674,7 +676,7 @@ bool RigCaseCellResultsData::mustBeCalculated(size_t scalarResultIndex) const
//--------------------------------------------------------------------------------------------------
void RigCaseCellResultsData::setMustBeCalculated(size_t scalarResultIndex)
{
std::vector<ResultInfo>::iterator it;
std::vector<RigEclipseResultInfo>::iterator it;
for (it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it)
{
if (it->m_gridScalarResultIndex == scalarResultIndex)
@@ -693,10 +695,10 @@ void RigCaseCellResultsData::eraseAllSourSimData()
for (size_t i = 0; i < m_resultInfos.size(); i++)
{
ResultInfo& ri = m_resultInfos[i];
if (ri.m_resultType == RimDefines::SOURSIMRL)
RigEclipseResultInfo& ri = m_resultInfos[i];
if (ri.m_resultType == RiaDefines::SOURSIMRL)
{
ri.m_resultType = RimDefines::REMOVED;
ri.m_resultType = RiaDefines::REMOVED;
}
}
}
@@ -708,45 +710,54 @@ void RigCaseCellResultsData::createPlaceholderResultEntries()
{
// SOIL
{
size_t soilIndex = findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "SOIL");
size_t soilIndex = findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SOIL");
if (soilIndex == cvf::UNDEFINED_SIZE_T)
{
size_t swatIndex = findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "SWAT");
size_t sgasIndex = findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "SGAS");
size_t swatIndex = findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SWAT");
size_t sgasIndex = findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SGAS");
if (swatIndex != cvf::UNDEFINED_SIZE_T || sgasIndex != cvf::UNDEFINED_SIZE_T)
{
soilIndex = addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL", false);
soilIndex = addEmptyScalarResult(RiaDefines::DYNAMIC_NATIVE, "SOIL", false);
this->setMustBeCalculated(soilIndex);
}
}
}
// Completion type
{
size_t completionTypeIndex = findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::completionTypeResultName());
if (completionTypeIndex == cvf::UNDEFINED_SIZE_T)
{
addEmptyScalarResult(RiaDefines::DYNAMIC_NATIVE, RiaDefines::completionTypeResultName(), false);
}
}
// FLUX
{
size_t waterIndex = findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, RimDefines::combinedWaterFluxResultName());
size_t waterIndex = findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedWaterFluxResultName());
if (waterIndex == cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLRWATI+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLRWATJ+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLRWATK+") != cvf::UNDEFINED_SIZE_T)
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRWATI+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRWATJ+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRWATK+") != cvf::UNDEFINED_SIZE_T)
{
addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, RimDefines::combinedWaterFluxResultName(), false);
addEmptyScalarResult(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedWaterFluxResultName(), false);
}
size_t oilIndex = findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, RimDefines::combinedOilFluxResultName());
size_t oilIndex = findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedOilFluxResultName());
if (oilIndex == cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLROILI+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLROILJ+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLROILK+") != cvf::UNDEFINED_SIZE_T)
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLROILI+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLROILJ+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLROILK+") != cvf::UNDEFINED_SIZE_T)
{
addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, RimDefines::combinedOilFluxResultName(), false);
addEmptyScalarResult(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedOilFluxResultName(), false);
}
size_t gasIndex = findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, RimDefines::combinedGasFluxResultName());
size_t gasIndex = findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedGasFluxResultName());
if (gasIndex == cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLRGASI+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLRGASJ+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "FLRGASK+") != cvf::UNDEFINED_SIZE_T)
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRGASI+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRGASJ+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRGASK+") != cvf::UNDEFINED_SIZE_T)
{
addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, RimDefines::combinedGasFluxResultName(), false);
addEmptyScalarResult(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedGasFluxResultName(), false);
}
}
@@ -755,24 +766,24 @@ void RigCaseCellResultsData::createPlaceholderResultEntries()
size_t tranX, tranY, tranZ;
if (findTransmissibilityResults(tranX, tranY, tranZ))
{
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::combinedTransmissibilityResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName(), false, 0);
}
}
// MULTXYZ
{
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::combinedMultResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::combinedMultResultName(), false, 0);
}
// riTRANSXYZ and X,Y,Z
{
if ( findScalarResultIndex(RimDefines::STATIC_NATIVE, "PERMX") != cvf::UNDEFINED_SIZE_T
&& findScalarResultIndex(RimDefines::STATIC_NATIVE, "PERMY") != cvf::UNDEFINED_SIZE_T
&& findScalarResultIndex(RimDefines::STATIC_NATIVE, "PERMZ") != cvf::UNDEFINED_SIZE_T)
if ( findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PERMX") != cvf::UNDEFINED_SIZE_T
&& findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PERMY") != cvf::UNDEFINED_SIZE_T
&& findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PERMZ") != cvf::UNDEFINED_SIZE_T)
{
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riTranXResultName(), false, 0);
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riTranYResultName(), false, 0);
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riTranZResultName(), false, 0);
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::combinedRiTranResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riTranXResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riTranYResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riTranZResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiTranResultName(), false, 0);
}
}
@@ -780,38 +791,38 @@ void RigCaseCellResultsData::createPlaceholderResultEntries()
{
size_t tranX, tranY, tranZ;
if (findTransmissibilityResults(tranX, tranY, tranZ)
&& findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riTranXResultName()) != cvf::UNDEFINED_SIZE_T
&& findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riTranYResultName()) != cvf::UNDEFINED_SIZE_T
&& findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riTranZResultName()) != cvf::UNDEFINED_SIZE_T)
&& findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranXResultName()) != cvf::UNDEFINED_SIZE_T
&& findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranYResultName()) != cvf::UNDEFINED_SIZE_T
&& findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranZResultName()) != cvf::UNDEFINED_SIZE_T)
{
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riMultXResultName(), false, 0);
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riMultYResultName(), false, 0);
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riMultZResultName(), false, 0);
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::combinedRiMultResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riMultXResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riMultYResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riMultZResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiMultResultName(), false, 0);
}
}
// riTRANSXYZbyArea and X, Y, Z
{
if (findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANX") != cvf::UNDEFINED_SIZE_T)
if (findScalarResultIndex(RiaDefines::STATIC_NATIVE, "TRANX") != cvf::UNDEFINED_SIZE_T)
{
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riAreaNormTranXResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranXResultName(), false, 0);
}
if (findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANY") != cvf::UNDEFINED_SIZE_T)
if (findScalarResultIndex(RiaDefines::STATIC_NATIVE, "TRANY") != cvf::UNDEFINED_SIZE_T)
{
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riAreaNormTranYResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranYResultName(), false, 0);
}
if (findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANZ") != cvf::UNDEFINED_SIZE_T)
if (findScalarResultIndex(RiaDefines::STATIC_NATIVE, "TRANZ") != cvf::UNDEFINED_SIZE_T)
{
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riAreaNormTranZResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranZResultName(), false, 0);
}
size_t tranX, tranY, tranZ;
if (findTransmissibilityResults(tranX, tranY, tranZ))
{
addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::combinedRiAreaNormTranResultName(), false, 0);
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiAreaNormTranResultName(), false, 0);
}
}
}
@@ -821,9 +832,9 @@ void RigCaseCellResultsData::createPlaceholderResultEntries()
//--------------------------------------------------------------------------------------------------
bool RigCaseCellResultsData::findTransmissibilityResults(size_t& tranX, size_t& tranY, size_t& tranZ) const
{
tranX = findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANX");
tranY = findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANY");
tranZ = findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANZ");
tranX = findScalarResultIndex(RiaDefines::STATIC_NATIVE, "TRANX");
tranY = findScalarResultIndex(RiaDefines::STATIC_NATIVE, "TRANY");
tranZ = findScalarResultIndex(RiaDefines::STATIC_NATIVE, "TRANZ");
if (tranX == cvf::UNDEFINED_SIZE_T ||
tranY == cvf::UNDEFINED_SIZE_T ||

View File

@@ -22,7 +22,7 @@
#include "RifReaderInterface.h"
#include "RimDefines.h"
#include "RiaDefines.h"
#include "cvfCollection.h"
@@ -32,9 +32,11 @@
#include <cmath>
class RifReaderInterface;
class RigMainGrid;
class RigActiveCellInfo;
class RigMainGrid;
class RigEclipseResultInfo;
class RigStatisticsDataCache;
class RigEclipseTimeStepInfo;
//==================================================================================================
/// Class containing the results for the complete number of active cells. Both main grid and LGR's
@@ -69,7 +71,7 @@ public:
size_t resultCount() const;
size_t timeStepCount(size_t scalarResultIndex) const;
size_t maxTimeStepCount(size_t* scalarResultIndex = NULL) const;
QStringList resultNames(RimDefines::ResultCatType type) const;
QStringList resultNames(RiaDefines::ResultCatType type) const;
bool isUsingGlobalActiveIndex(size_t scalarResultIndex) const;
bool hasFlowDiagUsableFluxes() const;
@@ -80,14 +82,16 @@ public:
std::vector<double> daysSinceSimulationStart(size_t scalarResultIndex) const;
int reportStepNumber(size_t scalarResultIndex, size_t timeStepIndex) const;
std::vector<int> reportStepNumbers(size_t scalarResultIndex) const;
void setTimeStepDates(size_t scalarResultIndex, const std::vector<QDateTime>& dates, const std::vector<double>& daysSinceSimulationStart, const std::vector<int>& reportStepNumbers);
std::vector<RigEclipseTimeStepInfo> timeStepInfos(size_t scalarResultIndex) const;
void setTimeStepInfos(size_t scalarResultIndex, const std::vector<RigEclipseTimeStepInfo>& timeStepInfos);
// Find or create a slot for the results
size_t findScalarResultIndex(RimDefines::ResultCatType type, const QString& resultName) const;
size_t findScalarResultIndex(RiaDefines::ResultCatType type, const QString& resultName) const;
size_t findScalarResultIndex(const QString& resultName) const;
size_t addEmptyScalarResult(RimDefines::ResultCatType type, const QString& resultName, bool needsToBeStored);
size_t addEmptyScalarResult(RiaDefines::ResultCatType type, const QString& resultName, bool needsToBeStored);
QString makeResultNameUnique(const QString& resultNameProposal) const;
void createPlaceholderResultEntries();
@@ -102,36 +106,10 @@ public:
std::vector< std::vector<double> > & cellScalarResults(size_t scalarResultIndex);
std::vector<double>& cellScalarResults(size_t scalarResultIndex, size_t timeStepIndex);
static RifReaderInterface::PorosityModelResultType convertFromProjectModelPorosityModel(RimDefines::PorosityModelType porosityModel);
bool updateResultName(RimDefines::ResultCatType resultType, QString& oldName, const QString& newName);
bool updateResultName(RiaDefines::ResultCatType resultType, QString& oldName, const QString& newName);
public:
class ResultInfo
{
public:
ResultInfo(RimDefines::ResultCatType resultType, bool needsToBeStored, bool mustBeCalculated, QString resultName, size_t gridScalarResultIndex)
: m_resultType(resultType),
m_needsToBeStored(needsToBeStored),
m_resultName(resultName),
m_gridScalarResultIndex(gridScalarResultIndex),
m_mustBeCalculated(mustBeCalculated),
m_isSourSimData(false)
{ }
public:
RimDefines::ResultCatType m_resultType;
bool m_needsToBeStored;
bool m_mustBeCalculated;
QString m_resultName;
size_t m_gridScalarResultIndex;
std::vector<QDateTime> m_timeStepDates;
std::vector<int> m_timeStepReportNumbers;
bool m_isSourSimData;
std::vector<double> m_daysSinceSimulationStart;
};
const std::vector<ResultInfo>& infoForEachResultIndex() { return m_resultInfos;}
const std::vector<RigEclipseResultInfo>& infoForEachResultIndex() { return m_resultInfos;}
bool mustBeCalculated(size_t scalarResultIndex) const;
void setMustBeCalculated(size_t scalarResultIndex);
@@ -139,7 +117,7 @@ public:
public:
size_t addStaticScalarResult(RimDefines::ResultCatType type,
size_t addStaticScalarResult(RiaDefines::ResultCatType type,
const QString& resultName,
bool needsToBeStored,
size_t resultValueCount);
@@ -151,9 +129,8 @@ private:
cvf::Collection<RigStatisticsDataCache> m_statisticsDataCache;
private:
std::vector<ResultInfo> m_resultInfos;
std::vector<RigEclipseResultInfo> m_resultInfos;
RigMainGrid* m_ownerMainGrid;
RigActiveCellInfo* m_activeCellInfo;
};

View File

@@ -0,0 +1,67 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigCellGeometryTools.h"
#include "cvfStructGrid.h"
#include "cvfGeometryTools.h"
//==================================================================================================
///
//==================================================================================================
void RigCellGeometryTools::findCellLocalXYZ(const std::array<cvf::Vec3d, 8>& hexCorners, cvf::Vec3d& localXdirection, cvf::Vec3d& localYdirection, cvf::Vec3d& localZdirection)
{
cvf::ubyte faceVertexIndices[4];
cvf::StructGridInterface::FaceEnum face;
face = cvf::StructGridInterface::NEG_I;
cvf::StructGridInterface::cellFaceVertexIndices(face, faceVertexIndices);
cvf::Vec3d faceCenterNegI = cvf::GeometryTools::computeFaceCenter(hexCorners[faceVertexIndices[0]], hexCorners[faceVertexIndices[1]], hexCorners[faceVertexIndices[2]], hexCorners[faceVertexIndices[3]]);
//TODO: Should we use face centroids instead of face centers?
face = cvf::StructGridInterface::POS_I;
cvf::StructGridInterface::cellFaceVertexIndices(face, faceVertexIndices);
cvf::Vec3d faceCenterPosI = cvf::GeometryTools::computeFaceCenter(hexCorners[faceVertexIndices[0]], hexCorners[faceVertexIndices[1]], hexCorners[faceVertexIndices[2]], hexCorners[faceVertexIndices[3]]);
face = cvf::StructGridInterface::NEG_J;
cvf::StructGridInterface::cellFaceVertexIndices(face, faceVertexIndices);
cvf::Vec3d faceCenterNegJ = cvf::GeometryTools::computeFaceCenter(hexCorners[faceVertexIndices[0]], hexCorners[faceVertexIndices[1]], hexCorners[faceVertexIndices[2]], hexCorners[faceVertexIndices[3]]);
face = cvf::StructGridInterface::POS_J;
cvf::StructGridInterface::cellFaceVertexIndices(face, faceVertexIndices);
cvf::Vec3d faceCenterPosJ = cvf::GeometryTools::computeFaceCenter(hexCorners[faceVertexIndices[0]], hexCorners[faceVertexIndices[1]], hexCorners[faceVertexIndices[2]], hexCorners[faceVertexIndices[3]]);
cvf::Vec3d faceCenterCenterVectorI = faceCenterPosI - faceCenterNegI;
cvf::Vec3d faceCenterCenterVectorJ = faceCenterPosJ - faceCenterNegJ;
localZdirection.cross(faceCenterCenterVectorI, faceCenterCenterVectorJ);
localZdirection.normalize();
cvf::Vec3d crossPoductJZ;
crossPoductJZ.cross(faceCenterCenterVectorJ, localZdirection);
localXdirection = faceCenterCenterVectorI + crossPoductJZ;
localXdirection.normalize();
cvf::Vec3d crossPoductIZ;
crossPoductIZ.cross(faceCenterCenterVectorI, localZdirection);
localYdirection = faceCenterCenterVectorJ - crossPoductIZ;
localYdirection.normalize();
//TODO: Check if we end up with 0-vectors, and handle this case...
}

View File

@@ -0,0 +1,35 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfBase.h"
#include "cvfVector3.h"
#include <array>
//==================================================================================================
///
//==================================================================================================
class RigCellGeometryTools
{
public:
static void findCellLocalXYZ(const std::array<cvf::Vec3d, 8>& hexCorners, cvf::Vec3d &localXdirection, cvf::Vec3d &localYdirection, cvf::Vec3d &localZdirection);
};

View File

@@ -0,0 +1,263 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigCompletionData.h"
#include "RiaLogging.h"
#include "cvfAssert.h"
#include <QString>
#include <cmath> // Needed for HUGE_VAL on Linux
//==================================================================================================
///
//==================================================================================================
RigCompletionData::RigCompletionData(const QString wellName, const IJKCellIndex& cellIndex)
: m_wellName(wellName),
m_cellIndex(cellIndex),
m_saturation(HUGE_VAL),
m_transmissibility(HUGE_VAL),
m_diameter(HUGE_VAL),
m_kh(HUGE_VAL),
m_skinFactor(HUGE_VAL),
m_dFactor(HUGE_VAL),
m_direction(DIR_UNDEF),
m_connectionState(OPEN),
m_count(1),
m_wpimult(HUGE_VAL),
m_isMainBore(false),
m_readyForExport(false)
{
}
//==================================================================================================
///
//==================================================================================================
RigCompletionData::~RigCompletionData()
{
}
//==================================================================================================
///
//==================================================================================================
RigCompletionData::RigCompletionData(const RigCompletionData& other)
{
copy(*this, other);
}
//==================================================================================================
///
//==================================================================================================
RigCompletionData RigCompletionData::combine(const std::vector<RigCompletionData>& completions)
{
CVF_ASSERT(!completions.empty());
auto it = completions.cbegin();
RigCompletionData result(*it);
++it;
for (; it != completions.cend(); ++it)
{
if (it->completionType() != result.completionType())
{
RiaLogging::error(QString("Cannot combine completions of different types in same cell [%1, %2, %3]").arg(result.m_cellIndex.i).arg(result.m_cellIndex.j).arg(result.m_cellIndex.k));
continue;
}
if (onlyOneIsDefaulted(result.m_transmissibility, it->m_transmissibility))
{
RiaLogging::error("Transmissibility defaulted in one but not both, will produce erroneous result");
}
else
{
result.m_transmissibility += it->m_transmissibility;
}
result.m_metadata.reserve(result.m_metadata.size() + it->m_metadata.size());
result.m_metadata.insert(result.m_metadata.end(), it->m_metadata.begin(), it->m_metadata.end());
result.m_count += it->m_count;
}
return result;
}
//==================================================================================================
///
//==================================================================================================
bool RigCompletionData::operator<(const RigCompletionData& other) const
{
if (m_wellName != other.m_wellName)
{
return (m_wellName < other.m_wellName);
}
return m_cellIndex < other.m_cellIndex;
}
//==================================================================================================
///
//==================================================================================================
RigCompletionData& RigCompletionData::operator=(const RigCompletionData& other)
{
if (this != &other)
{
copy(*this, other);
}
return *this;
}
//==================================================================================================
///
//==================================================================================================
void RigCompletionData::setFromFracture(double transmissibility, double skinFactor)
{
m_completionType = FRACTURE;
m_transmissibility = transmissibility;
m_skinFactor = skinFactor;
}
//==================================================================================================
///
//==================================================================================================
void RigCompletionData::setTransAndWPImultBackgroundDataFromFishbone(double transmissibility,
double skinFactor,
double diameter,
CellDirection direction,
bool isMainBore)
{
m_completionType = FISHBONES;
m_transmissibility = transmissibility;
m_skinFactor = skinFactor;
m_diameter = diameter;
m_direction = direction;
m_isMainBore = isMainBore;
}
//==================================================================================================
///
//==================================================================================================
void RigCompletionData::setTransAndWPImultBackgroundDataFromPerforation(double transmissibility,
double skinFactor,
double diameter,
CellDirection direction)
{
m_completionType = PERFORATION;
m_transmissibility = transmissibility;
m_skinFactor = skinFactor;
m_diameter = diameter;
m_direction = direction;
m_isMainBore = true;
}
//==================================================================================================
///
//==================================================================================================
void RigCompletionData::setCombinedValuesExplicitTrans(double transmissibility,
CompletionType completionType)
{
m_completionType = completionType;
m_transmissibility = transmissibility;
m_readyForExport = true;
}
//==================================================================================================
///
//==================================================================================================
void RigCompletionData::setCombinedValuesImplicitTransWPImult(double wpimult,
CellDirection celldirection,
double skinFactor,
double wellDiameter,
CompletionType completionType)
{
m_wpimult = wpimult;
m_direction = celldirection;
m_completionType = completionType;
m_skinFactor = skinFactor;
m_diameter = wellDiameter;
m_readyForExport = true;
}
//==================================================================================================
///
//==================================================================================================
void RigCompletionData::addMetadata(const QString& name, const QString& comment)
{
m_metadata.push_back(RigCompletionMetaData(name, comment));
}
//==================================================================================================
///
//==================================================================================================
bool RigCompletionData::isDefaultValue(double val)
{
return val == HUGE_VAL;
}
//==================================================================================================
///
//==================================================================================================
bool RigCompletionData::onlyOneIsDefaulted(double first, double second)
{
if (first == HUGE_VAL)
{
if (second == HUGE_VAL)
{
// Both have default values
return false;
}
else
{
// First has default value, second does not
return true;
}
}
if (second == HUGE_VAL)
{
// Second has default value, first does not
return true;
}
// Neither has default values
return false;
}
//==================================================================================================
///
//==================================================================================================
void RigCompletionData::copy(RigCompletionData& target, const RigCompletionData& from)
{
target.m_metadata = from.m_metadata;
target.m_wellName = from.m_wellName;
target.m_cellIndex = from.m_cellIndex;
target.m_connectionState = from.m_connectionState;
target.m_saturation = from.m_saturation;
target.m_transmissibility = from.m_transmissibility;
target.m_diameter = from.m_diameter;
target.m_kh = from.m_kh;
target.m_skinFactor = from.m_skinFactor;
target.m_dFactor = from.m_dFactor;
target.m_direction = from.m_direction;
target.m_isMainBore = from.m_isMainBore;
target.m_readyForExport = from.m_readyForExport;
target.m_count = from.m_count;
target.m_wpimult = from.m_wpimult;
target.m_completionType = from.m_completionType;
}

View File

@@ -0,0 +1,173 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QString>
#include <vector>
//==================================================================================================
///
//==================================================================================================
enum WellConnectionState {
OPEN,
SHUT,
AUTO,
};
//==================================================================================================
///
//==================================================================================================
enum CellDirection {
DIR_I,
DIR_J,
DIR_K,
DIR_UNDEF,
};
//==================================================================================================
///
//==================================================================================================
class IJKCellIndex {
public:
IJKCellIndex() {};
IJKCellIndex(size_t i, size_t j, size_t k) : i(i), j(j), k(k) {};
IJKCellIndex(const IJKCellIndex& other)
{
i = other.i;
j = other.j;
k = other.k;
}
bool operator==(const IJKCellIndex& other) const
{
return i == other.i && j == other.j && k == other.k;
}
bool operator<(const IJKCellIndex& other) const
{
if (i != other.i) return i < other.i;
if (j != other.j) return j < other.j;
if (k != other.k) return k < other.k;
return false;
}
size_t i;
size_t j;
size_t k;
};
//==================================================================================================
///
//==================================================================================================
struct RigCompletionMetaData {
RigCompletionMetaData(const QString& name, const QString& comment) : name(name), comment(comment) {}
QString name;
QString comment;
};
//==================================================================================================
///
//==================================================================================================
class RigCompletionData
{
public:
enum CompletionType {
FISHBONES,
FRACTURE,
PERFORATION,
};
RigCompletionData(const QString wellName, const IJKCellIndex& cellIndex);
~RigCompletionData();
RigCompletionData(const RigCompletionData& other);
static RigCompletionData combine(const std::vector<RigCompletionData>& completions);
bool operator<(const RigCompletionData& other) const;
RigCompletionData& operator=(const RigCompletionData& other);
void setFromFracture(double transmissibility, double skinFactor);
void setTransAndWPImultBackgroundDataFromFishbone(double transmissibility,
double skinFactor,
double diameter,
CellDirection direction,
bool isMainBore);
void setTransAndWPImultBackgroundDataFromPerforation(double transmissibility,
double skinFactor,
double diameter,
CellDirection direction);
void setCombinedValuesExplicitTrans(double transmissibility,
CompletionType completionType);
void setCombinedValuesImplicitTransWPImult(double wpimult,
CellDirection celldirection,
double skinFactor,
double wellDiameter,
CompletionType completionType);
void addMetadata(const QString& name, const QString& comment);
static bool isDefaultValue(double val);
const std::vector<RigCompletionMetaData>& metadata() const { return m_metadata; }
const QString& wellName() const { return m_wellName; }
const IJKCellIndex& cellIndex() const { return m_cellIndex; }
WellConnectionState connectionState() const { return m_connectionState; }
double saturation() const { return m_saturation; }
double transmissibility() const { return m_transmissibility; }
double diameter() const { return m_diameter; } //TODO: should be ft or m
double kh() const { return m_kh; }
double skinFactor() const { return m_skinFactor; }
double dFactor() const { return m_dFactor; }
CellDirection direction() const { return m_direction; }
size_t count() const { return m_count; }
double wpimult() const { return m_wpimult; }
CompletionType completionType() const { return m_completionType; }
bool isMainBore() const { return m_isMainBore; }
bool readyForExport() const { return m_readyForExport; }
std::vector<RigCompletionMetaData> m_metadata;
private:
QString m_wellName;
IJKCellIndex m_cellIndex;
WellConnectionState m_connectionState;
double m_saturation; //TODO: remove, always use default in Eclipse?
double m_transmissibility;
double m_diameter;
double m_kh; //TODO: Remove, always use default in Eclipse?
double m_skinFactor;
double m_dFactor; //TODO: Remove, always use default in Eclipse?
CellDirection m_direction;
bool m_isMainBore; //to use mainbore for Eclipse calculation
bool m_readyForExport;
size_t m_count; //TODO: Remove, usage replaced by WPImult
double m_wpimult;
CompletionType m_completionType;
private:
static bool onlyOneIsDefaulted(double first, double second);
static void copy(RigCompletionData& target, const RigCompletionData& from);
};

View File

@@ -45,7 +45,7 @@ RigEclipseCaseData::RigEclipseCaseData()
m_matrixModelResults->setActiveCellInfo(m_activeCellInfo.p());
m_fractureModelResults->setActiveCellInfo(m_fractureActiveCellInfo.p());
m_unitsType = UNITS_METRIC;
m_unitsType = RiaEclipseUnitTools::UNITS_METRIC;
}
//--------------------------------------------------------------------------------------------------
@@ -434,9 +434,9 @@ void RigEclipseCaseData::computeActiveCellBoundingBoxes()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigActiveCellInfo* RigEclipseCaseData::activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel)
RigActiveCellInfo* RigEclipseCaseData::activeCellInfo(RiaDefines::PorosityModelType porosityModel)
{
if (porosityModel == RifReaderInterface::MATRIX_RESULTS)
if (porosityModel == RiaDefines::MATRIX_MODEL)
{
return m_activeCellInfo.p();
}
@@ -447,9 +447,9 @@ RigActiveCellInfo* RigEclipseCaseData::activeCellInfo(RifReaderInterface::Porosi
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigActiveCellInfo* RigEclipseCaseData::activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel) const
const RigActiveCellInfo* RigEclipseCaseData::activeCellInfo(RiaDefines::PorosityModelType porosityModel) const
{
if (porosityModel == RifReaderInterface::MATRIX_RESULTS)
if (porosityModel == RiaDefines::MATRIX_MODEL)
{
return m_activeCellInfo.p();
}
@@ -460,9 +460,9 @@ const RigActiveCellInfo* RigEclipseCaseData::activeCellInfo(RifReaderInterface::
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::setActiveCellInfo(RifReaderInterface::PorosityModelResultType porosityModel, RigActiveCellInfo* activeCellInfo)
void RigEclipseCaseData::setActiveCellInfo(RiaDefines::PorosityModelType porosityModel, RigActiveCellInfo* activeCellInfo)
{
if (porosityModel == RifReaderInterface::MATRIX_RESULTS)
if (porosityModel == RiaDefines::MATRIX_MODEL)
{
m_activeCellInfo = activeCellInfo;
m_matrixModelResults->setActiveCellInfo(m_activeCellInfo.p());
@@ -537,7 +537,7 @@ void RigEclipseCaseData::setActiveFormationNames(RigFormationNames* activeFormat
m_activeFormationNamesData = activeFormationNames;
size_t totalGlobCellCount = m_mainGrid->globalCellArray().size();
size_t resIndex = m_matrixModelResults->addStaticScalarResult(RimDefines::FORMATION_NAMES,
size_t resIndex = m_matrixModelResults->addStaticScalarResult(RiaDefines::FORMATION_NAMES,
"Active Formation Names",
false,
totalGlobCellCount);
@@ -604,9 +604,9 @@ RigFormationNames* RigEclipseCaseData::activeFormationNames()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigCaseCellResultsData* RigEclipseCaseData::results(RifReaderInterface::PorosityModelResultType porosityModel)
RigCaseCellResultsData* RigEclipseCaseData::results(RiaDefines::PorosityModelType porosityModel)
{
if (porosityModel == RifReaderInterface::MATRIX_RESULTS)
if (porosityModel == RiaDefines::MATRIX_MODEL)
{
return m_matrixModelResults.p();
}
@@ -617,9 +617,9 @@ RigCaseCellResultsData* RigEclipseCaseData::results(RifReaderInterface::Porosity
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigCaseCellResultsData* RigEclipseCaseData::results(RifReaderInterface::PorosityModelResultType porosityModel) const
const RigCaseCellResultsData* RigEclipseCaseData::results(RiaDefines::PorosityModelType porosityModel) const
{
if (porosityModel == RifReaderInterface::MATRIX_RESULTS)
if (porosityModel == RiaDefines::MATRIX_MODEL)
{
return m_matrixModelResults.p();
}

View File

@@ -23,6 +23,8 @@
#include "RifReaderInterface.h"
#include "RiaEclipseUnitTools.h"
#include "cvfAssert.h"
#include "cvfArray.h"
#include "cvfObject.h"
@@ -48,14 +50,6 @@ struct RigWellResultPoint;
//--------------------------------------------------------------------------------------------------
class RigEclipseCaseData : public cvf::Object
{
public:
enum UnitsType
{
UNITS_METRIC,
UNITS_FIELD,
UNITS_LAB
};
public:
RigEclipseCaseData();
~RigEclipseCaseData();
@@ -70,12 +64,12 @@ public:
RigGridBase* grid(size_t index);
size_t gridCount() const;
RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel);
const RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel) const;
RigCaseCellResultsData* results(RiaDefines::PorosityModelType porosityModel);
const RigCaseCellResultsData* results(RiaDefines::PorosityModelType porosityModel) const;
RigActiveCellInfo* activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel);
const RigActiveCellInfo* activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel) const;
void setActiveCellInfo(RifReaderInterface::PorosityModelResultType porosityModel, RigActiveCellInfo* activeCellInfo);
RigActiveCellInfo* activeCellInfo(RiaDefines::PorosityModelType porosityModel);
const RigActiveCellInfo* activeCellInfo(RiaDefines::PorosityModelType porosityModel) const;
void setActiveCellInfo(RiaDefines::PorosityModelType porosityModel, RigActiveCellInfo* activeCellInfo);
void setActiveFormationNames(RigFormationNames* activeFormationNames);
RigFormationNames* activeFormationNames();
@@ -92,8 +86,8 @@ public:
void computeActiveCellBoundingBoxes();
UnitsType unitsType() const { return m_unitsType; }
void setUnitsType(UnitsType unitsType) { m_unitsType = unitsType; }
RiaEclipseUnitTools::UnitSystem unitsType() const { return m_unitsType; }
void setUnitsType(RiaEclipseUnitTools::UnitSystem unitsType) { m_unitsType = unitsType; }
private:
void computeActiveCellIJKBBox();
@@ -115,5 +109,5 @@ private:
cvf::Collection<cvf::UByteArray> m_wellCellsInGrid; //< A bool array pr grid with one bool pr cell telling wether the cell is a well cell or not
cvf::Collection<cvf::UIntArray> m_gridCellToResultWellIndex; //< Array pr grid with index to well pr cell telling which well a cell is in
UnitsType m_unitsType;
RiaEclipseUnitTools::UnitSystem m_unitsType;
};

View File

@@ -0,0 +1,110 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigEclipseResultInfo.h"
#include "cvfAssert.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigEclipseTimeStepInfo::RigEclipseTimeStepInfo(const QDateTime& date, int reportNumber, double daysSinceSimulationStart)
: m_date(date),
m_reportNumber(reportNumber),
m_daysSinceSimulationStart(daysSinceSimulationStart)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigEclipseTimeStepInfo> RigEclipseTimeStepInfo::createTimeStepInfos(std::vector<QDateTime> dates,
std::vector<int> reportNumbers,
std::vector<double> daysSinceSimulationStarts)
{
CVF_ASSERT(dates.size() == reportNumbers.size());
CVF_ASSERT(dates.size() == daysSinceSimulationStarts.size());
std::vector<RigEclipseTimeStepInfo> timeStepInfos;
for (size_t i = 0; i < dates.size(); i++)
{
timeStepInfos.push_back(RigEclipseTimeStepInfo(dates[i], reportNumbers[i], daysSinceSimulationStarts[i]));
}
return timeStepInfos;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigEclipseResultInfo::RigEclipseResultInfo(RiaDefines::ResultCatType resultType, bool needsToBeStored, bool mustBeCalculated,
QString resultName, size_t gridScalarResultIndex)
: m_resultType(resultType),
m_needsToBeStored(needsToBeStored),
m_mustBeCalculated(mustBeCalculated),
m_resultName(resultName),
m_gridScalarResultIndex(gridScalarResultIndex)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QDateTime> RigEclipseResultInfo::dates() const
{
std::vector<QDateTime> values;
for (auto v : m_timeStepInfos)
{
values.push_back(v.m_date);
}
return values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RigEclipseResultInfo::daysSinceSimulationStarts() const
{
std::vector<double> values;
for (auto v : m_timeStepInfos)
{
values.push_back(v.m_daysSinceSimulationStart);
}
return values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<int> RigEclipseResultInfo::reportNumbers() const
{
std::vector<int> values;
for (auto v : m_timeStepInfos)
{
values.push_back(v.m_reportNumber);
}
return values;
}

View File

@@ -0,0 +1,67 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiaDefines.h"
#include <QDateTime>
#include <QString>
#include <vector>
//==================================================================================================
///
//==================================================================================================
class RigEclipseTimeStepInfo
{
public:
RigEclipseTimeStepInfo(const QDateTime& date, int reportNumber, double daysSinceSimulationStart);
static std::vector<RigEclipseTimeStepInfo> createTimeStepInfos(std::vector<QDateTime> dates,
std::vector<int> reportNumbers,
std::vector<double> daysSinceSimulationStarts);
public:
QDateTime m_date;
int m_reportNumber;
double m_daysSinceSimulationStart;
};
//==================================================================================================
///
//==================================================================================================
class RigEclipseResultInfo
{
public:
RigEclipseResultInfo(RiaDefines::ResultCatType resultType, bool needsToBeStored, bool mustBeCalculated,
QString resultName, size_t gridScalarResultIndex);
std::vector<QDateTime> dates() const;
std::vector<double> daysSinceSimulationStarts() const;
std::vector<int> reportNumbers() const;
public:
RiaDefines::ResultCatType m_resultType;
bool m_needsToBeStored;
bool m_mustBeCalculated;
QString m_resultName;
size_t m_gridScalarResultIndex;
std::vector<RigEclipseTimeStepInfo> m_timeStepInfos;
};

View File

@@ -85,7 +85,7 @@ void RigEclipseWellLogExtractor::calculateIntersection()
hexCorners[7] = nodeCoords[cornerIndices[7]];
//int intersectionCount = RigHexIntersector::lineHexCellIntersection(p1, p2, hexCorners, closeCells[cIdx], &intersections);
RigHexIntersector::lineHexCellIntersection(p1, p2, hexCorners, closeCells[cIdx], &intersections);
RigHexIntersectionTools::lineHexCellIntersection(p1, p2, hexCorners, closeCells[cIdx], &intersections);
}
if (!isCellFaceNormalsOut)

View File

@@ -0,0 +1,201 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigFishbonesGeometry.h"
#include "RimFishbonesMultipleSubs.h"
#include "cvfAssert.h"
#include "RimWellPath.h"
#include "RigWellPath.h"
#include "cvfMatrix4.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFisbonesGeometry::RigFisbonesGeometry(RimFishbonesMultipleSubs* fishbonesSub)
: m_fishbonesSub(fishbonesSub)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::pair<cvf::Vec3d, double>> RigFisbonesGeometry::coordsForLateral(size_t subIndex, size_t lateralIndex) const
{
CVF_ASSERT(lateralIndex < m_fishbonesSub->lateralLengths().size());
bool found = false;
for (auto& sub : m_fishbonesSub->installedLateralIndices())
{
if (sub.subIndex == subIndex)
{
auto it = std::find(sub.lateralIndices.begin(), sub.lateralIndices.end(), lateralIndex);
if (it != sub.lateralIndices.end())
{
found = true;
break;
}
}
}
CVF_ASSERT(found);
cvf::Vec3d position;
cvf::Vec3d lateralInitialDirection;
cvf::Mat4d buildAngleRotationMatrix;
computeLateralPositionAndOrientation(subIndex, lateralIndex, &position, &lateralInitialDirection, &buildAngleRotationMatrix);
return computeCoordsAlongLateral(m_fishbonesSub->measuredDepth(subIndex), m_fishbonesSub->lateralLengths()[lateralIndex], position, lateralInitialDirection, buildAngleRotationMatrix);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFisbonesGeometry::computeLateralPositionAndOrientation(size_t subIndex, size_t lateralIndex, cvf::Vec3d* startCoord, cvf::Vec3d* startDirection, cvf::Mat4d* buildAngleMatrix) const
{
RimWellPath* wellPath = nullptr;
m_fishbonesSub->firstAncestorOrThisOfTypeAsserted(wellPath);
RigWellPath* rigWellPath = wellPath->wellPathGeometry();
CVF_ASSERT(rigWellPath);
double measuredDepth = m_fishbonesSub->measuredDepth(subIndex);
cvf::Vec3d position = rigWellPath->interpolatedPointAlongWellPath(measuredDepth);
cvf::Mat4d buildAngleMat;
cvf::Vec3d lateralDirection;
{
cvf::Vec3d lateralInitialDirection = cvf::Vec3d::Z_AXIS;
cvf::Vec3d p1 = cvf::Vec3d::UNDEFINED;
cvf::Vec3d p2 = cvf::Vec3d::UNDEFINED;
rigWellPath->twoClosestPoints(position, &p1, &p2);
CVF_ASSERT(!p1.isUndefined() && !p2.isUndefined());
cvf::Vec3d alongWellPath = (p2 - p1).getNormalized();
if (RigFisbonesGeometry::closestMainAxis(alongWellPath) == cvf::Vec3d::Z_AXIS)
{
// Use Y-AXIS if well path is heading close to Z-AXIS
lateralInitialDirection = cvf::Vec3d::Y_AXIS;
}
{
double intialRotationAngle = m_fishbonesSub->rotationAngle(subIndex);
double lateralOffsetDegrees = 360.0 / m_fishbonesSub->lateralLengths().size();
double lateralOffsetRadians = cvf::Math::toRadians(intialRotationAngle + lateralOffsetDegrees * lateralIndex);
cvf::Mat4d lateralOffsetMatrix = cvf::Mat4d::fromRotation(alongWellPath, lateralOffsetRadians);
lateralInitialDirection = lateralInitialDirection.getTransformedVector(lateralOffsetMatrix);
}
cvf::Vec3d rotationAxis;
rotationAxis.cross(alongWellPath, lateralInitialDirection);
double exitAngleRadians = cvf::Math::toRadians(m_fishbonesSub->exitAngle());
cvf::Mat4d lateralRotationMatrix = cvf::Mat4d::fromRotation(rotationAxis, exitAngleRadians);
lateralDirection = alongWellPath.getTransformedVector(lateralRotationMatrix);
double buildAngleRadians = cvf::Math::toRadians(m_fishbonesSub->buildAngle());
buildAngleMat = cvf::Mat4d::fromRotation(rotationAxis, buildAngleRadians);
}
*startCoord = position;
*startDirection = lateralDirection;
*buildAngleMatrix = buildAngleMat;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::pair<cvf::Vec3d, double>> RigFisbonesGeometry::computeCoordsAlongLateral(double startMeasuredDepth, double lateralLength, const cvf::Vec3d& startCoord, const cvf::Vec3d& startDirection, const cvf::Mat4d& buildAngleMatrix)
{
std::vector<std::pair<cvf::Vec3d, double>> coords;
cvf::Vec3d lateralDirection(startDirection);
// Compute coordinates along the lateral by modifying the lateral direction by the build angle for
// every unit vector along the lateral
cvf::Vec3d accumulatedPosition = startCoord;
double measuredDepth = startMeasuredDepth;
double accumulatedLength = 0.0;
while (accumulatedLength < lateralLength)
{
coords.push_back(std::make_pair(accumulatedPosition, measuredDepth));
double delta = 1.0;
if (lateralLength - accumulatedLength < 1.0)
{
delta = lateralLength - accumulatedLength;
}
accumulatedPosition += delta * lateralDirection;
// Modify the lateral direction by the build angle for each unit vector
lateralDirection = lateralDirection.getTransformedVector(buildAngleMatrix);
accumulatedLength += delta;
measuredDepth += delta;
}
coords.push_back(std::make_pair(accumulatedPosition, measuredDepth));
return coords;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3d RigFisbonesGeometry::closestMainAxis(const cvf::Vec3d& vec)
{
size_t maxComponent = 0;
double maxValue = cvf::Math::abs(vec.x());
if (cvf::Math::abs(vec.y()) > maxValue)
{
maxComponent = 1;
maxValue = cvf::Math::abs(vec.y());
}
if (cvf::Math::abs(vec.z()) > maxValue)
{
maxComponent = 2;
maxValue = cvf::Math::abs(vec.z());
}
if (maxComponent == 0)
{
return cvf::Vec3d::X_AXIS;
}
else if (maxComponent == 1)
{
return cvf::Vec3d::Y_AXIS;
}
else
{
return cvf::Vec3d::Z_AXIS;
}
}

View File

@@ -0,0 +1,56 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmPointer.h"
#include "cvfBase.h"
#include "cvfVector3.h"
#include "cvfMatrix4.h"
#include <vector>
class RimFishbonesMultipleSubs;
//==================================================================================================
///
///
//==================================================================================================
class RigFisbonesGeometry
{
public:
explicit RigFisbonesGeometry(RimFishbonesMultipleSubs* fishbonesSub);
std::vector<std::pair<cvf::Vec3d, double>> coordsForLateral(size_t subIndex, size_t lateralIndex) const;
private:
void computeLateralPositionAndOrientation(size_t subIndex, size_t lateralIndex,
cvf::Vec3d* startCoord, cvf::Vec3d* startDirection,
cvf::Mat4d* buildAngleMatrix) const;
static std::vector<std::pair<cvf::Vec3d, double>> computeCoordsAlongLateral(double startMeasuredDepth, double lateralLength,
const cvf::Vec3d& startCoord, const cvf::Vec3d& startDirection,
const cvf::Mat4d& buildAngleMatrix);
static cvf::Vec3d closestMainAxis(const cvf::Vec3d& vec);
private:
caf::PdmPointer<RimFishbonesMultipleSubs> m_fishbonesSub;
};

View File

@@ -1,6 +1,24 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFlowDiagResultAddress.h"
#include <opm/flowdiagnostics/ConnectivityGraph.hpp>
#include <opm/flowdiagnostics/ConnectionValues.hpp>
@@ -18,15 +36,34 @@
namespace RigFlowDiagInterfaceTools {
std::vector<Opm::ECLPhaseIndex> getPhases(RigFlowDiagResultAddress::PhaseSelection phaseSelection)
{
std::vector<Opm::ECLPhaseIndex> phases;
if (phaseSelection & RigFlowDiagResultAddress::PHASE_GAS)
{
phases.push_back(Opm::ECLPhaseIndex::Vapour);
}
if (phaseSelection & RigFlowDiagResultAddress::PHASE_OIL)
{
phases.push_back(Opm::ECLPhaseIndex::Liquid);
}
if (phaseSelection & RigFlowDiagResultAddress::PHASE_WAT)
{
phases.push_back(Opm::ECLPhaseIndex::Aqua);
}
return phases;
}
template <class FluxCalc>
inline Opm::FlowDiagnostics::ConnectionValues
extractFluxField(const Opm::ECLGraph& G,
FluxCalc&& getFlux)
FluxCalc&& getFlux,
std::vector<Opm::ECLPhaseIndex> actPh)
{
using ConnVals = Opm::FlowDiagnostics::ConnectionValues;
const auto actPh = G.activePhases();
auto flux = ConnVals(ConnVals::NumConnections{ G.numConnections() },
ConnVals::NumPhases{ actPh.size() });
@@ -53,7 +90,8 @@ namespace RigFlowDiagInterfaceTools {
inline Opm::FlowDiagnostics::ConnectionValues
extractFluxFieldFromRestartFile(const Opm::ECLGraph& G,
const Opm::ECLRestartData& rstrt)
const Opm::ECLRestartData& rstrt,
RigFlowDiagResultAddress::PhaseSelection phaseSelection)
{
auto getFlux = [&G, &rstrt]
(const Opm::ECLPhaseIndex p)
@@ -61,7 +99,26 @@ namespace RigFlowDiagInterfaceTools {
return G.flux(rstrt, p);
};
return extractFluxField(G, getFlux);
return extractFluxField(G, getFlux, getPhases(phaseSelection));
}
inline Opm::FlowDiagnostics::ConnectionValues
calculateFluxField(const Opm::ECLGraph& G,
const Opm::ECLInitFileData& init,
const Opm::ECLRestartData& rstrt,
RigFlowDiagResultAddress::PhaseSelection phaseSelection)
{
auto satfunc = Opm::ECLSaturationFunc(G, init);
Opm::ECLFluxCalc calc(G, std::move(satfunc));
auto getFlux = [&calc, &rstrt]
(const Opm::ECLPhaseIndex p)
{
return calc.flux(rstrt, p);
};
return extractFluxField(G, getFlux, getPhases(phaseSelection));
}
template <class WellFluxes>

View File

@@ -18,6 +18,19 @@
#include "RigFlowDiagResultAddress.h"
namespace caf
{
template<>
void RigFlowDiagResultAddress::PhaseSelectionEnum::setUp()
{
addItem(RigFlowDiagResultAddress::PHASE_ALL, "PHASE_ALL", "All");
addItem(RigFlowDiagResultAddress::PHASE_OIL, "PHASE_OIL", "Oil");
addItem(RigFlowDiagResultAddress::PHASE_GAS, "PHASE_GAS", "Gas");
addItem(RigFlowDiagResultAddress::PHASE_WAT, "PHASE_WAT", "Water");
setDefault(RigFlowDiagResultAddress::PHASE_ALL);
}
}
//--------------------------------------------------------------------------------------------------
///
@@ -35,6 +48,10 @@ std::string RigFlowDiagResultAddress::uiText() const
std::string uiVarname = variableName;
std::string uitext = uiVarname;
if (phaseSelection != PHASE_ALL)
{
uitext += " (" + RigFlowDiagResultAddress::PhaseSelectionEnum(phaseSelection).uiText().toStdString() + ")";
}
uitext += " (";
for (const std::string& tracerName : selectedTracerNames)
{
@@ -49,6 +66,11 @@ std::string RigFlowDiagResultAddress::uiText() const
//--------------------------------------------------------------------------------------------------
std::string RigFlowDiagResultAddress::uiShortText() const
{
return variableName;
std::string uitext = variableName;
if (phaseSelection != PHASE_ALL)
{
uitext += " (" + RigFlowDiagResultAddress::PhaseSelectionEnum(phaseSelection).uiText().toStdString() + ")";
}
return uitext;
}

View File

@@ -17,6 +17,8 @@
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafAppEnum.h"
#include <string>
#include <set>
@@ -37,11 +39,24 @@ class RigFlowDiagResultAddress
{
public:
RigFlowDiagResultAddress(const std::string& aVariableName, const std::set<std::string>& someSelectedTracerNames)
: variableName(aVariableName), selectedTracerNames(someSelectedTracerNames) {}
enum PhaseSelection
{
PHASE_ALL = 0b111,
PHASE_OIL = 0b001,
PHASE_GAS = 0b010,
PHASE_WAT = 0b100,
};
RigFlowDiagResultAddress(const std::string& aVariableName, const std::string& tracerName)
: variableName(aVariableName)
typedef caf::AppEnum<PhaseSelection> PhaseSelectionEnum;
RigFlowDiagResultAddress(const std::string& aVariableName, PhaseSelection phaseSelection, const std::set<std::string>& someSelectedTracerNames)
: variableName(aVariableName),
phaseSelection(phaseSelection),
selectedTracerNames(someSelectedTracerNames) {}
RigFlowDiagResultAddress(const std::string& aVariableName, PhaseSelection phaseSelection, const std::string& tracerName)
: variableName(aVariableName),
phaseSelection(phaseSelection)
{
selectedTracerNames.insert(tracerName);
}
@@ -53,6 +68,7 @@ public:
std::string variableName;
std::set<std::string> selectedTracerNames;
PhaseSelection phaseSelection;
bool operator< (const RigFlowDiagResultAddress& other) const
{
@@ -60,6 +76,10 @@ public:
{
return selectedTracerNames < other.selectedTracerNames;
}
if (phaseSelection != other.phaseSelection)
{
return phaseSelection < other.phaseSelection;
}
return variableName < other.variableName;
}

View File

@@ -39,9 +39,8 @@ RigFlowDiagResults::RigFlowDiagResults(RimFlowDiagSolution* flowSolution, size_t
{
m_timeStepCount = timeStepCount;
m_hasAtemptedNativeResults.resize(timeStepCount, false);
m_hasAtemptedNativeResults.resize(timeStepCount);
m_injProdPairFluxCommunicationTimesteps.resize(timeStepCount);
m_flowCharResultFrames.resize(timeStepCount);
}
//--------------------------------------------------------------------------------------------------
@@ -71,7 +70,7 @@ const RigActiveCellInfo * RigFlowDiagResults::activeCellInfo(const RigFlowDiagRe
RimEclipseResultCase* eclCase;
m_flowDiagSolution->firstAncestorOrThisOfType(eclCase);
return eclCase->eclipseCaseData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); // Todo: base on resVarAddr member
return eclCase->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); // Todo: base on resVarAddr member
}
//--------------------------------------------------------------------------------------------------
@@ -92,7 +91,7 @@ const std::vector<double>* RigFlowDiagResults::findOrCalculateResult(const RigFl
if (!solverInterface()) return nullptr;
calculateNativeResultsIfNotPreviouslyAttempted(frameIndex);
calculateNativeResultsIfNotPreviouslyAttempted(frameIndex, resVarAddr.phaseSelection);
return findScalarResultFrame(resVarAddr, frameIndex);
}
@@ -100,12 +99,14 @@ const std::vector<double>* RigFlowDiagResults::findOrCalculateResult(const RigFl
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFlowDiagResults::calculateNativeResultsIfNotPreviouslyAttempted(size_t frameIndex)
void RigFlowDiagResults::calculateNativeResultsIfNotPreviouslyAttempted(size_t frameIndex, RigFlowDiagResultAddress::PhaseSelection phaseSelection)
{
if ( !m_hasAtemptedNativeResults[frameIndex] )
auto it = m_hasAtemptedNativeResults[frameIndex].find(phaseSelection);
if ( it == m_hasAtemptedNativeResults[frameIndex].end() || !it->second )
{
RigFlowDiagTimeStepResult nativeTimestepResults = solverInterface()->calculate(frameIndex,
phaseSelection,
m_flowDiagSolution->allInjectorTracerActiveCellIndices(frameIndex),
m_flowDiagSolution->allProducerTracerActiveCellIndices(frameIndex));
@@ -119,15 +120,9 @@ void RigFlowDiagResults::calculateNativeResultsIfNotPreviouslyAttempted(size_t f
nativeResFrames->frameData(frameIndex).swap(resIt.second);
}
m_injProdPairFluxCommunicationTimesteps[frameIndex].swap(nativeTimestepResults.injProdWellPairFluxes());
m_injProdPairFluxCommunicationTimesteps[frameIndex][phaseSelection].swap(nativeTimestepResults.injProdWellPairFluxes());
m_flowCharResultFrames[frameIndex].m_lorenzCoefficient = nativeTimestepResults.lorenzCoefficient();
m_flowCharResultFrames[frameIndex].m_flowCapStorageCapCurve.first.swap(nativeTimestepResults.flowCapStorageCapCurve().first);
m_flowCharResultFrames[frameIndex].m_flowCapStorageCapCurve.second.swap(nativeTimestepResults.flowCapStorageCapCurve().second);
m_flowCharResultFrames[frameIndex].m_sweepEfficiencyCurve.first.swap(nativeTimestepResults.sweepEfficiencyCurve().first);
m_flowCharResultFrames[frameIndex].m_sweepEfficiencyCurve.second.swap(nativeTimestepResults.sweepEfficiencyCurve().second);
m_hasAtemptedNativeResults[frameIndex] = true;
m_hasAtemptedNativeResults[frameIndex][phaseSelection] = true;
}
}
@@ -428,7 +423,7 @@ std::vector<const std::vector<double>* > RigFlowDiagResults::findResultsForSelec
if (tracerType != RimFlowDiagSolution::CLOSED
&& ( tracerType == wantedTracerType || wantedTracerType == RimFlowDiagSolution::UNDEFINED) )
{
selectedTracersResults.push_back(findOrCalculateResult(RigFlowDiagResultAddress(nativeResultName, tracerName), frameIndex));
selectedTracersResults.push_back(findOrCalculateResult(RigFlowDiagResultAddress(nativeResultName, resVarAddr.phaseSelection, tracerName), frameIndex));
}
}
@@ -455,7 +450,7 @@ RigFlowDiagResults::findNamedResultsForSelectedTracers(const RigFlowDiagResultAd
if (tracerType != RimFlowDiagSolution::CLOSED
&& ( tracerType == wantedTracerType || wantedTracerType == RimFlowDiagSolution::UNDEFINED) )
{
selectedTracersResults.push_back(std::make_pair(tracerName, findOrCalculateResult(RigFlowDiagResultAddress(nativeResultName, tracerName), frameIndex)));
selectedTracersResults.push_back(std::make_pair(tracerName, findOrCalculateResult(RigFlowDiagResultAddress(nativeResultName, resVarAddr.phaseSelection, tracerName), frameIndex)));
}
}
@@ -632,10 +627,10 @@ std::pair<double, double> RigFlowDiagResults::injectorProducerPairFluxes(const s
const std::string& prodTracerName,
int frameIndex)
{
calculateNativeResultsIfNotPreviouslyAttempted(frameIndex);
calculateNativeResultsIfNotPreviouslyAttempted(frameIndex, RigFlowDiagResultAddress::PHASE_ALL);
auto commPair = m_injProdPairFluxCommunicationTimesteps[frameIndex].find(std::make_pair(injTracername, prodTracerName));
if (commPair != m_injProdPairFluxCommunicationTimesteps[frameIndex].end())
auto commPair = m_injProdPairFluxCommunicationTimesteps[frameIndex][RigFlowDiagResultAddress::PHASE_ALL].find(std::make_pair(injTracername, prodTracerName));
if (commPair != m_injProdPairFluxCommunicationTimesteps[frameIndex][RigFlowDiagResultAddress::PHASE_ALL].end())
{
return commPair->second;
}
@@ -650,10 +645,10 @@ std::pair<double, double> RigFlowDiagResults::injectorProducerPairFluxes(const s
//--------------------------------------------------------------------------------------------------
double RigFlowDiagResults::maxAbsPairFlux(int frameIndex)
{
calculateNativeResultsIfNotPreviouslyAttempted(frameIndex);
calculateNativeResultsIfNotPreviouslyAttempted(frameIndex, RigFlowDiagResultAddress::PHASE_ALL);
double maxFlux = 0.0;
for (const auto& commPair : m_injProdPairFluxCommunicationTimesteps[frameIndex])
for (const auto& commPair : m_injProdPairFluxCommunicationTimesteps[frameIndex][RigFlowDiagResultAddress::PHASE_ALL])
{
if (fabs(commPair.second.first) > maxFlux ) maxFlux = fabs(commPair.second.first);
if (fabs(commPair.second.second) > maxFlux ) maxFlux = fabs(commPair.second.second);
@@ -665,12 +660,16 @@ double RigFlowDiagResults::maxAbsPairFlux(int frameIndex)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<int> RigFlowDiagResults::calculatedTimeSteps()
std::vector<int> RigFlowDiagResults::calculatedTimeSteps(RigFlowDiagResultAddress::PhaseSelection phaseSelection)
{
std::vector<int> timestepIndices;
for (size_t tsIdx = 0; tsIdx < m_timeStepCount; ++tsIdx)
{
if (m_hasAtemptedNativeResults[tsIdx]) timestepIndices.push_back(static_cast<int>(tsIdx));
auto it = m_hasAtemptedNativeResults[tsIdx].find(phaseSelection);
if (it != m_hasAtemptedNativeResults[tsIdx].end() && it->second)
{
timestepIndices.push_back(static_cast<int>(tsIdx));
}
}
return timestepIndices;
@@ -679,8 +678,31 @@ std::vector<int> RigFlowDiagResults::calculatedTimeSteps()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagResults::FlowCharacteristicsResultFrame::FlowCharacteristicsResultFrame()
: m_lorenzCoefficient(HUGE_VAL)
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagResults::flowCharacteristicsResults(int frameIndex, double max_pv_fraction)
{
std::vector<QString> tracerNames = m_flowDiagSolution->tracerNames();
std::set<std::string> injectorNames;
std::set<std::string> producerNames;
for (const QString& tracerName : tracerNames)
{
RimFlowDiagSolution::TracerStatusType status = m_flowDiagSolution->tracerStatusInTimeStep(tracerName, frameIndex);
if (status == RimFlowDiagSolution::INJECTOR)
{
injectorNames.insert(tracerName.toStdString());
}
else if (status == RimFlowDiagSolution::PRODUCER)
{
producerNames.insert(tracerName.toStdString());
}
}
RigFlowDiagResultAddress injectorAddress(RIG_FLD_TOF_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, injectorNames);
RigFlowDiagResultAddress producerAddress(RIG_FLD_TOF_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, producerNames);
const std::vector<double>* injectorResults = resultValues(injectorAddress, frameIndex);
const std::vector<double>* producerResults = resultValues(producerAddress, frameIndex);
return solverInterface()->calculateFlowCharacteristics(injectorResults, producerResults, max_pv_fraction);
}

View File

@@ -19,6 +19,8 @@
#include "RigFlowDiagResultAddress.h"
#include "RigFlowDiagSolverInterface.h"
#include "RimFlowDiagSolution.h"
#include "cafPdmPointer.h"
@@ -32,7 +34,6 @@
class RigFlowDiagResultFrames;
class RigStatisticsDataCache;
class RigFlowDiagSolverInterface;
class RigActiveCellInfo;
class RigFlowDiagResults: public cvf::Object
@@ -63,24 +64,14 @@ public:
std::pair<double, double> injectorProducerPairFluxes(const std::string& injTracername, const std::string& prodTracerName, int frameIndex);
double maxAbsPairFlux(int frameIndex);
std::vector<int> calculatedTimeSteps();
std::vector<int> calculatedTimeSteps(RigFlowDiagResultAddress::PhaseSelection phaseSelection);
struct FlowCharacteristicsResultFrame
{
FlowCharacteristicsResultFrame();
using Curve = std::pair< std::vector<double>, std::vector<double> >;
Curve m_flowCapStorageCapCurve;
Curve m_sweepEfficiencyCurve;
double m_lorenzCoefficient;
};
const FlowCharacteristicsResultFrame& flowCharacteristicsResults(int frameIndex) { return m_flowCharResultFrames[frameIndex];}
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame flowCharacteristicsResults(int frameIndex, double max_pv_fraction);
private:
const std::vector<double>* findOrCalculateResult (const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);
void calculateNativeResultsIfNotPreviouslyAttempted(size_t frameIndex);
void calculateNativeResultsIfNotPreviouslyAttempted(size_t frameIndex, RigFlowDiagResultAddress::PhaseSelection phaseSelection);
std::vector<double>* calculateDerivedResult(const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);
@@ -126,18 +117,13 @@ private:
size_t m_timeStepCount;
caf::PdmPointer<RimFlowDiagSolution> m_flowDiagSolution;
std::vector<bool> m_hasAtemptedNativeResults;
std::vector< std::map<RigFlowDiagResultAddress::PhaseSelection, bool > > m_hasAtemptedNativeResults;
std::map< RigFlowDiagResultAddress, cvf::ref<RigFlowDiagResultFrames> > m_resultSets;
std::map< RigFlowDiagResultAddress, cvf::ref<RigStatisticsDataCache> > m_resultStatistics;
using InjectorProducerCommunicationMap = std::map< std::pair<std::string, std::string>, std::pair<double, double> >;
std::vector<InjectorProducerCommunicationMap> m_injProdPairFluxCommunicationTimesteps;
std::vector<FlowCharacteristicsResultFrame> m_flowCharResultFrames;
std::vector< std::map<RigFlowDiagResultAddress::PhaseSelection, InjectorProducerCommunicationMap> > m_injProdPairFluxCommunicationTimesteps;
};

View File

@@ -39,7 +39,7 @@
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagTimeStepResult::RigFlowDiagTimeStepResult(size_t activeCellCount)
: m_activeCellCount(activeCellCount), m_lorenzCoefficient(HUGE_VAL)
: m_activeCellCount(activeCellCount)
{
}
@@ -49,12 +49,14 @@ RigFlowDiagTimeStepResult::RigFlowDiagTimeStepResult(size_t activeCellCount)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFlowDiagTimeStepResult::setTracerTOF(const std::string& tracerName, const std::map<int, double>& cellValues)
void RigFlowDiagTimeStepResult::setTracerTOF(const std::string& tracerName,
RigFlowDiagResultAddress::PhaseSelection phaseSelection,
const std::map<int, double>& cellValues)
{
std::set<std::string> tracers;
tracers.insert(tracerName);
RigFlowDiagResultAddress resAddr(RIG_FLD_TOF_RESNAME, tracers);
RigFlowDiagResultAddress resAddr(RIG_FLD_TOF_RESNAME, phaseSelection, tracers);
this->addResult(resAddr, cellValues);
@@ -68,12 +70,14 @@ void RigFlowDiagTimeStepResult::setTracerTOF(const std::string& tracerName, cons
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFlowDiagTimeStepResult::setTracerFraction(const std::string& tracerName, const std::map<int, double>& cellValues)
void RigFlowDiagTimeStepResult::setTracerFraction(const std::string& tracerName,
RigFlowDiagResultAddress::PhaseSelection phaseSelection,
const std::map<int, double>& cellValues)
{
std::set<std::string> tracers;
tracers.insert(tracerName);
this->addResult(RigFlowDiagResultAddress(RIG_FLD_CELL_FRACTION_RESNAME, tracers), cellValues);
this->addResult(RigFlowDiagResultAddress(RIG_FLD_CELL_FRACTION_RESNAME, phaseSelection, tracers), cellValues);
}
//--------------------------------------------------------------------------------------------------
@@ -148,12 +152,13 @@ RigFlowDiagSolverInterface::~RigFlowDiagSolverInterface()
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepIndex,
RigFlowDiagResultAddress::PhaseSelection phaseSelection,
std::map<std::string, std::vector<int> > injectorTracers,
std::map<std::string, std::vector<int> > producerTracers)
{
using namespace Opm::FlowDiagnostics;
RigFlowDiagTimeStepResult result(m_eclipseCase->eclipseCaseData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->reservoirActiveCellCount());
RigFlowDiagTimeStepResult result(m_eclipseCase->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL)->reservoirActiveCellCount());
caf::ProgressInfo progressInfo(8, "Calculating Flow Diagnostics");
@@ -164,14 +169,11 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
// Get set of files
QString gridFileName = m_eclipseCase->gridFileName();
QStringList m_filesWithSameBaseName;
std::string initFileName = getInitFileName();
if ( !RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(gridFileName, &m_filesWithSameBaseName) ) return result;
if (initFileName.empty()) return result;
QString initFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_INIT_FILE);
m_opmFlowDiagStaticData = new RigOpmFlowDiagStaticData(gridFileName.toStdString(),
initFileName.toStdString());
m_opmFlowDiagStaticData = new RigOpmFlowDiagStaticData(gridFileName.toStdString(), initFileName);
progressInfo.incrementProgress();
progressInfo.setProgressDescription("Calculating Connectivities");
@@ -189,6 +191,9 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
m_opmFlowDiagStaticData->m_fldToolbox->assignPoreVolume( m_opmFlowDiagStaticData->m_poreVolume);
// Look for unified restart file
QStringList m_filesWithSameBaseName;
if ( !RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(gridFileName, &m_filesWithSameBaseName) ) return result;
QString restartFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_UNIFIED_RESTART_FILE);
if ( !restartFileName.isEmpty() )
@@ -201,7 +206,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
QStringList restartFileNames = RifEclipseOutputFileTools::filterFileNamesOfType(m_filesWithSameBaseName, ECL_RESTART_FILE);
size_t restartFileCount = static_cast<size_t>(restartFileNames.size());
size_t maxTimeStepCount = m_eclipseCase->eclipseCaseData()->results(RifReaderInterface::MATRIX_RESULTS)->maxTimeStepCount();
size_t maxTimeStepCount = m_eclipseCase->eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->maxTimeStepCount();
if (restartFileCount <= timeStepIndex && restartFileCount != maxTimeStepCount )
{
@@ -236,9 +241,9 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
CVF_ASSERT(currentRestartData);
size_t resultIndexWithMaxTimeSteps = cvf::UNDEFINED_SIZE_T;
m_eclipseCase->eclipseCaseData()->results(RifReaderInterface::MATRIX_RESULTS)->maxTimeStepCount(&resultIndexWithMaxTimeSteps);
m_eclipseCase->eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->maxTimeStepCount(&resultIndexWithMaxTimeSteps);
int reportStepNumber = m_eclipseCase->eclipseCaseData()->results(RifReaderInterface::MATRIX_RESULTS)->reportStepNumber(resultIndexWithMaxTimeSteps, timeStepIndex);
int reportStepNumber = m_eclipseCase->eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->reportStepNumber(resultIndexWithMaxTimeSteps, timeStepIndex);
if ( !currentRestartData->selectReportStep(reportStepNumber) )
{
@@ -251,10 +256,20 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
Opm::FlowDiagnostics::CellSetValues sumWellFluxPrCell;
{
Opm::FlowDiagnostics::ConnectionValues connectionsVals = RigFlowDiagInterfaceTools::extractFluxFieldFromRestartFile(*(m_opmFlowDiagStaticData->m_eclGraph),
*currentRestartData);
if (m_eclipseCase->eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->hasFlowDiagUsableFluxes())
{
Opm::FlowDiagnostics::ConnectionValues connectionsVals = RigFlowDiagInterfaceTools::extractFluxFieldFromRestartFile(*(m_opmFlowDiagStaticData->m_eclGraph),
*currentRestartData,
phaseSelection);
m_opmFlowDiagStaticData->m_fldToolbox->assignConnectionFlux(connectionsVals);
}
else
{
Opm::ECLInitFileData init(getInitFileName());
Opm::FlowDiagnostics::ConnectionValues connectionVals = RigFlowDiagInterfaceTools::calculateFluxField((*m_opmFlowDiagStaticData->m_eclGraph), init, *currentRestartData, phaseSelection);
m_opmFlowDiagStaticData->m_fldToolbox->assignConnectionFlux(connectionVals);
}
m_opmFlowDiagStaticData->m_fldToolbox->assignConnectionFlux(connectionsVals);
progressInfo.incrementProgress();
@@ -334,9 +349,9 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
for ( const CellSetID& tracerId: injectorSolution->fd.startPoints() )
{
CellSetValues tofVals = injectorSolution->fd.timeOfFlight(tracerId);
result.setTracerTOF(tracerId.to_string(), tofVals);
result.setTracerTOF(tracerId.to_string(), phaseSelection, tofVals);
CellSetValues fracVals = injectorSolution->fd.concentration(tracerId);
result.setTracerFraction(tracerId.to_string(), fracVals);
result.setTracerFraction(tracerId.to_string(), phaseSelection, fracVals);
}
progressInfo.incrementProgress();
@@ -364,9 +379,9 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
for ( const CellSetID& tracerId: producerSolution->fd.startPoints() )
{
CellSetValues tofVals = producerSolution->fd.timeOfFlight(tracerId);
result.setTracerTOF(tracerId.to_string(), tofVals);
result.setTracerTOF(tracerId.to_string(), phaseSelection, tofVals);
CellSetValues fracVals = producerSolution->fd.concentration(tracerId);
result.setTracerFraction(tracerId.to_string(), fracVals);
result.setTracerFraction(tracerId.to_string(), phaseSelection, fracVals);
}
progressInfo.incrementProgress();
@@ -394,24 +409,67 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
}
}
}
try
{
Graph flowCapStorCapCurve = flowCapacityStorageCapacityCurve(*(injectorSolution.get()),
*(producerSolution.get()),
m_opmFlowDiagStaticData->m_poreVolume,
0.1);
result.setFlowCapStorageCapCurve(flowCapStorCapCurve);
result.setSweepEfficiencyCurve(sweepEfficiency(flowCapStorCapCurve));
result.setLorenzCoefficient(lorenzCoefficient(flowCapStorCapCurve));
}
catch ( const std::exception& e )
{
QMessageBox::critical(nullptr, "ResInsight", "Flow Diagnostics: " + QString(e.what()));
}
}
return result; // Relying on implicit move constructor
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagSolverInterface::calculateFlowCharacteristics(const std::vector<double>* injector_tof,
const std::vector<double>* producer_tof,
double max_pv_fraction)
{
using namespace Opm::FlowDiagnostics;
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame result;
if (injector_tof == nullptr || producer_tof == nullptr)
{
return result;
}
try
{
Graph flowCapStorCapCurve = flowCapacityStorageCapacityCurve(*injector_tof,
*producer_tof,
m_opmFlowDiagStaticData->m_poreVolume,
max_pv_fraction);
result.m_flowCapStorageCapCurve = flowCapStorCapCurve;
result.m_lorenzCoefficient = lorenzCoefficient(flowCapStorCapCurve);
result.m_sweepEfficiencyCurve = sweepEfficiency(flowCapStorCapCurve);
}
catch (const std::exception& e)
{
QMessageBox::critical(nullptr, "ResInsight", "Flow Diagnostics: " + QString(e.what()));
}
return result;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RigFlowDiagSolverInterface::getInitFileName() const
{
QString gridFileName = m_eclipseCase->gridFileName();
QStringList m_filesWithSameBaseName;
if (!RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(gridFileName, &m_filesWithSameBaseName)) return std::string();
QString initFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_INIT_FILE);
return initFileName.toStdString();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame::FlowCharacteristicsResultFrame()
: m_lorenzCoefficient(HUGE_VAL)
{
}

View File

@@ -35,25 +35,18 @@ class RigFlowDiagTimeStepResult
public:
explicit RigFlowDiagTimeStepResult(size_t activeCellCount);
void setTracerTOF (const std::string& tracerName, const std::map<int, double>& cellValues);
void setTracerFraction(const std::string& tracerName, const std::map<int, double>& cellValues);
void setTracerTOF (const std::string& tracerName, RigFlowDiagResultAddress::PhaseSelection phaseSelection, const std::map<int, double>& cellValues);
void setTracerFraction(const std::string& tracerName, RigFlowDiagResultAddress::PhaseSelection phaseSelection, const std::map<int, double>& cellValues);
void setInjProdWellPairFlux(const std::string& injectorTracerName,
const std::string& producerTracerName,
const std::pair<double, double>& injProdFluxes) ;
using Curve = std::pair< std::vector<double>, std::vector<double> >;
void setFlowCapStorageCapCurve(const Curve& flCapStCapCurve) { m_flowCapStorageCapCurve = flCapStCapCurve;}
void setSweepEfficiencyCurve(const Curve& sweepEffCurve) { m_sweepEfficiencyCurve = sweepEffCurve; }
void setLorenzCoefficient(double coeff) { m_lorenzCoefficient = coeff;}
// Used to "steal" the data from this one using swap
std::map<RigFlowDiagResultAddress, std::vector<double> >& nativeResults() { return m_nativeResults; }
std::map<std::pair<std::string, std::string>, std::pair<double, double> > & injProdWellPairFluxes() { return m_injProdWellPairFluxes; }
Curve& flowCapStorageCapCurve() { return m_flowCapStorageCapCurve; }
Curve& sweepEfficiencyCurve() { return m_sweepEfficiencyCurve; }
double lorenzCoefficient() { return m_lorenzCoefficient;}
private:
void addResult(const RigFlowDiagResultAddress& resAddr, const std::map<int, double>& cellValues);
@@ -61,10 +54,6 @@ private:
std::map<RigFlowDiagResultAddress, std::vector<double> > m_nativeResults;
std::map<std::pair<std::string, std::string>, std::pair<double, double> > m_injProdWellPairFluxes;
Curve m_flowCapStorageCapCurve;
Curve m_sweepEfficiencyCurve;
double m_lorenzCoefficient;
size_t m_activeCellCount;
};
@@ -74,15 +63,34 @@ class RigOpmFlowDiagStaticData;
class RigFlowDiagSolverInterface : public cvf::Object
{
public:
struct FlowCharacteristicsResultFrame
{
FlowCharacteristicsResultFrame();
using Curve = std::pair< std::vector<double>, std::vector<double> >;
Curve m_flowCapStorageCapCurve;
Curve m_sweepEfficiencyCurve;
double m_lorenzCoefficient;
};
public:
explicit RigFlowDiagSolverInterface(RimEclipseResultCase * eclipseCase);
virtual ~RigFlowDiagSolverInterface();
RigFlowDiagTimeStepResult calculate(size_t timestep,
RigFlowDiagResultAddress::PhaseSelection phaseSelection,
std::map<std::string, std::vector<int> > injectorTracers,
std::map<std::string, std::vector<int> > producerTracers);
FlowCharacteristicsResultFrame calculateFlowCharacteristics(const std::vector<double>* injector_tof,
const std::vector<double>* producer_tof,
double max_pv_fraction);
private:
std::string getInitFileName() const;
RimEclipseResultCase * m_eclipseCase;
cvf::ref<RigOpmFlowDiagStaticData> m_opmFlowDiagStaticData;

View File

@@ -28,6 +28,7 @@
#include "RigWellLogExtractionTools.h"
#include "RigWellPath.h"
#include "cvfGeometryTools.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -155,7 +156,7 @@ void RigGeoMechWellLogExtractor::calculateIntersection()
hexCorners[7] = cvf::Vec3d(nodeCoords[cornerIndices[7]]);
//int intersectionCount = RigHexIntersector::lineHexCellIntersection(p1, p2, hexCorners, closeCells[ccIdx], &intersections);
RigHexIntersector::lineHexCellIntersection(p1, p2, hexCorners, closeCells[ccIdx], &intersections);
RigHexIntersectionTools::lineHexCellIntersection(p1, p2, hexCorners, closeCells[ccIdx], &intersections);
}
// Now, with all the intersections of this piece of line, we need to

View File

@@ -0,0 +1,91 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigHexIntersectionTools.h"
#include "cvfBoundingBox.h"
#include "cvfGeometryTools.h"
#include "cvfRay.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RigHexIntersectionTools::lineHexCellIntersection(const cvf::Vec3d p1, const cvf::Vec3d p2, const cvf::Vec3d hexCorners[8], const size_t hexIndex, std::vector<HexIntersectionInfo>* intersections)
{
CVF_ASSERT(intersections != NULL);
int intersectionCount = 0;
for ( int face = 0; face < 6 ; ++face )
{
cvf::ubyte faceVertexIndices[4];
cvf::StructGridInterface::cellFaceVertexIndices(static_cast<cvf::StructGridInterface::FaceType>(face), faceVertexIndices);
cvf::Vec3d intersection;
bool isEntering = false;
cvf::Vec3d faceCenter = cvf::GeometryTools::computeFaceCenter(hexCorners[faceVertexIndices[0]], hexCorners[faceVertexIndices[1]], hexCorners[faceVertexIndices[2]], hexCorners[faceVertexIndices[3]]);
for ( int i = 0; i < 4; ++i )
{
int next = i < 3 ? i+1 : 0;
int intsStatus = cvf::GeometryTools::intersectLineSegmentTriangle(p1, p2,
hexCorners[faceVertexIndices[i]],
hexCorners[faceVertexIndices[next]],
faceCenter,
&intersection,
&isEntering);
if ( intsStatus == 1 )
{
intersectionCount++;
intersections->push_back(HexIntersectionInfo(intersection,
isEntering,
static_cast<cvf::StructGridInterface::FaceType>(face), hexIndex));
}
}
}
return intersectionCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigHexIntersectionTools::isPointInCell(const cvf::Vec3d point, const cvf::Vec3d hexCorners[8])
{
cvf::Ray ray;
ray.setOrigin(point);
size_t intersections = 0;
for ( int face = 0; face < 6; ++face )
{
cvf::ubyte faceVertexIndices[4];
cvf::StructGridInterface::cellFaceVertexIndices(static_cast<cvf::StructGridInterface::FaceType>(face), faceVertexIndices);
cvf::Vec3d faceCenter = cvf::GeometryTools::computeFaceCenter(hexCorners[faceVertexIndices[0]], hexCorners[faceVertexIndices[1]], hexCorners[faceVertexIndices[2]], hexCorners[faceVertexIndices[3]]);
for ( int i = 0; i < 4; ++i )
{
int next = i < 3 ? i + 1 : 0;
if ( ray.triangleIntersect(hexCorners[faceVertexIndices[i]], hexCorners[faceVertexIndices[next]], faceCenter) )
{
++intersections;
}
}
}
return intersections % 2 == 1;
}

View File

@@ -0,0 +1,64 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfBase.h"
#include "cvfVector3.h"
#include "cvfStructGrid.h"
//==================================================================================================
/// Internal class for intersection point info
//==================================================================================================
struct HexIntersectionInfo
{
public:
HexIntersectionInfo( cvf::Vec3d intersectionPoint,
bool isIntersectionEntering,
cvf::StructGridInterface::FaceType face,
size_t hexIndex)
: m_intersectionPoint(intersectionPoint),
m_isIntersectionEntering(isIntersectionEntering),
m_face(face),
m_hexIndex(hexIndex) {}
cvf::Vec3d m_intersectionPoint;
bool m_isIntersectionEntering;
cvf::StructGridInterface::FaceType m_face;
size_t m_hexIndex;
};
//--------------------------------------------------------------------------------------------------
/// Specialized Line - Hex intersection
//--------------------------------------------------------------------------------------------------
struct RigHexIntersectionTools
{
static int lineHexCellIntersection(const cvf::Vec3d p1,
const cvf::Vec3d p2,
const cvf::Vec3d hexCorners[8],
const size_t hexIndex,
std::vector<HexIntersectionInfo>* intersections);
static bool isPointInCell(const cvf::Vec3d point, const cvf::Vec3d hexCorners[8]);
};

View File

@@ -20,7 +20,7 @@
#include "RigWellLogCurveData.h"
#include "RimCase.h"
#include "RimDefines.h"
#include "RiaDefines.h"
#include "RimWellLogCurve.h"
#include "RimWellLogExtractionCurve.h"
@@ -196,15 +196,15 @@ public:
const RigWellLogCurveData* firstCurveData = curveDataForFirstCurve();
if (firstCurveData->depthUnit() == RimDefines::UNIT_METER)
if (firstCurveData->depthUnit() == RiaDefines::UNIT_METER)
{
lasFile->AddLog("DEPTH", "M", "Depth in meters", firstCurveData->measuredDepths());
}
else if (firstCurveData->depthUnit() == RimDefines::UNIT_FEET)
else if (firstCurveData->depthUnit() == RiaDefines::UNIT_FEET)
{
lasFile->AddLog("DEPTH", "FT", "Depth in feet", firstCurveData->measuredDepths());
}
else if ( firstCurveData->depthUnit() == RimDefines::UNIT_NONE )
else if ( firstCurveData->depthUnit() == RiaDefines::UNIT_NONE )
{
CVF_ASSERT(false);
lasFile->AddLog("DEPTH", "", "Depth in Connection number", firstCurveData->measuredDepths());
@@ -223,15 +223,15 @@ public:
value += m_rkbDiff;
}
if (firstCurveData->depthUnit() == RimDefines::UNIT_METER)
if (firstCurveData->depthUnit() == RiaDefines::UNIT_METER)
{
lasFile->AddLog("TVDRKB", "M", "True vertical depth (Rotary Kelly Bushing)", tvdrkbValues);
}
else if (firstCurveData->depthUnit() == RimDefines::UNIT_FEET)
else if (firstCurveData->depthUnit() == RiaDefines::UNIT_FEET)
{
lasFile->AddLog("TVDRKB", "FT", "True vertical depth (Rotary Kelly Bushing)", tvdrkbValues);
}
else if ( firstCurveData->depthUnit() == RimDefines::UNIT_NONE )
else if ( firstCurveData->depthUnit() == RiaDefines::UNIT_NONE )
{
CVF_ASSERT(false);
lasFile->AddLog("TVDRKB", "", "", tvdrkbValues);
@@ -247,15 +247,15 @@ public:
lasFile->setStartDepth(minDepth);
lasFile->setStopDepth(maxDepth);
if (firstCurveData->depthUnit() == RimDefines::UNIT_METER)
if (firstCurveData->depthUnit() == RiaDefines::UNIT_METER)
{
lasFile->setDepthUnit("M");
}
else if (firstCurveData->depthUnit() == RimDefines::UNIT_FEET)
else if (firstCurveData->depthUnit() == RiaDefines::UNIT_FEET)
{
lasFile->setDepthUnit("FT");
}
else if ( firstCurveData->depthUnit() == RimDefines::UNIT_NONE )
else if ( firstCurveData->depthUnit() == RiaDefines::UNIT_NONE )
{
CVF_ASSERT(false);
}
@@ -299,7 +299,7 @@ private:
double m_rkbDiff;
bool m_exportTvdrkb;
RimDefines::DepthUnitType m_depthUnit;
RiaDefines::DepthUnitType m_depthUnit;
std::vector<double> m_depthValues;
std::vector<SingleChannelData> m_logCurveData;

View File

@@ -21,7 +21,7 @@
#include "RigMainGrid.h"
#include "RiaLogging.h"
#include "RimDefines.h"
#include "RiaDefines.h"
#include "RigFault.h"
#include "RigActiveCellInfo.h"
@@ -237,8 +237,8 @@ bool RigMainGrid::hasFaultWithName(const QString& name) const
//--------------------------------------------------------------------------------------------------
void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo)
{
if (hasFaultWithName(RimDefines::undefinedGridFaultName())
&& hasFaultWithName(RimDefines::undefinedGridFaultWithInactiveName()))
if (hasFaultWithName(RiaDefines::undefinedGridFaultName())
&& hasFaultWithName(RiaDefines::undefinedGridFaultWithInactiveName()))
{
//RiaLogging::debug(QString("Calculate faults already run for grid."));
return;
@@ -255,12 +255,12 @@ void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo)
// Separate the grid faults that has an inactive cell as member
RigFault* unNamedFault = new RigFault;
unNamedFault->setName(RimDefines::undefinedGridFaultName());
unNamedFault->setName(RiaDefines::undefinedGridFaultName());
int unNamedFaultIdx = static_cast<int>(m_faults.size());
m_faults.push_back(unNamedFault);
RigFault* unNamedFaultWithInactive = new RigFault;
unNamedFaultWithInactive->setName(RimDefines::undefinedGridFaultWithInactiveName());
unNamedFaultWithInactive->setName(RiaDefines::undefinedGridFaultWithInactiveName());
int unNamedFaultWithInactiveIdx = static_cast<int>(m_faults.size());
m_faults.push_back(unNamedFaultWithInactive);

View File

@@ -250,7 +250,7 @@ void RigReservoirBuilderMock::populateReservoir(RigEclipseCaseData* eclipseCase)
addFaults(eclipseCase);
// Set all cells active
RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS);
RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo(RiaDefines::MATRIX_MODEL);
activeCellInfo->setReservoirCellCount(eclipseCase->mainGrid()->globalCellArray().size());
for (size_t i = 0; i < eclipseCase->mainGrid()->globalCellArray().size(); i++)
{

View File

@@ -0,0 +1,143 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigReservoirGridTools.h"
#include "RigActiveCellInfo.h"
#include "RigEclipseCaseData.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"
#include "RigGeoMechCaseData.h"
#include "RigMainGrid.h"
#include "RimEclipseCase.h"
#include "RimGeoMechCase.h"
#include "RimEclipseView.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RigReservoirGridTools::gridCount(RimCase* rimCase)
{
RigMainGrid* eclipseMainGrid = RigReservoirGridTools::eclipseMainGrid(rimCase);
RigFemPartCollection* geoMechPartCollection = RigReservoirGridTools::geoMechPartCollection(rimCase);
if (eclipseMainGrid)
{
return static_cast<int>(eclipseMainGrid->gridCount());
}
else if (geoMechPartCollection)
{
return geoMechPartCollection->partCount();
}
return 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const cvf::StructGridInterface* RigReservoirGridTools::mainGrid(RimCase* rimCase)
{
return gridByIndex(rimCase, 0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const cvf::StructGridInterface* RigReservoirGridTools::gridByIndex(RimCase* rimCase, int gridIndex)
{
RigMainGrid* eclipseMainGrid = RigReservoirGridTools::eclipseMainGrid(rimCase);
RigFemPartCollection* geoMechPartCollection = RigReservoirGridTools::geoMechPartCollection(rimCase);
if (eclipseMainGrid)
{
return eclipseMainGrid->gridByIndex(gridIndex);
}
else if (geoMechPartCollection)
{
return geoMechPartCollection->part(gridIndex)->structGrid();
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RigReservoirGridTools::gridName(RimCase* rimCase, int gridIndex)
{
RigMainGrid* eclipseMainGrid = RigReservoirGridTools::eclipseMainGrid(rimCase);
RigFemPartCollection* geoMechPartCollection = RigReservoirGridTools::geoMechPartCollection(rimCase);
if (eclipseMainGrid)
{
return eclipseMainGrid->gridByIndex(gridIndex)->gridName().c_str();
}
else if (geoMechPartCollection)
{
return QString::number(gridIndex);
}
return "";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigActiveCellInfo* RigReservoirGridTools::activeCellInfo(RimView* rimView)
{
RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>(rimView);
if (eclipseView)
{
return eclipseView->currentActiveCellInfo();
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigMainGrid* RigReservoirGridTools::eclipseMainGrid(RimCase* rimCase)
{
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(rimCase);
if (eclipseCase && eclipseCase->eclipseCaseData())
{
return eclipseCase->eclipseCaseData()->mainGrid();
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartCollection* RigReservoirGridTools::geoMechPartCollection(RimCase* rimCase)
{
RimGeoMechCase* geoMechCase = dynamic_cast<RimGeoMechCase*>(rimCase);
if (geoMechCase && geoMechCase->geoMechData())
{
return geoMechCase->geoMechData()->femParts();
}
return nullptr;
}

View File

@@ -0,0 +1,52 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 RigActiveCellInfo;
class RigFemPartCollection;
class RigMainGrid;
class RimCase;
class RimView;
namespace cvf
{
class StructGridInterface;
}
class QString;
//==================================================================================================
///
///
//==================================================================================================
class RigReservoirGridTools
{
public:
static int gridCount(RimCase* rimCase);
static const cvf::StructGridInterface* mainGrid(RimCase* rimCase);
static const cvf::StructGridInterface* gridByIndex(RimCase* rimCase, int gridIndex);
static QString gridName(RimCase* rimCase, int gridIndex);
static RigActiveCellInfo* activeCellInfo(RimView* rimView);
private:
static RigMainGrid* eclipseMainGrid(RimCase* rimCase);
static RigFemPartCollection* geoMechPartCollection(RimCase* rimCase);
};

View File

@@ -41,7 +41,7 @@
//--------------------------------------------------------------------------------------------------
cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromUiResultName(RigEclipseCaseData* eclipseCase,
size_t gridIndex,
RifReaderInterface::PorosityModelResultType porosityModel,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex,
const QString& uiResultName)
{
@@ -52,7 +52,7 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromUiResultName(Rig
RigGridBase* grid = eclipseCase->grid(gridIndex);
if (uiResultName == RimDefines::combinedTransmissibilityResultName())
if (uiResultName == RiaDefines::combinedTransmissibilityResultName())
{
CVF_ASSERT(timeStepIndex == 0); // Static result, only data for first time step
@@ -66,7 +66,7 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromUiResultName(Rig
return cellFaceAccessObject;
}
else if (uiResultName == RimDefines::combinedMultResultName())
else if (uiResultName == RiaDefines::combinedMultResultName())
{
CVF_ASSERT(timeStepIndex == 0); // Static result, only data for first time step
@@ -83,49 +83,49 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromUiResultName(Rig
return cellFaceAccessObject;
}
else if (uiResultName == RimDefines::combinedRiTranResultName())
else if (uiResultName == RiaDefines::combinedRiTranResultName())
{
CVF_ASSERT(timeStepIndex == 0); // Static result, only data for first time step
cvf::ref<RigCombTransResultAccessor> cellFaceAccessObject = new RigCombTransResultAccessor(grid);
cvf::ref<RigResultAccessor> xTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riTranXResultName());
cvf::ref<RigResultAccessor> yTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riTranYResultName());
cvf::ref<RigResultAccessor> zTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riTranZResultName());
cvf::ref<RigResultAccessor> xTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RiaDefines::riTranXResultName());
cvf::ref<RigResultAccessor> yTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RiaDefines::riTranYResultName());
cvf::ref<RigResultAccessor> zTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RiaDefines::riTranZResultName());
cellFaceAccessObject->setTransResultAccessors(xTransAccessor.p(), yTransAccessor.p(), zTransAccessor.p());
return cellFaceAccessObject;
}
else if (uiResultName == RimDefines::combinedRiMultResultName())
else if (uiResultName == RiaDefines::combinedRiMultResultName())
{
CVF_ASSERT(timeStepIndex == 0); // Static result, only data for first time step
cvf::ref<RigCombTransResultAccessor> cellFaceAccessObject = new RigCombTransResultAccessor(grid);
cvf::ref<RigResultAccessor> xRiMultAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riMultXResultName());
cvf::ref<RigResultAccessor> yRiMultAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riMultYResultName());
cvf::ref<RigResultAccessor> zRiMultAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riMultZResultName());
cvf::ref<RigResultAccessor> xRiMultAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RiaDefines::riMultXResultName());
cvf::ref<RigResultAccessor> yRiMultAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RiaDefines::riMultYResultName());
cvf::ref<RigResultAccessor> zRiMultAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RiaDefines::riMultZResultName());
cellFaceAccessObject->setTransResultAccessors(xRiMultAccessor.p(), yRiMultAccessor.p(), zRiMultAccessor.p());
return cellFaceAccessObject;
}
else if (uiResultName == RimDefines::combinedRiAreaNormTranResultName())
else if (uiResultName == RiaDefines::combinedRiAreaNormTranResultName())
{
CVF_ASSERT(timeStepIndex == 0); // Static result, only data for first time step
cvf::ref<RigCombTransResultAccessor> cellFaceAccessObject = new RigCombTransResultAccessor(grid);
cvf::ref<RigResultAccessor> xRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riAreaNormTranXResultName());
cvf::ref<RigResultAccessor> yRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riAreaNormTranYResultName());
cvf::ref<RigResultAccessor> zRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riAreaNormTranZResultName());
cvf::ref<RigResultAccessor> xRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RiaDefines::riAreaNormTranXResultName());
cvf::ref<RigResultAccessor> yRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RiaDefines::riAreaNormTranYResultName());
cvf::ref<RigResultAccessor> zRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, RiaDefines::riAreaNormTranZResultName());
cellFaceAccessObject->setTransResultAccessors(xRiAreaNormTransAccessor.p(), yRiAreaNormTransAccessor.p(), zRiAreaNormTransAccessor.p());
return cellFaceAccessObject;
}
else if (uiResultName == RimDefines::combinedWaterFluxResultName())
else if (uiResultName == RiaDefines::combinedWaterFluxResultName())
{
cvf::ref<RigCombTransResultAccessor> cellFaceAccessObject = new RigCombTransResultAccessor(grid);
@@ -137,7 +137,7 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromUiResultName(Rig
return cellFaceAccessObject;
}
else if (uiResultName == RimDefines::combinedOilFluxResultName())
else if (uiResultName == RiaDefines::combinedOilFluxResultName())
{
cvf::ref<RigCombTransResultAccessor> cellFaceAccessObject = new RigCombTransResultAccessor(grid);
@@ -149,7 +149,7 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromUiResultName(Rig
return cellFaceAccessObject;
}
else if (uiResultName == RimDefines::combinedGasFluxResultName())
else if (uiResultName == RiaDefines::combinedGasFluxResultName())
{
cvf::ref<RigCombTransResultAccessor> cellFaceAccessObject = new RigCombTransResultAccessor(grid);
@@ -183,10 +183,10 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromUiResultName(Rig
//--------------------------------------------------------------------------------------------------
cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromNameAndType(RigEclipseCaseData* eclipseCase,
size_t gridIndex,
RifReaderInterface::PorosityModelResultType porosityModel,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex,
const QString& uiResultName,
RimDefines::ResultCatType resultType)
RiaDefines::ResultCatType resultType)
{
CVF_ASSERT(gridIndex < eclipseCase->gridCount());
CVF_ASSERT(eclipseCase);
@@ -205,7 +205,7 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromNameAndType(RigE
}
size_t adjustedTimeStepIndex = timeStepIndex;
if (resultType == RimDefines::STATIC_NATIVE)
if (resultType == RiaDefines::STATIC_NATIVE)
{
adjustedTimeStepIndex = 0;
}
@@ -221,9 +221,7 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromResultDefinition
size_t timeStepIndex,
RimEclipseResultDefinition* resultDefinition)
{
RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultDefinition->porosityModel());
if (resultDefinition->resultType() != RimDefines::FLOW_DIAGNOSTICS)
if (resultDefinition->resultType() != RiaDefines::FLOW_DIAGNOSTICS)
{
size_t adjustedTimeStepIndex = timeStepIndex;
@@ -234,7 +232,7 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromResultDefinition
return RigResultAccessorFactory::createFromUiResultName(eclipseCase,
gridIndex,
porosityModel,
resultDefinition->porosityModel(),
adjustedTimeStepIndex,
resultDefinition->resultVariable());
}
@@ -249,7 +247,7 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromResultDefinition
RigGridBase* grid = eclipseCase->grid(gridIndex);
if ( !grid ) return new RigHugeValResultAccessor;
cvf::ref<RigResultAccessor> object = new RigActiveCellsResultAccessor(grid, resultValues, eclipseCase->activeCellInfo(porosityModel));
cvf::ref<RigResultAccessor> object = new RigActiveCellsResultAccessor(grid, resultValues, eclipseCase->activeCellInfo(resultDefinition->porosityModel()));
return object;
}
@@ -260,7 +258,7 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromResultDefinition
//--------------------------------------------------------------------------------------------------
cvf::ref<RigResultAccessor> RigResultAccessorFactory::createNativeFromUiResultName(RigEclipseCaseData* eclipseCase,
size_t gridIndex,
RifReaderInterface::PorosityModelResultType porosityModel,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex,
const QString& uiResultName)
{
@@ -288,7 +286,7 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createNativeFromUiResultNa
//--------------------------------------------------------------------------------------------------
cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromResultIdx(RigEclipseCaseData* eclipseCase,
size_t gridIndex,
RifReaderInterface::PorosityModelResultType porosityModel,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex,
size_t resultIndex)
{

View File

@@ -22,7 +22,7 @@
#include "RifReaderInterface.h"
#include "RigResultAccessor.h"
#include "RimDefines.h"
#include "RiaDefines.h"
class RigActiveCellInfo;
class RigGridBase;
@@ -41,22 +41,22 @@ public:
static cvf::ref<RigResultAccessor>
createFromUiResultName(RigEclipseCaseData* eclipseCase,
size_t gridIndex,
RifReaderInterface::PorosityModelResultType porosityModel,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex,
const QString& uiResultName);
static cvf::ref<RigResultAccessor>
createFromNameAndType(RigEclipseCaseData* eclipseCase,
size_t gridIndex,
RifReaderInterface::PorosityModelResultType porosityModel,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex,
const QString& uiResultName,
RimDefines::ResultCatType resultType);
RiaDefines::ResultCatType resultType);
static cvf::ref<RigResultAccessor>
createFromResultIdx(RigEclipseCaseData* eclipseCase,
size_t gridIndex,
RifReaderInterface::PorosityModelResultType porosityModel,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex,
size_t resultIndex);
@@ -64,7 +64,7 @@ private:
static cvf::ref<RigResultAccessor>
createNativeFromUiResultName(RigEclipseCaseData* eclipseCase,
size_t gridIndex,
RifReaderInterface::PorosityModelResultType porosityModel,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex,
const QString& resultName);

View File

@@ -31,7 +31,7 @@
//--------------------------------------------------------------------------------------------------
cvf::ref<RigResultModifier> RigResultModifierFactory::createResultModifier(RigEclipseCaseData* eclipseCase,
size_t gridIndex,
RifReaderInterface::PorosityModelResultType porosityModel,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex,
QString& uiResultName)
{
@@ -53,7 +53,7 @@ cvf::ref<RigResultModifier> RigResultModifierFactory::createResultModifier(RigEc
//--------------------------------------------------------------------------------------------------
cvf::ref<RigResultModifier> RigResultModifierFactory::createResultModifier(RigEclipseCaseData* eclipseCase,
size_t gridIndex,
RifReaderInterface::PorosityModelResultType porosityModel,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex, size_t scalarResultIndex)
{
if ( !eclipseCase ) return NULL;

View File

@@ -30,14 +30,14 @@ public:
static cvf::ref<RigResultModifier>
createResultModifier(RigEclipseCaseData* eclipseCase,
size_t gridIndex,
RifReaderInterface::PorosityModelResultType porosityModel,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex,
QString& uiResultName);
static cvf::ref<RigResultModifier>
createResultModifier(RigEclipseCaseData* eclipseCase,
size_t gridIndex,
RifReaderInterface::PorosityModelResultType porosityModel,
RiaDefines::PorosityModelType porosityModel,
size_t timeStepIndex,
size_t scalarResultIndex);
};

View File

@@ -37,12 +37,12 @@ const RigWellResultFrame& RigSingleWellResultsData::wellResultFrame(size_t resul
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigSingleWellResultsData::computeMappingFromResultTimeIndicesToWellTimeIndices(const std::vector<QDateTime>& resultTimes)
void RigSingleWellResultsData::computeMappingFromResultTimeIndicesToWellTimeIndices(const std::vector<QDateTime>& simulationTimeSteps)
{
m_resultTimeStepIndexToWellTimeStepIndex.clear();
if (m_wellCellsTimeSteps.size() == 0) return;
m_resultTimeStepIndexToWellTimeStepIndex.resize(resultTimes.size(), cvf::UNDEFINED_SIZE_T);
m_resultTimeStepIndexToWellTimeStepIndex.resize(simulationTimeSteps.size(), cvf::UNDEFINED_SIZE_T);
if (false)
{
@@ -54,29 +54,23 @@ void RigSingleWellResultsData::computeMappingFromResultTimeIndicesToWellTimeIndi
}
qDebug() << "Result TimeStamps";
for (size_t i = 0; i < resultTimes.size(); i++)
for (size_t i = 0; i < simulationTimeSteps.size(); i++)
{
qDebug() << resultTimes[i].toString();
qDebug() << simulationTimeSteps[i].toString();
}
}
int resultIdx = 0;
size_t wellIdx = 0;
size_t activeWellIdx = cvf::UNDEFINED_SIZE_T;
while (wellIdx <= m_wellCellsTimeSteps.size() && resultIdx < static_cast<int>(resultTimes.size()))
for (size_t resultTimeStepIndex = 0; resultTimeStepIndex< simulationTimeSteps.size(); resultTimeStepIndex++)
{
if (wellIdx < m_wellCellsTimeSteps.size() && m_wellCellsTimeSteps[wellIdx].m_timestamp <= resultTimes[resultIdx])
size_t wellTimeStepIndex = 0;
while (wellTimeStepIndex < m_wellCellsTimeSteps.size() &&
m_wellCellsTimeSteps[wellTimeStepIndex].m_timestamp < simulationTimeSteps[resultTimeStepIndex])
{
activeWellIdx = wellIdx;
wellIdx++;
wellTimeStepIndex++;
}
CVF_ASSERT(resultIdx < static_cast<int>(m_resultTimeStepIndexToWellTimeStepIndex.size()));
m_resultTimeStepIndexToWellTimeStepIndex[resultIdx] = activeWellIdx;
resultIdx++;
m_resultTimeStepIndexToWellTimeStepIndex[resultTimeStepIndex] = wellTimeStepIndex;
}
}

View File

@@ -21,12 +21,12 @@
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfMath.h"
#include "RimDefines.h"
#include <QDateTime>
#include <vector>
#include "cvfVector3.h"
#include <QDateTime>
#include <vector>
//==================================================================================================
/// Stores the info on a significant point in the well. Either a well-to-grid connection, or the
/// bottom position of a connection less well-segment

View File

@@ -0,0 +1,137 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigTofAccumulatedPhaseFractionsCalculator.h"
#include "RiaDefines.h"
#include "RiaPorosityModel.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
#include "RigFlowDiagResultAddress.h"
#include "RigFlowDiagResults.h"
#include "RigResultAccessor.h"
#include "RigResultAccessorFactory.h"
#include "RigSingleWellResultsData.h"
#include "RimEclipseResultCase.h"
#include "RimFlowDiagSolution.h"
#include "RimReservoirCellResultsStorage.h"
#include <map>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigTofAccumulatedPhaseFractionsCalculator::RigTofAccumulatedPhaseFractionsCalculator(RimEclipseResultCase* caseToApply,
QString wellname,
size_t timestep)
{
RigEclipseCaseData* eclipseCaseData = caseToApply->eclipseCaseData();
RiaDefines::PorosityModelType porosityModel = RiaDefines::MATRIX_MODEL;
RimReservoirCellResultsStorage* gridCellResults = caseToApply->results(porosityModel);
size_t scalarResultIndexSwat = gridCellResults->findOrLoadScalarResult(RiaDefines::DYNAMIC_NATIVE, "SWAT");
size_t scalarResultIndexSoil = gridCellResults->findOrLoadScalarResult(RiaDefines::DYNAMIC_NATIVE, "SOIL");
size_t scalarResultIndexSgas = gridCellResults->findOrLoadScalarResult(RiaDefines::DYNAMIC_NATIVE, "SGAS");
size_t scalarResultIndexPorv = gridCellResults->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "PORV");
const std::vector<double>* swatResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexSwat, timestep));
const std::vector<double>* soilResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexSoil, timestep));
const std::vector<double>* sgasResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexSgas, timestep));
const std::vector<double>* porvResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexPorv, timestep));
RimFlowDiagSolution* flowDiagSolution = caseToApply->defaultFlowDiagSolution();
std::string resultNameTof = "TOF";
const std::vector<double>* tofData = flowDiagSolution->flowDiagResults()->resultValues(RigFlowDiagResultAddress(resultNameTof,
RigFlowDiagResultAddress::PhaseSelection::PHASE_ALL,
wellname.toStdString()),
timestep);
std::string resultNameFraction = "Fraction";
const std::vector<double>* fractionData = flowDiagSolution->flowDiagResults()->resultValues(RigFlowDiagResultAddress(resultNameFraction,
RigFlowDiagResultAddress::PhaseSelection::PHASE_ALL,
wellname.toStdString()),
timestep);
sortTofAndCalculateAccPhaseFraction(tofData,
fractionData,
porvResults,
swatResults,
soilResults,
sgasResults,
m_accumulatedPhaseFractionSwat,
m_accumulatedPhaseFractionSoil,
m_accumulatedPhaseFractionSgas,
m_tofInIncreasingOrder);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigTofAccumulatedPhaseFractionsCalculator::sortTofAndCalculateAccPhaseFraction(const std::vector<double>* tofData,
const std::vector<double>* fractionData,
const std::vector<double>* porvResults,
const std::vector<double>* swatResults,
const std::vector<double>* soilResults,
const std::vector<double>* sgasResults,
std::vector<double>& tofInIncreasingOrder,
std::vector<double>& accumulatedPhaseFractionSwat,
std::vector<double>& accumulatedPhaseFractionSoil,
std::vector<double>& accumulatedPhaseFractionSgas)
{
std::map<double, std::vector<int> > tofAndIndexMap;
for (int i = 0; i < static_cast<int>(tofData->size()); i++)
{
std::vector<int> vectorOfIndexes;
vectorOfIndexes.push_back(i);
auto iteratorBoolFromInsertToMap = tofAndIndexMap.insert(std::make_pair(tofData->at(i), vectorOfIndexes));
if (!iteratorBoolFromInsertToMap.second)
{
//Element exist already, was not inserted
iteratorBoolFromInsertToMap.first->second.push_back(i);
}
}
double fractionPorvSum = 0.0;
double fractionPorvPhaseSumSwat = 0.0;
double fractionPorvPhaseSumSoil = 0.0;
double fractionPorvPhaseSumSgas = 0.0;
for (auto element : tofAndIndexMap)
{
double tofValue = element.first;
for (int index : element.second)
{
fractionPorvSum += fractionData->at(index) * porvResults->at(index);
fractionPorvPhaseSumSwat += fractionData->at(index) * porvResults->at(index) * swatResults->at(index);
fractionPorvPhaseSumSoil += fractionData->at(index) * porvResults->at(index) * soilResults->at(index);
fractionPorvPhaseSumSgas += fractionData->at(index) * porvResults->at(index) * sgasResults->at(index);
}
tofInIncreasingOrder.push_back(tofValue);
accumulatedPhaseFractionSwat.push_back(fractionPorvPhaseSumSwat / fractionPorvSum);
accumulatedPhaseFractionSoil.push_back(fractionPorvPhaseSumSoil / fractionPorvSum);
accumulatedPhaseFractionSgas.push_back(fractionPorvPhaseSumSgas / fractionPorvSum);
}
}

View File

@@ -0,0 +1,91 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <cstddef>
#include <vector>
class RimEclipseResultCase;
class QString;
//==================================================================================================
///
//==================================================================================================
class RigTofAccumulatedPhaseFractionsCalculator
{
public:
explicit RigTofAccumulatedPhaseFractionsCalculator(RimEclipseResultCase* caseToApply,
QString wellname,
size_t timestep);
const std::vector<double>& sortedUniqueTOFValues() const { return m_tofInIncreasingOrder; }
const std::vector<double>& accumulatedPhaseFractionsSwat() const { return m_accumulatedPhaseFractionSwat; }
const std::vector<double>& accumulatedPhaseFractionsSoil() const { return m_accumulatedPhaseFractionSoil; }
const std::vector<double>& accumulatedPhaseFractionsSgas() const { return m_accumulatedPhaseFractionSgas; }
private:
friend class RigTofAccumulatedPhaseFractionsCalculatorTester;
static void sortTofAndCalculateAccPhaseFraction(const std::vector<double>* tofData,
const std::vector<double>* fractionData,
const std::vector<double>* porvResults,
const std::vector<double>* swatResults,
const std::vector<double>* soilResults,
const std::vector<double>* sgasResults,
std::vector<double>& tofInIncreasingOrder,
std::vector<double>& accumulatedPhaseFractionSwat,
std::vector<double>& accumulatedPhaseFractionSoil,
std::vector<double>& accumulatedPhaseFractionSgas);
private:
std::vector<double> m_tofInIncreasingOrder;
std::vector<double> m_accumulatedPhaseFractionSwat;
std::vector<double> m_accumulatedPhaseFractionSgas;
std::vector<double> m_accumulatedPhaseFractionSoil;
};
class RigTofAccumulatedPhaseFractionsCalculatorTester
{
public:
static void testSortTofAndCalculateAccPhaseFraction(const std::vector<double>* tofData,
const std::vector<double>* fractionData,
const std::vector<double>* porvResults,
const std::vector<double>* swatResults,
const std::vector<double>* soilResults,
const std::vector<double>* sgasResults,
std::vector<double>& tofInIncreasingOrder,
std::vector<double>& accumulatedPhaseFractionSwat,
std::vector<double>& accumulatedPhaseFractionSoil,
std::vector<double>& accumulatedPhaseFractionSgas)
{
RigTofAccumulatedPhaseFractionsCalculator::sortTofAndCalculateAccPhaseFraction(tofData,
fractionData,
porvResults,
swatResults,
soilResults,
sgasResults,
tofInIncreasingOrder,
accumulatedPhaseFractionSwat,
accumulatedPhaseFractionSoil,
accumulatedPhaseFractionSgas);
}
};

View File

@@ -0,0 +1,82 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigTransmissibilityEquations.h"
#include "cvfBase.h"
#include "cvfMath.h"
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigTransmissibilityEquations::peacemanRadius(double permeabilityNormalDirection1,
double permeabilityNormalDirection2,
double cellSizeNormalDirection1,
double cellSizeNormalDirection2)
{
double numerator = cvf::Math::sqrt(
pow(cellSizeNormalDirection2, 2) * pow(permeabilityNormalDirection1 / permeabilityNormalDirection2, 1 / 2)
+ pow(cellSizeNormalDirection1, 2) * pow(permeabilityNormalDirection2 / permeabilityNormalDirection1, 1 / 2));
double denominator = pow((permeabilityNormalDirection1 / permeabilityNormalDirection2), 1 / 4)
+ pow((permeabilityNormalDirection2 / permeabilityNormalDirection1), 1 / 4);
double r0 = 0.28 * numerator / denominator;
return r0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigTransmissibilityEquations::wellBoreTransmissibilityComponent(double cellPerforationVectorComponent,
double permeabilityNormalDirection1,
double permeabilityNormalDirection2,
double cellSizeNormalDirection1,
double cellSizeNormalDirection2,
double wellRadius,
double skinFactor,
double cDarcyForRelevantUnit)
{
double K = cvf::Math::sqrt(permeabilityNormalDirection1 * permeabilityNormalDirection2);
double nominator = cDarcyForRelevantUnit * 2 * cvf::PI_D * K * cellPerforationVectorComponent;
double peaceManRad = peacemanRadius(permeabilityNormalDirection1,
permeabilityNormalDirection2,
cellSizeNormalDirection1,
cellSizeNormalDirection2);
double denominator = log(peaceManRad / wellRadius) + skinFactor;
double trans = nominator / denominator;
return trans;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigTransmissibilityEquations::totalConnectionFactor(double transX, double transY, double transZ)
{
return cvf::Math::sqrt(
pow(transX, 2.0) + pow(transY, 2.0) + pow(transZ, 2));
}

View File

@@ -0,0 +1,52 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 RigTransmissibilityEquations
{
public:
// Calculations are assuming an orthogonal coordinate system
// If using wellBoreTransmissibilityComponent to calculate Tx (transmissibility in x direction),
// perforationVectorComponent is the x component (in the cell local coordinate system) of the perforation vector
// permeability and cell size for Z and Y are to be specified as "normal directions" 1 and 2
// but normal directions 1 and 2 are interchangeable (so Z=1, Y=2 and Z=2, Y=1 gives same result)
static double peacemanRadius(double permeabilityNormalDirection1,
double permeabilityNormalDirection2,
double cellSizeNormalDirection1,
double cellSizeNormalDirection2);
static double wellBoreTransmissibilityComponent(double cellPerforationVectorComponent,
double permeabilityNormalDirection1,
double permeabilityNormalDirection2,
double cellSizeNormalDirection1,
double cellSizeNormalDirection2,
double wellRadius,
double skinFactor,
double cDarcyForRelevantUnit);
static double totalConnectionFactor(double transX,
double transY,
double transZ);
};

View File

@@ -21,6 +21,8 @@
#include "RigCurveDataTools.h"
#include "RiaEclipseUnitTools.h"
#include "cvfMath.h"
#include "cvfAssert.h"
@@ -32,7 +34,7 @@
RigWellLogCurveData::RigWellLogCurveData()
{
m_isExtractionCurve = false;
m_depthUnit = RimDefines::UNIT_METER;
m_depthUnit = RiaDefines::UNIT_METER;
}
//--------------------------------------------------------------------------------------------------
@@ -47,7 +49,7 @@ RigWellLogCurveData::~RigWellLogCurveData()
//--------------------------------------------------------------------------------------------------
void RigWellLogCurveData::setValuesAndMD(const std::vector<double>& xValues,
const std::vector<double>& measuredDepths,
RimDefines::DepthUnitType depthUnit,
RiaDefines::DepthUnitType depthUnit,
bool isExtractionCurve)
{
CVF_ASSERT(xValues.size() == measuredDepths.size());
@@ -70,7 +72,7 @@ void RigWellLogCurveData::setValuesAndMD(const std::vector<double>& xValues,
void RigWellLogCurveData::setValuesWithTVD(const std::vector<double>& xValues,
const std::vector<double>& measuredDepths,
const std::vector<double>& tvDepths,
RimDefines::DepthUnitType depthUnit)
RiaDefines::DepthUnitType depthUnit)
{
CVF_ASSERT(xValues.size() == measuredDepths.size());
@@ -124,7 +126,7 @@ std::vector<double> RigWellLogCurveData::xPlotValues() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RigWellLogCurveData::trueDepthPlotValues(RimDefines::DepthUnitType destinationDepthUnit) const
std::vector<double> RigWellLogCurveData::trueDepthPlotValues(RiaDefines::DepthUnitType destinationDepthUnit) const
{
std::vector<double> filteredValues;
if(m_tvDepths.size())
@@ -146,7 +148,7 @@ std::vector<double> RigWellLogCurveData::trueDepthPlotValues(RimDefines::DepthUn
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RigWellLogCurveData::measuredDepthPlotValues(RimDefines::DepthUnitType destinationDepthUnit) const
std::vector<double> RigWellLogCurveData::measuredDepthPlotValues(RiaDefines::DepthUnitType destinationDepthUnit) const
{
std::vector<double> filteredValues;
@@ -352,7 +354,7 @@ bool RigWellLogCurveData::calculateMDRange(double* minimumDepth, double* maximum
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimDefines::DepthUnitType RigWellLogCurveData::depthUnit() const
RiaDefines::DepthUnitType RigWellLogCurveData::depthUnit() const
{
return m_depthUnit;
}
@@ -366,7 +368,7 @@ std::vector<double> RigWellLogCurveData::convertFromMeterToFeet(const std::vecto
for (size_t i = 0; i < valuesInMeter.size(); i++)
{
valuesInFeet[i] = valuesInMeter[i] * RimDefines::feetPerMeter();
valuesInFeet[i] = valuesInMeter[i] * RiaEclipseUnitTools::feetPerMeter();
}
return valuesInFeet;
@@ -381,7 +383,7 @@ std::vector<double> RigWellLogCurveData::convertFromFeetToMeter(const std::vecto
for (size_t i = 0; i < valuesInFeet.size(); i++)
{
valuesInMeter[i] = valuesInFeet[i] / RimDefines::feetPerMeter();
valuesInMeter[i] = valuesInFeet[i] / RiaEclipseUnitTools::feetPerMeter();
}
return valuesInMeter;
@@ -390,11 +392,11 @@ std::vector<double> RigWellLogCurveData::convertFromFeetToMeter(const std::vecto
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RigWellLogCurveData::convertDepthValues(RimDefines::DepthUnitType destinationDepthUnit, const std::vector<double>& values) const
std::vector<double> RigWellLogCurveData::convertDepthValues(RiaDefines::DepthUnitType destinationDepthUnit, const std::vector<double>& values) const
{
CVF_ASSERT(destinationDepthUnit != m_depthUnit);
if (destinationDepthUnit == RimDefines::UNIT_METER)
if (destinationDepthUnit == RiaDefines::UNIT_METER)
{
return convertFromFeetToMeter(values);
}

View File

@@ -19,7 +19,7 @@
#pragma once
#include "RimDefines.h"
#include "RiaDefines.h"
#include "cvfBase.h"
#include "cvfObject.h"
@@ -39,24 +39,24 @@ public:
void setValuesAndMD(const std::vector<double>& xValues,
const std::vector<double>& measuredDepths,
RimDefines::DepthUnitType depthUnit,
RiaDefines::DepthUnitType depthUnit,
bool isExtractionCurve);
void setValuesWithTVD(const std::vector<double>& xValues,
const std::vector<double>& measuredDepths,
const std::vector<double>& tvDepths,
RimDefines::DepthUnitType depthUnit);
RiaDefines::DepthUnitType depthUnit);
const std::vector<double>& xValues() const;
const std::vector<double>& measuredDepths() const;
const std::vector<double>& tvDepths() const;
bool calculateMDRange(double* minMD, double* maxMD) const;
RimDefines::DepthUnitType depthUnit() const;
RiaDefines::DepthUnitType depthUnit() const;
std::vector<double> xPlotValues() const;
std::vector<double> trueDepthPlotValues(RimDefines::DepthUnitType destinationDepthUnit) const;
std::vector<double> measuredDepthPlotValues(RimDefines::DepthUnitType destinationDepthUnit) const;
std::vector<double> trueDepthPlotValues(RiaDefines::DepthUnitType destinationDepthUnit) const;
std::vector<double> measuredDepthPlotValues(RiaDefines::DepthUnitType destinationDepthUnit) const;
std::vector< std::pair<size_t, size_t> > polylineStartStopIndices() const;
cvf::ref<RigWellLogCurveData> calculateResampledCurveData(double newMeasuredDepthStepSize) const;
@@ -68,7 +68,7 @@ private:
size_t startIdx, size_t stopIdx,
std::vector< std::pair<size_t, size_t> >* intervals);
std::vector<double> convertDepthValues(RimDefines::DepthUnitType destinationDepthUnit, const std::vector<double>& originalValues) const;
std::vector<double> convertDepthValues(RiaDefines::DepthUnitType destinationDepthUnit, const std::vector<double>& originalValues) const;
static std::vector<double> convertFromMeterToFeet(const std::vector<double>& valuesInMeter);
static std::vector<double> convertFromFeetToMeter(const std::vector<double>& valuesInFeet);
@@ -81,6 +81,6 @@ private:
std::vector< std::pair<size_t, size_t> > m_intervalsOfContinousValidValues;
RimDefines::DepthUnitType m_depthUnit;
RiaDefines::DepthUnitType m_depthUnit;
};

View File

@@ -18,80 +18,17 @@
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfBoundingBox.h"
#include "cvfGeometryTools.h"
#include "cvfStructGrid.h"
#include <cmath>
//==================================================================================================
/// Internal class for intersection point info
///
///
//==================================================================================================
struct HexIntersectionInfo
struct RigWellLogExtractionTools
{
public:
HexIntersectionInfo( cvf::Vec3d intersectionPoint,
bool isIntersectionEntering,
cvf::StructGridInterface::FaceType face,
size_t hexIndex)
: m_intersectionPoint(intersectionPoint),
m_isIntersectionEntering(isIntersectionEntering),
m_face(face),
m_hexIndex(hexIndex) {}
cvf::Vec3d m_intersectionPoint;
bool m_isIntersectionEntering;
cvf::StructGridInterface::FaceType m_face;
size_t m_hexIndex;
};
//--------------------------------------------------------------------------------------------------
/// Specialized Line - Hex intersection
//--------------------------------------------------------------------------------------------------
struct RigHexIntersector
{
static int lineHexCellIntersection(const cvf::Vec3d p1, const cvf::Vec3d p2, const cvf::Vec3d hexCorners[8], const size_t hexIndex,
std::vector<HexIntersectionInfo>* intersections)
static bool isEqualDepth(double d1, double d2)
{
CVF_ASSERT(intersections != NULL);
int intersectionCount = 0;
for (int face = 0; face < 6 ; ++face)
{
cvf::ubyte faceVertexIndices[4];
cvf::StructGridInterface::cellFaceVertexIndices(static_cast<cvf::StructGridInterface::FaceType>(face), faceVertexIndices);
cvf::Vec3d intersection;
bool isEntering = false;
cvf::Vec3d faceCenter = cvf::GeometryTools::computeFaceCenter(hexCorners[faceVertexIndices[0]], hexCorners[faceVertexIndices[1]], hexCorners[faceVertexIndices[2]], hexCorners[faceVertexIndices[3]]);
for (int i = 0; i < 4; ++i)
{
int next = i < 3 ? i+1 : 0;
int intsStatus = cvf::GeometryTools::intersectLineSegmentTriangle(p1, p2,
hexCorners[faceVertexIndices[i]],
hexCorners[faceVertexIndices[next]],
faceCenter,
&intersection,
&isEntering);
if (intsStatus == 1)
{
intersectionCount++;
intersections->push_back(HexIntersectionInfo(intersection,
isEntering,
static_cast<cvf::StructGridInterface::FaceType>(face), hexIndex));
}
}
}
return intersectionCount;
}
static bool isEqualDepth(double d1, double d2)
{
double depthDiff = d1 - d2;
const double tolerance = 0.1;// Meters To handle inaccuracies across faults
@@ -117,7 +54,7 @@ struct RigMDCellIdxEnterLeaveKey
bool operator < (const RigMDCellIdxEnterLeaveKey& other) const
{
if (RigHexIntersector::isEqualDepth(measuredDepth, other.measuredDepth))
if (RigWellLogExtractionTools::isEqualDepth(measuredDepth, other.measuredDepth))
{
if (hexIndex == other.hexIndex)
{
@@ -157,7 +94,7 @@ struct RigMDEnterLeaveCellIdxKey
bool operator < (const RigMDEnterLeaveCellIdxKey& other) const
{
if (RigHexIntersector::isEqualDepth(measuredDepth, other.measuredDepth))
if (RigWellLogExtractionTools::isEqualDepth(measuredDepth, other.measuredDepth))
{
if (isEnteringCell == other.isEnteringCell)
{
@@ -182,7 +119,7 @@ struct RigMDEnterLeaveCellIdxKey
{
return ( key1.hexIndex == key2.hexIndex
&& key1.isEnteringCell && key2.isLeavingCell()
&& !RigHexIntersector::isEqualDepth(key1.measuredDepth, key2.measuredDepth));
&& !RigWellLogExtractionTools::isEqualDepth(key1.measuredDepth, key2.measuredDepth));
}
};

View File

@@ -85,7 +85,7 @@ void RigWellLogExtractor::populateReturnArrays(std::map<RigMDCellIdxEnterLeaveKe
++it2;
if (it2 != uniqueIntersections.end())
{
if (RigHexIntersector::isEqualDepth(it1->first.measuredDepth, it2->first.measuredDepth))
if (RigWellLogExtractionTools::isEqualDepth(it1->first.measuredDepth, it2->first.measuredDepth))
{
if (it1->first.hexIndex == it2->first.hexIndex)
{

View File

@@ -25,9 +25,12 @@
#include "cvfVector3.h"
#include <vector>
#include <map>
#include "cvfStructGrid.h"
#include "RigWellLogExtractionTools.h"
#include "RigHexIntersectionTools.h"
class RigWellPath;

View File

@@ -208,7 +208,7 @@ QString RigWellLogFile::depthUnitString() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RigWellLogFile::wellLogChannelUnitString(const QString& wellLogChannelName, RimDefines::DepthUnitType displayDepthUnit) const
QString RigWellLogFile::wellLogChannelUnitString(const QString& wellLogChannelName, RiaDefines::DepthUnitType displayDepthUnit) const
{
QString unit;
@@ -222,15 +222,15 @@ QString RigWellLogFile::wellLogChannelUnitString(const QString& wellLogChannelNa
{
if (displayDepthUnit != depthUnit())
{
if (displayDepthUnit == RimDefines::UNIT_METER)
if (displayDepthUnit == RiaDefines::UNIT_METER)
{
return "M";
}
else if (displayDepthUnit == RimDefines::UNIT_FEET)
else if (displayDepthUnit == RiaDefines::UNIT_FEET)
{
return "FT";
}
else if (displayDepthUnit == RimDefines::UNIT_NONE)
else if (displayDepthUnit == RiaDefines::UNIT_NONE)
{
CVF_ASSERT(false);
return "";
@@ -279,15 +279,15 @@ bool RigWellLogFile::exportToLasFile(const RimWellLogCurve* curve, const QString
lasFile.addWellInfo("WELL", curve->wellName().trimmed().toStdString());
lasFile.addWellInfo("DATE", wellLogDate.toStdString());
if (curveData->depthUnit() == RimDefines::UNIT_METER)
if (curveData->depthUnit() == RiaDefines::UNIT_METER)
{
lasFile.AddLog("DEPTH", "M", "Depth in meters", curveData->measuredDepths());
}
else if (curveData->depthUnit() == RimDefines::UNIT_FEET)
else if (curveData->depthUnit() == RiaDefines::UNIT_FEET)
{
lasFile.AddLog("DEPTH", "FT", "Depth in feet", curveData->measuredDepths());
}
else if (curveData->depthUnit() == RimDefines::UNIT_NONE)
else if (curveData->depthUnit() == RiaDefines::UNIT_NONE)
{
CVF_ASSERT(false);
lasFile.AddLog("DEPTH", "", "Depth in connection number", curveData->measuredDepths());
@@ -308,15 +308,15 @@ bool RigWellLogFile::exportToLasFile(const RimWellLogCurve* curve, const QString
lasFile.setStartDepth(minDepth);
lasFile.setStopDepth(maxDepth);
if (curveData->depthUnit() == RimDefines::UNIT_METER)
if (curveData->depthUnit() == RiaDefines::UNIT_METER)
{
lasFile.setDepthUnit("M");
}
else if (curveData->depthUnit() == RimDefines::UNIT_FEET)
else if (curveData->depthUnit() == RiaDefines::UNIT_FEET)
{
lasFile.setDepthUnit("FT");
}
else if ( curveData->depthUnit() == RimDefines::UNIT_NONE )
else if ( curveData->depthUnit() == RiaDefines::UNIT_NONE )
{
CVF_ASSERT(false);
lasFile.setDepthUnit("");
@@ -333,13 +333,13 @@ bool RigWellLogFile::exportToLasFile(const RimWellLogCurve* curve, const QString
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimDefines::DepthUnitType RigWellLogFile::depthUnit() const
RiaDefines::DepthUnitType RigWellLogFile::depthUnit() const
{
RimDefines::DepthUnitType unitType = RimDefines::UNIT_METER;
RiaDefines::DepthUnitType unitType = RiaDefines::UNIT_METER;
if (depthUnitString().toUpper() == "F" || depthUnitString().toUpper() == "FT")
{
unitType = RimDefines::UNIT_FEET;
unitType = RiaDefines::UNIT_FEET;
}
return unitType;

View File

@@ -19,7 +19,7 @@
#pragma once
#include "RimDefines.h"
#include "RiaDefines.h"
#include "cvfBase.h"
#include "cvfObject.h"
@@ -51,8 +51,8 @@ public:
std::vector<double> depthValues() const;
std::vector<double> values(const QString& name) const;
QString wellLogChannelUnitString(const QString& wellLogChannelName, RimDefines::DepthUnitType displayDepthUnit) const;
RimDefines::DepthUnitType depthUnit() const;
QString wellLogChannelUnitString(const QString& wellLogChannelName, RiaDefines::DepthUnitType displayDepthUnit) const;
RiaDefines::DepthUnitType depthUnit() const;
static bool exportToLasFile(const RimWellLogCurve* curve, const QString& fileName);

View File

@@ -18,6 +18,8 @@
#include "RigWellPath.h"
#include "cvfGeometryTools.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -52,3 +54,146 @@ double RigWellPath::datumElevation() const
return m_datumElevation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3d RigWellPath::interpolatedPointAlongWellPath(double measuredDepth) const
{
cvf::Vec3d wellPathPoint = cvf::Vec3d::ZERO;
size_t i = 0;
while (i < m_measuredDepths.size() && m_measuredDepths.at(i) < measuredDepth )
{
i++;
}
if (m_measuredDepths.size() > i)
{
if (i == 0)
{
//For measuredDepth same or lower than first point, use this first point
wellPathPoint = m_wellPathPoints.at(0);
}
else
{
//Do interpolation
double stepsize = (measuredDepth - m_measuredDepths.at(i-1)) /
(m_measuredDepths.at(i) - m_measuredDepths.at(i - 1));
wellPathPoint = m_wellPathPoints.at(i - 1) + stepsize * (m_wellPathPoints.at(i) - m_wellPathPoints.at(i-1));
}
}
else
{
//Use endpoint if measuredDepth same or higher than last point
wellPathPoint = m_wellPathPoints.at(i-1);
}
return wellPathPoint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigWellPath::wellPathAzimuthAngle(const cvf::Vec3d& position) const
{
double azimuthAngle = 0.0;
cvf::Vec3d p1 = cvf::Vec3d::UNDEFINED;
cvf::Vec3d p2 = cvf::Vec3d::UNDEFINED;
twoClosestPoints(position, &p1, &p2);
if (!p1.isUndefined() && !p2.isUndefined())
{
cvf::Vec3d direction = p1 - p2;
if (abs(direction.x()) > 1e-5)
{
double atanValue = direction.y() / direction.x();
azimuthAngle = atan(atanValue);
azimuthAngle = cvf::Math::toDegrees(azimuthAngle);
azimuthAngle = -azimuthAngle;
}
}
return azimuthAngle;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigWellPath::twoClosestPoints(const cvf::Vec3d& position, cvf::Vec3d* p1, cvf::Vec3d* p2) const
{
CVF_ASSERT(p1 && p2);
size_t closestIndex = cvf::UNDEFINED_SIZE_T;
double closestDistance = cvf::UNDEFINED_DOUBLE;
for (size_t i = 1; i < m_wellPathPoints.size(); i++)
{
cvf::Vec3d p1 = m_wellPathPoints[i - 1];
cvf::Vec3d p2 = m_wellPathPoints[i - 0];
double candidateDistance = cvf::GeometryTools::linePointSquareDist(p1, p2, position);
if (candidateDistance < closestDistance)
{
closestDistance = candidateDistance;
closestIndex = i;
}
}
if (closestIndex != cvf::UNDEFINED_DOUBLE)
{
if (closestIndex > 0)
{
*p1 = m_wellPathPoints[closestIndex - 1];
*p2 = m_wellPathPoints[closestIndex - 0];
}
else
{
*p1 = m_wellPathPoints[closestIndex + 1];
*p2 = m_wellPathPoints[closestIndex + 0];
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RigWellPath::clippedPointSubset(double startMD, double endMD) const
{
std::vector<cvf::Vec3d> points;
if (m_measuredDepths.empty()) return points;
if (startMD > endMD) return points;
size_t i = 0;
// Skip points below startMD
while (i < m_measuredDepths.size() && m_measuredDepths[i] < startMD) ++i;
if (i == 0)
{
// If startMD is at or below the starting MD, use that point
points.push_back(m_wellPathPoints[0]);
}
else
{
double stepsize = (startMD - m_measuredDepths[i - 1]) / (m_measuredDepths[i] - m_measuredDepths[i - 1]);
points.push_back(m_wellPathPoints[i - 1] + stepsize * (m_wellPathPoints[i] - m_wellPathPoints[i - 1]));
}
while (i < m_measuredDepths.size() && m_measuredDepths[i] < endMD)
{
// Add all points between startMD and endMD
points.push_back(m_wellPathPoints[i]);
++i;
}
if (i < m_measuredDepths.size() && m_measuredDepths[i] > endMD)
{
double stepsize = (endMD - m_measuredDepths[i - 1]) / (m_measuredDepths[i] - m_measuredDepths[i - 1]);
points.push_back(m_wellPathPoints[i - 1] + stepsize * (m_wellPathPoints[i] - m_wellPathPoints[i - 1]));
}
return points;
}

View File

@@ -40,6 +40,10 @@ public:
void setDatumElevation(double value);
bool hasDatumElevation() const;
double datumElevation() const;
cvf::Vec3d interpolatedPointAlongWellPath(double measuredDepth) const;
double wellPathAzimuthAngle(const cvf::Vec3d& position) const;
void twoClosestPoints(const cvf::Vec3d& position, cvf::Vec3d* p1, cvf::Vec3d* p2) const;
std::vector<cvf::Vec3d> clippedPointSubset(double startMD, double endMD) const;
private:
bool m_hasDatumElevation;

View File

@@ -0,0 +1,212 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigWellPathIntersectionTools.h"
#include "RiaLogging.h"
#include "RigWellPath.h"
#include "RigMainGrid.h"
#include "RigEclipseCaseData.h"
#include "RigWellLogExtractionTools.h"
#include "RigCellGeometryTools.h"
#include "cvfGeometryTools.h"
#include "cvfMatrix3.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<WellPathCellIntersectionInfo> RigWellPathIntersectionTools::findCellsIntersectedByPath(const RigEclipseCaseData* caseData, const std::vector<cvf::Vec3d>& pathCoords)
{
std::vector<WellPathCellIntersectionInfo> intersectionInfo;
const RigMainGrid* grid = caseData->mainGrid();
if (pathCoords.size() < 2) return intersectionInfo;
std::vector<HexIntersectionInfo> intersections = getIntersectedCells(grid, pathCoords);
removeEnteringIntersections(&intersections);
if (intersections.empty()) return intersectionInfo;
cvf::Vec3d startPoint;
cvf::Vec3d endPoint;
size_t cellIndex;
cvf::Vec3d internalCellLengths;
auto intersection = intersections.cbegin();
//start cell
bool foundCell;
startPoint = pathCoords[0];
cellIndex = findCellFromCoords(grid, startPoint, &foundCell);
if (foundCell)
{
endPoint = intersection->m_intersectionPoint;
internalCellLengths = calculateLengthInCell(grid, cellIndex, startPoint, endPoint);
intersectionInfo.push_back(WellPathCellIntersectionInfo(cellIndex, startPoint, endPoint, internalCellLengths));
}
else
{
RiaLogging::debug("Path starts outside valid cell");
}
//center cells
startPoint = intersection->m_intersectionPoint;
cellIndex = intersection->m_hexIndex;
++intersection;
while (intersection != intersections.cend())
{
endPoint = intersection->m_intersectionPoint;
internalCellLengths = calculateLengthInCell(grid, cellIndex, startPoint, endPoint);
intersectionInfo.push_back(WellPathCellIntersectionInfo(cellIndex, startPoint, endPoint, internalCellLengths));
startPoint = endPoint;
cellIndex = intersection->m_hexIndex;
++intersection;
}
//end cell
endPoint = pathCoords[pathCoords.size() - 1];
internalCellLengths = calculateLengthInCell(grid, cellIndex, startPoint, endPoint);
intersectionInfo.push_back(WellPathCellIntersectionInfo(cellIndex, startPoint, endPoint, internalCellLengths));
return intersectionInfo;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<HexIntersectionInfo> RigWellPathIntersectionTools::getIntersectedCells(const RigMainGrid* grid, const std::vector<cvf::Vec3d>& coords)
{
const std::vector<cvf::Vec3d>& nodeCoords = grid->nodes();
std::vector<HexIntersectionInfo> intersections;
for (size_t i = 0; i < coords.size() - 1; ++i)
{
cvf::BoundingBox bb;
bb.add(coords[i]);
bb.add(coords[i + 1]);
std::vector<size_t> closeCells = findCloseCells(grid, bb);
std::array<cvf::Vec3d, 8> hexCorners;
for (size_t closeCell : closeCells)
{
const RigCell& cell = grid->globalCellArray()[closeCell];
if (cell.isInvalid()) continue;
grid->cellCornerVertices(closeCell, hexCorners.data());
RigHexIntersectionTools::lineHexCellIntersection(coords[i], coords[i + 1], hexCorners.data(), closeCell, &intersections);
}
}
return intersections;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3d RigWellPathIntersectionTools::calculateLengthInCell(const std::array<cvf::Vec3d, 8>& hexCorners, const cvf::Vec3d& startPoint, const cvf::Vec3d& endPoint)
{
cvf::Vec3d vec = endPoint - startPoint;
cvf::Vec3d iAxisDirection;
cvf::Vec3d jAxisDirection;
cvf::Vec3d kAxisDirection;
RigCellGeometryTools::findCellLocalXYZ(hexCorners, iAxisDirection, jAxisDirection, kAxisDirection);
cvf::Mat3d localCellCoordinateSystem(iAxisDirection.x(), jAxisDirection.x(), kAxisDirection.x(),
iAxisDirection.y(), jAxisDirection.y(), kAxisDirection.y(),
iAxisDirection.z(), jAxisDirection.z(), kAxisDirection.z());
return vec.getTransformedVector(localCellCoordinateSystem.getInverted());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3d RigWellPathIntersectionTools::calculateLengthInCell(const RigMainGrid* grid, size_t cellIndex, const cvf::Vec3d& startPoint, const cvf::Vec3d& endPoint)
{
std::array<cvf::Vec3d, 8> hexCorners;
grid->cellCornerVertices(cellIndex, hexCorners.data());
return calculateLengthInCell(hexCorners, startPoint, endPoint);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RigWellPathIntersectionTools::findCloseCells(const RigMainGrid* grid, const cvf::BoundingBox& bb)
{
std::vector<size_t> closeCells;
grid->findIntersectingCells(bb, &closeCells);
return closeCells;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigWellPathIntersectionTools::findCellFromCoords(const RigMainGrid* grid, const cvf::Vec3d& coords, bool* foundCell)
{
const std::vector<cvf::Vec3d>& nodeCoords = grid->nodes();
cvf::BoundingBox bb;
bb.add(coords);
std::vector<size_t> closeCells = findCloseCells(grid, bb);
std::array<cvf::Vec3d, 8> hexCorners;
for (size_t closeCell : closeCells)
{
const RigCell& cell = grid->globalCellArray()[closeCell];
if (cell.isInvalid()) continue;
grid->cellCornerVertices(closeCell, hexCorners.data());
if (RigHexIntersectionTools::isPointInCell(coords, hexCorners.data()))
{
*foundCell = true;
return closeCell;
}
}
*foundCell = false;
return 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigWellPathIntersectionTools::removeEnteringIntersections(std::vector<HexIntersectionInfo>* intersections)
{
for (auto it = intersections->begin(); it != intersections->end();)
{
if (it->m_isIntersectionEntering)
{
it = intersections->erase(it);
}
else
{
++it;
}
}
}

View File

@@ -0,0 +1,68 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigCell.h"
#include "RigHexIntersectionTools.h"
#include "cvfVector3.h"
#include <array>
class RigWellPath;
class RigMainGrid;
class RigEclipseCaseData;
//==================================================================================================
///
//==================================================================================================
struct WellPathCellIntersectionInfo {
WellPathCellIntersectionInfo(size_t cellIndex, cvf::Vec3d startPoint, cvf::Vec3d endPoint, cvf::Vec3d internalCellLengths)
: cellIndex(cellIndex),
startPoint(startPoint),
endPoint(endPoint),
internalCellLengths(internalCellLengths)
{}
size_t cellIndex;
cvf::Vec3d startPoint;
cvf::Vec3d endPoint;
cvf::Vec3d internalCellLengths; // intersectionLengthsInCellCS
};
//==================================================================================================
///
//==================================================================================================
class RigWellPathIntersectionTools
{
public:
static std::vector<WellPathCellIntersectionInfo> findCellsIntersectedByPath(const RigEclipseCaseData* caseData, const std::vector<cvf::Vec3d>& pathCoords);
static std::vector<HexIntersectionInfo> getIntersectedCells(const RigMainGrid* grid, const std::vector<cvf::Vec3d>& coords);
static cvf::Vec3d calculateLengthInCell(const std::array<cvf::Vec3d, 8>& hexCorners, const cvf::Vec3d& startPoint, const cvf::Vec3d& endPoint);
static cvf::Vec3d calculateLengthInCell(const RigMainGrid* grid, size_t cellIndex, const cvf::Vec3d& startPoint, const cvf::Vec3d& endPoint);
static std::vector<size_t> findCloseCells(const RigMainGrid* grid, const cvf::BoundingBox& bb);
static size_t findCellFromCoords(const RigMainGrid* caseData, const cvf::Vec3d& coords, bool* foundCell);
private:
static void removeEnteringIntersections(std::vector<HexIntersectionInfo>* intersections);
};