#3032 Completion Export Fracture Header : Refactoring

Rename to reservoirCellIndicesOpenForFlow
Include inactive cells in area calculation
Consider containment/truncation for header related calculations
Moved calculations from stim plan fracture to stim plan calculator
This commit is contained in:
Magne Sjaastad
2018-09-11 13:22:57 +02:00
parent ccd196b52c
commit d5b10546b8
15 changed files with 404 additions and 386 deletions

View File

@@ -21,6 +21,7 @@
#include "RicWellPathFractureReportItem.h" #include "RicWellPathFractureReportItem.h"
#include "RiaLogging.h" #include "RiaLogging.h"
#include "RiaWeightedAverageCalculator.h"
#include "RimEclipseCase.h" #include "RimEclipseCase.h"
#include "RimEclipseView.h" #include "RimEclipseView.h"
@@ -222,9 +223,9 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
////// //////
// Calculate Matrix To Fracture Trans // Calculate Matrix To Fracture Trans
RigEclipseToStimPlanCalculator eclToFractureCalc( RigEclipseToStimPlanCalculator eclToFractureCalc(
caseToApply, fracture->transformMatrix(), fracTemplate->skinFactor(), cDarcyInCorrectUnit, *fractureGrid); caseToApply, fracture->transformMatrix(), fracTemplate->skinFactor(), cDarcyInCorrectUnit, *fractureGrid, fracture);
eclToFractureCalc.appendDataToTransmissibilityCondenser(fracture, useFiniteConductivityInFracture, &transCondenser); eclToFractureCalc.appendDataToTransmissibilityCondenser(useFiniteConductivityInFracture, &transCondenser);
if (useFiniteConductivityInFracture) if (useFiniteConductivityInFracture)
{ {
@@ -233,13 +234,15 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
if (useFiniteConductivityInFracture) if (useFiniteConductivityInFracture)
{ {
calculateFractureToWellTransmissibilities(fracTemplate, fractureGrid, fracture, cDarcyInCorrectUnit, wellPathGeometry, transCondenser); calculateFractureToWellTransmissibilities(
fracTemplate, fractureGrid, fracture, cDarcyInCorrectUnit, wellPathGeometry, transCondenser);
} }
///// /////
// Insert total transmissibility from eclipse-cell to well for this fracture into the map // Insert total transmissibility from eclipse-cell to well for this fracture into the map
std::map<size_t, double> matrixToWellTrans = calculateMatrixToWellTransmissibilities(transCondenser); std::map<size_t, double> matrixToWellTrans = calculateMatrixToWellTransmissibilities(transCondenser);
std::vector<RigCompletionData> allCompletionsForOneFracture = generateCompdatValuesForFracture(matrixToWellTrans, wellPathName, caseToApply, fracture, fracTemplate); std::vector<RigCompletionData> allCompletionsForOneFracture =
generateCompdatValuesForFracture(matrixToWellTrans, wellPathName, caseToApply, fracture, fracTemplate);
if (fracTemplate->isNonDarcyFlowEnabled()) if (fracTemplate->isNonDarcyFlowEnabled())
{ {
@@ -248,19 +251,11 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
if (fractureDataReportItems) if (fractureDataReportItems)
{ {
QString fractureTemplateName = fracTemplate->name(); RicWellPathFractureReportItem reportItem(wellPathName, fracture->name(), fracTemplate->name());
RicWellPathFractureReportItem reportItem(wellPathName, fracture->name(), fractureTemplateName); reportItem.setUnitSystem(fracTemplate->fractureTemplateUnit());
auto cellAreas = eclToFractureCalc.eclipseCellAreas(); RicExportFractureCompletionsImpl::calculateAndSetReportItemData(
allCompletionsForOneFracture, eclToFractureCalc, reportItem);
double fcd = -1.0;
double area = sumUpCellAreas(cellAreas);
double transmissibility = sumUpTransmissibilities(allCompletionsForOneFracture);
reportItem.setData(transmissibility, allCompletionsForOneFracture.size(), fcd, area);
calculateAndSetLengthsAndConductivity(fracTemplate, area, reportItem);
calculateAndSetAreaWeightedTransmissibility(caseToApply, cellAreas, area, reportItem);
fractureDataReportItems->push_back(reportItem); fractureDataReportItems->push_back(reportItem);
} }
@@ -273,7 +268,8 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
{ {
#pragma omp critical(critical_section_outputStreamForIntermediateResultsText) #pragma omp critical(critical_section_outputStreamForIntermediateResultsText)
{ {
outputIntermediateResultsText(outputStreamForIntermediateResultsText, fracture, transCondenser, mainGrid, fractureGrid); outputIntermediateResultsText(
outputStreamForIntermediateResultsText, fracture, transCondenser, mainGrid, fractureGrid);
} }
} }
} }
@@ -288,7 +284,8 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool RicExportFractureCompletionsImpl::checkForStimPlanConductivity(const RimFractureTemplate* fracTemplate, const RimFracture* fracture) bool RicExportFractureCompletionsImpl::checkForStimPlanConductivity(const RimFractureTemplate* fracTemplate,
const RimFracture* fracture)
{ {
auto fracTemplateStimPlan = dynamic_cast<const RimStimPlanFractureTemplate*>(fracTemplate); auto fracTemplateStimPlan = dynamic_cast<const RimStimPlanFractureTemplate*>(fracTemplate);
if (fracTemplateStimPlan) if (fracTemplateStimPlan)
@@ -296,7 +293,7 @@ bool RicExportFractureCompletionsImpl::checkForStimPlanConductivity(const RimFra
if (!fracTemplateStimPlan->hasConductivity()) if (!fracTemplateStimPlan->hasConductivity())
{ {
RiaLogging::error("Trying to export completion data for stimPlan fracture without conductivity data for " + RiaLogging::error("Trying to export completion data for stimPlan fracture without conductivity data for " +
fracture->name()); fracture->name());
RiaLogging::error("No transmissibilities will be calculated for " + fracture->name()); RiaLogging::error("No transmissibilities will be calculated for " + fracture->name());
return false; return false;
} }
@@ -307,7 +304,9 @@ bool RicExportFractureCompletionsImpl::checkForStimPlanConductivity(const RimFra
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicExportFractureCompletionsImpl::calculateInternalFractureTransmissibilities(const RigFractureGrid* fractureGrid, double cDarcyInCorrectUnit, RigTransmissibilityCondenser &transCondenser) void RicExportFractureCompletionsImpl::calculateInternalFractureTransmissibilities(const RigFractureGrid* fractureGrid,
double cDarcyInCorrectUnit,
RigTransmissibilityCondenser& transCondenser)
{ {
for (size_t i = 0; i < fractureGrid->iCellCount(); i++) for (size_t i = 0; i < fractureGrid->iCellCount(); i++)
{ {
@@ -322,7 +321,7 @@ void RicExportFractureCompletionsImpl::calculateInternalFractureTransmissibiliti
if (i < fractureGrid->iCellCount() - 1) if (i < fractureGrid->iCellCount() - 1)
{ {
size_t fractureCellNeighbourXIndex = fractureGrid->getGlobalIndexFromIJ(i + 1, j); size_t fractureCellNeighbourXIndex = fractureGrid->getGlobalIndexFromIJ(i + 1, j);
const RigFractureCell& fractureCellNeighbourX = fractureGrid->cellFromIndex(fractureCellNeighbourXIndex); const RigFractureCell& fractureCellNeighbourX = fractureGrid->cellFromIndex(fractureCellNeighbourXIndex);
double horizontalTransToXneigbour = RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans( double horizontalTransToXneigbour = RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans(
fractureCell.getConductivityValue(), fractureCell.getConductivityValue(),
@@ -334,15 +333,15 @@ void RicExportFractureCompletionsImpl::calculateInternalFractureTransmissibiliti
cDarcyInCorrectUnit); cDarcyInCorrectUnit);
transCondenser.addNeighborTransmissibility( transCondenser.addNeighborTransmissibility(
{ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellIndex }, {false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellIndex},
{ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellNeighbourXIndex }, {false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellNeighbourXIndex},
horizontalTransToXneigbour); horizontalTransToXneigbour);
} }
if (j < fractureGrid->jCellCount() - 1) if (j < fractureGrid->jCellCount() - 1)
{ {
size_t fractureCellNeighbourZIndex = fractureGrid->getGlobalIndexFromIJ(i, j + 1); size_t fractureCellNeighbourZIndex = fractureGrid->getGlobalIndexFromIJ(i, j + 1);
const RigFractureCell& fractureCellNeighbourZ = fractureGrid->cellFromIndex(fractureCellNeighbourZIndex); const RigFractureCell& fractureCellNeighbourZ = fractureGrid->cellFromIndex(fractureCellNeighbourZIndex);
double verticalTransToZneigbour = RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans( double verticalTransToZneigbour = RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans(
fractureCell.getConductivityValue(), fractureCell.getConductivityValue(),
@@ -354,8 +353,8 @@ void RicExportFractureCompletionsImpl::calculateInternalFractureTransmissibiliti
cDarcyInCorrectUnit); cDarcyInCorrectUnit);
transCondenser.addNeighborTransmissibility( transCondenser.addNeighborTransmissibility(
{ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellIndex }, {false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellIndex},
{ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellNeighbourZIndex }, {false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellNeighbourZIndex},
verticalTransToZneigbour); verticalTransToZneigbour);
} }
} }
@@ -365,7 +364,12 @@ void RicExportFractureCompletionsImpl::calculateInternalFractureTransmissibiliti
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicExportFractureCompletionsImpl::calculateFractureToWellTransmissibilities(const RimFractureTemplate* fracTemplate, const RigFractureGrid* fractureGrid, const RimFracture* fracture, double cDarcyInCorrectUnit, const RigWellPath* wellPathGeometry, RigTransmissibilityCondenser &transCondenser) void RicExportFractureCompletionsImpl::calculateFractureToWellTransmissibilities(const RimFractureTemplate* fracTemplate,
const RigFractureGrid* fractureGrid,
const RimFracture* fracture,
double cDarcyInCorrectUnit,
const RigWellPath* wellPathGeometry,
RigTransmissibilityCondenser& transCondenser)
{ {
//// ////
// If fracture has orientation Azimuth or Transverse, assume only radial inflow // If fracture has orientation Azimuth or Transverse, assume only radial inflow
@@ -373,23 +377,21 @@ void RicExportFractureCompletionsImpl::calculateFractureToWellTransmissibilities
if (fracTemplate->orientationType() == RimFractureTemplate::AZIMUTH || if (fracTemplate->orientationType() == RimFractureTemplate::AZIMUTH ||
fracTemplate->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) fracTemplate->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH)
{ {
std::pair<size_t, size_t> wellCellIJ = fractureGrid->fractureCellAtWellCenter(); std::pair<size_t, size_t> wellCellIJ = fractureGrid->fractureCellAtWellCenter();
size_t wellCellIndex = fractureGrid->getGlobalIndexFromIJ(wellCellIJ.first, wellCellIJ.second); size_t wellCellIndex = fractureGrid->getGlobalIndexFromIJ(wellCellIJ.first, wellCellIJ.second);
const RigFractureCell& wellCell = fractureGrid->cellFromIndex(wellCellIndex); const RigFractureCell& wellCell = fractureGrid->cellFromIndex(wellCellIndex);
double radialTrans = double radialTrans = RigFractureTransmissibilityEquations::fractureCellToWellRadialTrans(wellCell.getConductivityValue(),
RigFractureTransmissibilityEquations::fractureCellToWellRadialTrans(wellCell.getConductivityValue(), wellCell.cellSizeX(),
wellCell.cellSizeX(), wellCell.cellSizeZ(),
wellCell.cellSizeZ(), fracture->wellRadius(),
fracture->wellRadius(), fracTemplate->skinFactor(),
fracTemplate->skinFactor(), cDarcyInCorrectUnit);
cDarcyInCorrectUnit);
transCondenser.addNeighborTransmissibility( transCondenser.addNeighborTransmissibility({true, RigTransmissibilityCondenser::CellAddress::WELL, 1},
{ true, RigTransmissibilityCondenser::CellAddress::WELL, 1 }, {false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, wellCellIndex},
{ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, wellCellIndex }, radialTrans);
radialTrans);
} }
else if (fracTemplate->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) else if (fracTemplate->orientationType() == RimFractureTemplate::ALONG_WELL_PATH)
{ {
@@ -411,30 +413,30 @@ void RicExportFractureCompletionsImpl::calculateFractureToWellTransmissibilities
double linearTrans = 0.0; double linearTrans = 0.0;
if (intersection.hlength > 0.0 || intersection.vlength > 0.0) if (intersection.hlength > 0.0 || intersection.vlength > 0.0)
{ {
linearTrans = RigFractureTransmissibilityEquations::fractureCellToWellLinearTrans( linearTrans =
fractureWellCell.getConductivityValue(), RigFractureTransmissibilityEquations::fractureCellToWellLinearTrans(fractureWellCell.getConductivityValue(),
fractureWellCell.cellSizeX(), fractureWellCell.cellSizeX(),
fractureWellCell.cellSizeZ(), fractureWellCell.cellSizeZ(),
intersection.vlength, intersection.vlength,
intersection.hlength, intersection.hlength,
fracture->perforationEfficiency(), fracture->perforationEfficiency(),
fracTemplate->skinFactor(), fracTemplate->skinFactor(),
cDarcyInCorrectUnit); cDarcyInCorrectUnit);
} }
transCondenser.addNeighborTransmissibility( transCondenser.addNeighborTransmissibility(
{ true, RigTransmissibilityCondenser::CellAddress::WELL, 1 }, {true, RigTransmissibilityCondenser::CellAddress::WELL, 1},
{ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fracWellCellIdx }, {false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fracWellCellIdx},
linearTrans); linearTrans);
} }
} }
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::map<size_t, double> RicExportFractureCompletionsImpl::calculateMatrixToWellTransmissibilities(RigTransmissibilityCondenser &transCondenser) std::map<size_t, double>
RicExportFractureCompletionsImpl::calculateMatrixToWellTransmissibilities(RigTransmissibilityCondenser& transCondenser)
{ {
std::map<size_t, double> matrixToWellTransmissibilities; std::map<size_t, double> matrixToWellTransmissibilities;
@@ -443,11 +445,10 @@ std::map<size_t, double> RicExportFractureCompletionsImpl::calculateMatrixToWell
{ {
if (externalCell.m_cellIndexSpace == RigTransmissibilityCondenser::CellAddress::ECLIPSE) if (externalCell.m_cellIndexSpace == RigTransmissibilityCondenser::CellAddress::ECLIPSE)
{ {
double trans = transCondenser.condensedTransmissibility( double trans = transCondenser.condensedTransmissibility(externalCell,
externalCell, { true, RigTransmissibilityCondenser::CellAddress::WELL, 1 }); {true, RigTransmissibilityCondenser::CellAddress::WELL, 1});
matrixToWellTransmissibilities.insert(std::make_pair(externalCell.m_globalCellIdx, trans)); matrixToWellTransmissibilities.insert(std::make_pair(externalCell.m_globalCellIdx, trans));
} }
} }
return matrixToWellTransmissibilities; return matrixToWellTransmissibilities;
@@ -456,16 +457,20 @@ std::map<size_t, double> RicExportFractureCompletionsImpl::calculateMatrixToWell
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdatValuesForFracture(const std::map<size_t, double>& matrixToWellTransmissibilites, const QString& wellPathName, const RimEclipseCase* caseToApply, const RimFracture* fracture, const RimFractureTemplate* fracTemplate) std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdatValuesForFracture(
const std::map<size_t, double>& matrixToWellTransmissibilites,
const QString& wellPathName,
const RimEclipseCase* caseToApply,
const RimFracture* fracture,
const RimFractureTemplate* fracTemplate)
{ {
std::vector<RigCompletionData> allCompletionsForOneFracture; std::vector<RigCompletionData> allCompletionsForOneFracture;
for (const auto& matrixToWellTransmissibility : matrixToWellTransmissibilites) for (const auto& matrixToWellTransmissibility : matrixToWellTransmissibilites)
{ {
size_t globalCellIndex = matrixToWellTransmissibility.first; size_t globalCellIndex = matrixToWellTransmissibility.first;
double trans = matrixToWellTransmissibility.second; double trans = matrixToWellTransmissibility.second;
RigCompletionData compDat(wellPathName, RigCompletionData compDat(
RigCompletionDataGridCell(globalCellIndex, caseToApply->mainGrid()), wellPathName, RigCompletionDataGridCell(globalCellIndex, caseToApply->mainGrid()), fracture->fractureMD());
fracture->fractureMD());
double diameter = 2.0 * fracture->wellRadius(); double diameter = 2.0 * fracture->wellRadius();
compDat.setFromFracture(trans, fracTemplate->skinFactor(), diameter); compDat.setFromFracture(trans, fracTemplate->skinFactor(), diameter);
@@ -478,10 +483,11 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicExportFractureCompletionsImpl::computeNonDarcyFlowParameters(const RimFracture* fracture, std::vector<RigCompletionData> allCompletionsForOneFracture) void RicExportFractureCompletionsImpl::computeNonDarcyFlowParameters(const RimFracture* fracture,
std::vector<RigCompletionData> allCompletionsForOneFracture)
{ {
double dFactorForFracture = fracture->nonDarcyProperties().dFactor; double dFactorForFracture = fracture->nonDarcyProperties().dFactor;
double khForFracture = fracture->nonDarcyProperties().conductivity; double khForFracture = fracture->nonDarcyProperties().conductivity;
double sumOfTransmissibilitiesInFracture = 0.0; double sumOfTransmissibilitiesInFracture = 0.0;
for (const auto& c : allCompletionsForOneFracture) for (const auto& c : allCompletionsForOneFracture)
@@ -505,21 +511,8 @@ void RicExportFractureCompletionsImpl::computeNonDarcyFlowParameters(const RimFr
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
double RicExportFractureCompletionsImpl::sumUpCellAreas(const std::map<size_t, double>& cellAreas) double
{ RicExportFractureCompletionsImpl::sumUpTransmissibilities(const std::vector<RigCompletionData>& allCompletionsForOneFracture)
double area = 0.0;
for (const auto& cellArea : cellAreas)
{
area += cellArea.second;
}
return area;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RicExportFractureCompletionsImpl::sumUpTransmissibilities(const std::vector<RigCompletionData>& allCompletionsForOneFracture)
{ {
double transmissibility = 0.0; double transmissibility = 0.0;
for (const auto& c : allCompletionsForOneFracture) for (const auto& c : allCompletionsForOneFracture)
@@ -532,98 +525,51 @@ double RicExportFractureCompletionsImpl::sumUpTransmissibilities(const std::vect
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicExportFractureCompletionsImpl::calculateAndSetLengthsAndConductivity(const RimFractureTemplate* fracTemplate, void RicExportFractureCompletionsImpl::calculateAndSetReportItemData(
double area, const std::vector<RigCompletionData>& allCompletionsForOneFracture,
RicWellPathFractureReportItem& reportItem) const RigEclipseToStimPlanCalculator& eclToFractureCalc,
RicWellPathFractureReportItem& reportItem)
{ {
double conductivity = 0.0; double aggregatedTransmissibility = sumUpTransmissibilities(allCompletionsForOneFracture);
double width = 0.0;
double height = 0.0;
double halfLength = 0.0;
RiaEclipseUnitTools::UnitSystem unitSystem = RiaEclipseUnitTools::UNITS_METRIC;
double areaWeightedMatrixTransmissibility = eclToFractureCalc.areaWeightedMatrixTransmissibility();
reportItem.setAreaWeightedTransmissibility(areaWeightedMatrixTransmissibility);
double totalAreaOpenForFlow = eclToFractureCalc.totalEclipseAreaOpenForFlow();
double areaWeightedConductivity = eclToFractureCalc.areaWeightedConductivity();
double fcd = 0.0;
if (areaWeightedMatrixTransmissibility > 0.0)
{ {
auto* ellipseTemplate = dynamic_cast<const RimEllipseFractureTemplate*>(fracTemplate); fcd = areaWeightedConductivity / areaWeightedMatrixTransmissibility;
if (ellipseTemplate) }
{
unitSystem = ellipseTemplate->fractureTemplateUnit(); reportItem.setData(aggregatedTransmissibility, allCompletionsForOneFracture.size(), fcd, totalAreaOpenForFlow);
conductivity = ellipseTemplate->conductivity();
width = ellipseTemplate->width(); reportItem.setWidthAndConductivity(eclToFractureCalc.areaWeightedWidth(), areaWeightedConductivity);
height = ellipseTemplate->height();
halfLength = ellipseTemplate->halfLength(); if (totalAreaOpenForFlow > 0.0)
} {
double height = eclToFractureCalc.longestYSectionOpenForFlow();
auto* stimplanTemplate = dynamic_cast<const RimStimPlanFractureTemplate*>(fracTemplate); double halfLength = 0.0;
if (stimplanTemplate) if (height > 0.0)
{ {
unitSystem = stimplanTemplate->fractureTemplateUnit(); double length = totalAreaOpenForFlow / height;
conductivity = stimplanTemplate->areaWeightedConductivity(); halfLength = length / 2.0;
width = stimplanTemplate->areaWeightedWidth(); }
height = stimplanTemplate->longestYRange(); reportItem.setHeightAndHalfLength(height, halfLength);
double xLength = 0.0;
if (height > 1e-9)
{
xLength = area / height;
}
// Compute half length defined as (total area / (H/2) )
halfLength = xLength / 2.0;
}
} }
reportItem.setUnitSystem(unitSystem);
reportItem.setWidthAndConductivity(width, conductivity);
reportItem.setHeightAndHalfLength(height, halfLength);
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicExportFractureCompletionsImpl::calculateAndSetAreaWeightedTransmissibility(const RimEclipseCase* caseToApply, void RicExportFractureCompletionsImpl::outputIntermediateResultsText(QTextStream* outputStreamForIntermediateResultsText,
std::map<size_t, double> cellAreas, const RimFracture* fracture,
double area, RigTransmissibilityCondenser& transCondenser,
RicWellPathFractureReportItem& reportItem) const RigMainGrid* mainGrid,
{ const RigFractureGrid* fractureGrid)
double areaWeightedEclipseTransmissibility = 0.0;
if (caseToApply && caseToApply->eclipseCaseData())
{
cvf::ref<RigResultAccessor> tranxAccessObject = RigResultAccessorFactory::createFromUiResultName(
caseToApply->eclipseCaseData(), 0, RiaDefines::MATRIX_MODEL, 0, "TRANX");
cvf::ref<RigResultAccessor> tranyAccessObject = RigResultAccessorFactory::createFromUiResultName(
caseToApply->eclipseCaseData(), 0, RiaDefines::MATRIX_MODEL, 0, "TRANY");
cvf::ref<RigResultAccessor> tranzAccessObject = RigResultAccessorFactory::createFromUiResultName(
caseToApply->eclipseCaseData(), 0, RiaDefines::MATRIX_MODEL, 0, "TRANZ");
if (tranxAccessObject.notNull() && tranyAccessObject.notNull() && tranzAccessObject.notNull())
{
for (const auto& cellArea : cellAreas)
{
double tranx = tranxAccessObject->cellScalarGlobIdx(cellArea.first);
double trany = tranyAccessObject->cellScalarGlobIdx(cellArea.first);
double tranz = tranzAccessObject->cellScalarGlobIdx(cellArea.first);
double transmissibilityForCell = RigTransmissibilityEquations::totalConnectionFactor(tranx, trany, tranz);
areaWeightedEclipseTransmissibility += transmissibilityForCell * cellArea.second / area;
}
}
}
reportItem.setAreaWeightedTransmissibility(areaWeightedEclipseTransmissibility);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicExportFractureCompletionsImpl::outputIntermediateResultsText(QTextStream* outputStreamForIntermediateResultsText,
const RimFracture* fracture,
RigTransmissibilityCondenser& transCondenser,
const RigMainGrid* mainGrid,
const RigFractureGrid* fractureGrid)
{ {
(*outputStreamForIntermediateResultsText) (*outputStreamForIntermediateResultsText)
<< "\n" << "\n"

View File

@@ -27,6 +27,7 @@ class RigFractureGrid;
class RicWellPathFractureReportItem; class RicWellPathFractureReportItem;
class RigWellPath; class RigWellPath;
class RigTransmissibilityCondenser; class RigTransmissibilityCondenser;
class RigEclipseToStimPlanCalculator;
class RimEclipseCase; class RimEclipseCase;
class RimFracture; class RimFracture;
@@ -79,11 +80,9 @@ private:
static void computeNonDarcyFlowParameters(const RimFracture* fracture, std::vector<RigCompletionData> allCompletionsForOneFracture); static void computeNonDarcyFlowParameters(const RimFracture* fracture, std::vector<RigCompletionData> allCompletionsForOneFracture);
static double sumUpCellAreas(const std::map<size_t, double>& cellAreas);
static double sumUpTransmissibilities(const std::vector<RigCompletionData>& allCompletionsForOneFracture); static double sumUpTransmissibilities(const std::vector<RigCompletionData>& allCompletionsForOneFracture);
static void calculateAndSetLengthsAndConductivity(const RimFractureTemplate* fracTemplate, double area, RicWellPathFractureReportItem &reportItem); static void calculateAndSetReportItemData(const std::vector<RigCompletionData>& allCompletionsForOneFracture, const RigEclipseToStimPlanCalculator& calculator, RicWellPathFractureReportItem& reportItem);
static void calculateAndSetAreaWeightedTransmissibility(const RimEclipseCase* caseToApply, std::map<size_t, double> cellAreas, double area, RicWellPathFractureReportItem &reportItem);
static void outputIntermediateResultsText(QTextStream* outputStreamForIntermediateResultsText, const RimFracture* fracture, RigTransmissibilityCondenser &transCondenser, const RigMainGrid* mainGrid, const RigFractureGrid* fractureGrid); static void outputIntermediateResultsText(QTextStream* outputStreamForIntermediateResultsText, const RimFracture* fracture, RigTransmissibilityCondenser &transCondenser, const RigMainGrid* mainGrid, const RigFractureGrid* fractureGrid);
}; };

View File

@@ -662,11 +662,11 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createContainmentMaskPart(const RimE
RimEclipseCase* eclipseCase = nullptr; RimEclipseCase* eclipseCase = nullptr;
activeView.firstAncestorOrThisOfType(eclipseCase); activeView.firstAncestorOrThisOfType(eclipseCase);
auto containedFractureCells = RimFractureContainmentTools::fracturedCellsTruncatedByFaults(eclipseCase, m_rimFracture); auto reservoirCellIndicesOpenForFlow = RimFractureContainmentTools::reservoirCellIndicesOpenForFlow(eclipseCase, m_rimFracture);
for (size_t resCellIdx : cellCandidates) for (size_t resCellIdx : cellCandidates)
{ {
if (!m_rimFracture->isEclipseCellWithinContainment(activeView.mainGrid(), containedFractureCells, resCellIdx)) if (!m_rimFracture->isEclipseCellOpenForFlow(activeView.mainGrid(), reservoirCellIndicesOpenForFlow, resCellIdx))
{ {
// Calculate Eclipse cell intersection with fracture plane // Calculate Eclipse cell intersection with fracture plane

View File

@@ -646,17 +646,15 @@ void RimFracture::setFractureUnit(RiaEclipseUnitTools::UnitSystem unitSystem)
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool RimFracture::isEclipseCellWithinContainment(const RigMainGrid* mainGrid, bool RimFracture::isEclipseCellOpenForFlow(const RigMainGrid* mainGrid,
const std::set<size_t>& containmentCells, const std::set<size_t>& reservoirCellIndicesOpenForFlow,
size_t globalCellIndex) const size_t globalCellIndex) const
{ {
CVF_ASSERT(fractureTemplate()); CVF_ASSERT(fractureTemplate());
if (!fractureTemplate()->fractureContainment()->isEnabled()) return true; if (!fractureTemplate()->fractureContainment()->isEnabled()) return true;
size_t anchorEclipseCell = mainGrid->findReservoirCellIndexFromPoint(m_anchorPosition); return fractureTemplate()->fractureContainment()->isEclipseCellOpenForFlow(
mainGrid, globalCellIndex, reservoirCellIndicesOpenForFlow);
return fractureTemplate()->fractureContainment()->isEclipseCellWithinContainment(
mainGrid, anchorEclipseCell, globalCellIndex, containmentCells);
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@@ -90,9 +90,9 @@ public:
RiaEclipseUnitTools::UnitSystem fractureUnit() const; RiaEclipseUnitTools::UnitSystem fractureUnit() const;
void setFractureUnit(RiaEclipseUnitTools::UnitSystem unitSystem); void setFractureUnit(RiaEclipseUnitTools::UnitSystem unitSystem);
bool isEclipseCellWithinContainment(const RigMainGrid* mainGrid, bool isEclipseCellOpenForFlow(const RigMainGrid* mainGrid,
const std::set<size_t>& containmentCells, const std::set<size_t>& reservoirCellIndicesOpenForFlow,
size_t globalCellIndex) const; size_t globalCellIndex) const;
cvf::Mat4d transformMatrix() const; cvf::Mat4d transformMatrix() const;
double dip() const; double dip() const;

View File

@@ -69,10 +69,9 @@ bool RimFractureContainment::isEnabled() const
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool RimFractureContainment::isEclipseCellWithinContainment(const RigMainGrid* mainGrid, bool RimFractureContainment::isEclipseCellOpenForFlow(const RigMainGrid* mainGrid,
size_t anchorEclipseCell, size_t globalCellIndex,
size_t globalCellIndex, const std::set<size_t>& reservoirCellIndicesOpenForFlow) const
const std::set<size_t>& containmentCells) const
{ {
if (!isEnabled()) return true; if (!isEnabled()) return true;
@@ -82,7 +81,7 @@ bool RimFractureContainment::isEclipseCellWithinContainment(const RigMainGrid*
if (globalCellIndex >= mainGrid->globalCellArray().size()) return false; if (globalCellIndex >= mainGrid->globalCellArray().size()) return false;
auto cell = mainGrid->globalCellArray()[globalCellIndex]; auto cell = mainGrid->globalCellArray()[globalCellIndex];
auto mainGridCellIndex = cell.mainGridCellIndex(); auto mainGridCellIndex = cell.mainGridCellIndex();
size_t i, j, k; size_t i, j, k;
@@ -101,7 +100,7 @@ bool RimFractureContainment::isEclipseCellWithinContainment(const RigMainGrid*
if (m_truncateAtFaults()) if (m_truncateAtFaults())
{ {
if (containmentCells.count(globalCellIndex) > 0) if (reservoirCellIndicesOpenForFlow.count(globalCellIndex) > 0)
{ {
return true; return true;
} }
@@ -123,7 +122,7 @@ void RimFractureContainment::setTopKLayer(int topKLayer)
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
int RimFractureContainment::topKLayer() const int RimFractureContainment::topKLayer() const
{ {
@@ -139,7 +138,7 @@ void RimFractureContainment::setBaseKLayer(int baseKLayer)
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
int RimFractureContainment::baseKLayer() const int RimFractureContainment::baseKLayer() const
{ {

View File

@@ -1,31 +1,31 @@
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2017 - Statoil ASA // Copyright (C) 2017 - Statoil ASA
// //
// ResInsight is free software: you can redistribute it and/or modify // ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or // WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. // FITNESS FOR A PARTICULAR PURPOSE.
// //
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> // See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details. // for more details.
// //
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
#pragma once #pragma once
#include "cafPdmObject.h"
#include "cafPdmField.h" #include "cafPdmField.h"
#include "cafPdmObject.h"
class RigMainGrid; class RigMainGrid;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
class RimFractureContainment : public caf::PdmObject class RimFractureContainment : public caf::PdmObject
{ {
CAF_PDM_HEADER_INIT; CAF_PDM_HEADER_INIT;
@@ -34,25 +34,27 @@ public:
~RimFractureContainment(); ~RimFractureContainment();
bool isEnabled() const; bool isEnabled() const;
bool isEclipseCellWithinContainment(const RigMainGrid* mainGrid, size_t anchorEclipseCell, size_t globalCellIndex, const std::set<size_t>& containmentCells) const; bool isEclipseCellOpenForFlow(const RigMainGrid* mainGrid,
size_t globalCellIndex,
const std::set<size_t>& reservoirCellIndicesOpenForFlow) const;
void setTopKLayer(int topKLayer); void setTopKLayer(int topKLayer);
int topKLayer() const; int topKLayer() const;
void setBaseKLayer(int baseKLayer); void setBaseKLayer(int baseKLayer);
int baseKLayer() const; int baseKLayer() const;
double minimumFaultThrow() const; // Negative value means do not test for fault throw double minimumFaultThrow() const; // Negative value means do not test for fault throw
private: private:
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
private: private:
caf::PdmField<bool> m_useContainment; caf::PdmField<bool> m_useContainment;
caf::PdmField<int> m_topKLayer; caf::PdmField<int> m_topKLayer;
caf::PdmField<int> m_baseKLayer; caf::PdmField<int> m_baseKLayer;
caf::PdmField<bool> m_truncateAtFaults; caf::PdmField<bool> m_truncateAtFaults;
caf::PdmField<float> m_minimumFaultThrow; caf::PdmField<float> m_minimumFaultThrow;
}; };

View File

@@ -201,10 +201,10 @@ void RimFractureContainmentTools::appendNeighborCells(const std::set<size_t>& al
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::set<size_t> RimFractureContainmentTools::fracturedCellsTruncatedByFaults(const RimEclipseCase* eclipseCase, std::set<size_t> RimFractureContainmentTools::reservoirCellIndicesOpenForFlow(const RimEclipseCase* eclipseCase,
const RimFracture* fracture) const RimFracture* fracture)
{ {
std::set<size_t> fracturedCellsContainedByFaults; std::set<size_t> cellsOpenForFlow;
if (eclipseCase && fracture) if (eclipseCase && fracture)
{ {
@@ -230,12 +230,12 @@ std::set<size_t> RimFractureContainmentTools::fracturedCellsTruncatedByFaults(co
appendNeighborCells(cellsIntersectingFracturePlane, appendNeighborCells(cellsIntersectingFracturePlane,
mainGrid, mainGrid,
anchorCellGlobalIndex, anchorCellGlobalIndex,
fracturedCellsContainedByFaults, cellsOpenForFlow,
maximumFaultThrow); maximumFaultThrow);
} }
else else
{ {
fracturedCellsContainedByFaults = cellsIntersectingFracturePlane; cellsOpenForFlow = cellsIntersectingFracturePlane;
} }
} }
@@ -250,7 +250,7 @@ std::set<size_t> RimFractureContainmentTools::fracturedCellsTruncatedByFaults(co
} }
} }
return fracturedCellsContainedByFaults; return cellsOpenForFlow;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@@ -30,7 +30,7 @@ class RimEclipseCase;
class RimFractureContainmentTools class RimFractureContainmentTools
{ {
public: public:
static std::set<size_t> fracturedCellsTruncatedByFaults(const RimEclipseCase* eclipseCase, const RimFracture* fracture); static std::set<size_t> reservoirCellIndicesOpenForFlow(const RimEclipseCase* eclipseCase, const RimFracture* fracture);
private: private:
static std::set<size_t> getCellsIntersectingFracturePlane(const RigMainGrid* mainGrid, const RimFracture* fracture); static std::set<size_t> getCellsIntersectingFracturePlane(const RigMainGrid* mainGrid, const RimFracture* fracture);

View File

@@ -84,10 +84,6 @@ RimStimPlanFractureTemplate::RimStimPlanFractureTemplate()
m_fractureGrid = new RigFractureGrid(); m_fractureGrid = new RigFractureGrid();
m_readError = false; m_readError = false;
m_areaWeightedConductivity = 0.0;
m_areaWeightedWidth = 0.0;
m_longestYRangeAboveConductivityThreshold = 0.0;
// clang-format on // clang-format on
} }
@@ -824,25 +820,18 @@ double RimStimPlanFractureTemplate::resultValueAtIJ(const QString& uiResultName,
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
double RimStimPlanFractureTemplate::areaWeightedWidth() const std::vector<double> RimStimPlanFractureTemplate::widthResultValues() const
{ {
return m_areaWeightedWidth; std::vector<double> resultValues;
}
//-------------------------------------------------------------------------------------------------- auto nameUnit = widthParameterNameAndUnit();
/// if (!nameUnit.first.isEmpty())
//-------------------------------------------------------------------------------------------------- {
double RimStimPlanFractureTemplate::areaWeightedConductivity() const resultValues =
{ fractureGridResultsForUnitSystem(nameUnit.first, nameUnit.second, m_activeTimeStepIndex, fractureTemplateUnit());
return m_areaWeightedConductivity; }
}
//-------------------------------------------------------------------------------------------------- return resultValues;
///
//--------------------------------------------------------------------------------------------------
double RimStimPlanFractureTemplate::longestYRange() const
{
return m_longestYRangeAboveConductivityThreshold;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -875,80 +864,12 @@ const RigFractureGrid* RimStimPlanFractureTemplate::fractureGrid() const
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate::updateFractureGrid() void RimStimPlanFractureTemplate::updateFractureGrid()
{ {
m_fractureGrid = nullptr; m_fractureGrid = nullptr;
m_areaWeightedConductivity = 0.0;
m_areaWeightedWidth = 0.0;
m_longestYRangeAboveConductivityThreshold = 0.0;
if (m_stimPlanFractureDefinitionData.notNull()) if (m_stimPlanFractureDefinitionData.notNull())
{ {
m_fractureGrid = m_stimPlanFractureDefinitionData->createFractureGrid( m_fractureGrid = m_stimPlanFractureDefinitionData->createFractureGrid(
m_conductivityResultNameOnFile, m_activeTimeStepIndex, m_wellPathDepthAtFracture, m_fractureTemplateUnit()); m_conductivityResultNameOnFile, m_activeTimeStepIndex, m_wellPathDepthAtFracture, m_fractureTemplateUnit());
if (m_fractureGrid.notNull())
{
std::vector<double> areaPerCell;
double totalArea = 0.0;
for (const auto& c : m_fractureGrid->fractureCells())
{
double cellArea = c.cellSizeX() * c.cellSizeZ();
areaPerCell.push_back(cellArea);
totalArea += cellArea;
}
for (size_t i = 0; i < areaPerCell.size(); i++)
{
const auto& c = m_fractureGrid->fractureCells()[i];
double perCellValue = c.getConductivityValue() * areaPerCell[i] / totalArea;
m_areaWeightedConductivity += perCellValue;
}
auto nameUnit = widthParameterNameAndUnit();
if (!nameUnit.first.isEmpty())
{
auto resultValues = fractureGridResultsForUnitSystem(
nameUnit.first, nameUnit.second, m_activeTimeStepIndex, fractureTemplateUnit());
for (size_t i = 0; i < areaPerCell.size(); i++)
{
double perCellValue = resultValues[i] * areaPerCell[i] / totalArea;
m_areaWeightedWidth += perCellValue;
}
}
// Compute longest y-range with continuous non-zero conductivity
{
double longestYRange = 0.0;
for (size_t i = 0; i < m_fractureGrid->iCellCount(); i++)
{
double currentYRange = 0.0;
for (size_t j = 0; j < m_fractureGrid->jCellCount(); j++)
{
size_t globalIndex = m_fractureGrid->getGlobalIndexFromIJ(i, j);
const auto& cell = m_fractureGrid->cellFromIndex(globalIndex);
if (cell.hasNonZeroConductivity())
{
currentYRange += cell.cellSizeZ();
}
else
{
longestYRange = std::max(longestYRange, currentYRange);
currentYRange = 0.0;
}
}
longestYRange = std::max(longestYRange, currentYRange);
}
m_longestYRangeAboveConductivityThreshold = longestYRange;
}
}
} }
} }

View File

@@ -79,9 +79,7 @@ public:
bool hasConductivity() const; bool hasConductivity() const;
double resultValueAtIJ(const QString& uiResultName, const QString& unitName, size_t timeStepIndex, size_t i, size_t j); double resultValueAtIJ(const QString& uiResultName, const QString& unitName, size_t timeStepIndex, size_t i, size_t j);
double areaWeightedWidth() const; std::vector<double> widthResultValues() const;
double areaWeightedConductivity() const;
double longestYRange() const;
void appendDataToResultStatistics(const QString& uiResultName, void appendDataToResultStatistics(const QString& uiResultName,
const QString& unit, const QString& unit,
@@ -128,9 +126,5 @@ private:
cvf::ref<RigFractureGrid> m_fractureGrid; cvf::ref<RigFractureGrid> m_fractureGrid;
bool m_readError; bool m_readError;
double m_areaWeightedConductivity;
double m_areaWeightedWidth;
double m_longestYRangeAboveConductivityThreshold;
caf::PdmField<bool> m_showStimPlanMesh_OBSOLETE; caf::PdmField<bool> m_showStimPlanMesh_OBSOLETE;
}; };

View File

@@ -32,9 +32,12 @@
#include "RigResultAccessorFactory.h" #include "RigResultAccessorFactory.h"
#include "RigTransmissibilityCondenser.h" #include "RigTransmissibilityCondenser.h"
#include "RiaWeightedAverageCalculator.h"
#include "RimEclipseCase.h" #include "RimEclipseCase.h"
#include "RimEllipseFractureTemplate.h"
#include "RimFracture.h" #include "RimFracture.h"
#include "RimFractureContainmentTools.h" #include "RimFractureContainmentTools.h"
#include "RimStimPlanFractureTemplate.h"
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
@@ -43,13 +46,16 @@ RigEclipseToStimPlanCalculator::RigEclipseToStimPlanCalculator(const RimEclipseC
cvf::Mat4d fractureTransform, cvf::Mat4d fractureTransform,
double skinFactor, double skinFactor,
double cDarcy, double cDarcy,
const RigFractureGrid& fractureGrid) const RigFractureGrid& fractureGrid,
const RimFracture* fracture)
: m_case(caseToApply) : m_case(caseToApply)
, m_fractureTransform(fractureTransform) , m_fractureTransform(fractureTransform)
, m_fractureSkinFactor(skinFactor) , m_fractureSkinFactor(skinFactor)
, m_cDarcy(cDarcy) , m_cDarcy(cDarcy)
, m_fractureGrid(fractureGrid) , m_fractureGrid(fractureGrid)
, m_fracture(fracture)
{ {
computeValues(); computeValues();
} }
@@ -58,19 +64,22 @@ RigEclipseToStimPlanCalculator::RigEclipseToStimPlanCalculator(const RimEclipseC
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RigEclipseToStimPlanCalculator::computeValues() void RigEclipseToStimPlanCalculator::computeValues()
{ {
for (const RigFractureCell& fractureCell : m_fractureGrid.fractureCells()) auto reservoirCellIndicesOpenForFlow = RimFractureContainmentTools::reservoirCellIndicesOpenForFlow(m_case, m_fracture);
for (size_t i = 0; i < m_fractureGrid.fractureCells().size(); i++)
{ {
const RigFractureCell& fractureCell = m_fractureGrid.fractureCells()[i];
if (!fractureCell.hasNonZeroConductivity()) continue; if (!fractureCell.hasNonZeroConductivity()) continue;
RigEclipseToStimPlanCellTransmissibilityCalculator eclToFractureTransCalc( RigEclipseToStimPlanCellTransmissibilityCalculator eclToFractureTransCalc(
m_case, m_fractureTransform, m_fractureSkinFactor, m_cDarcy, fractureCell); m_case, m_fractureTransform, m_fractureSkinFactor, m_cDarcy, fractureCell, reservoirCellIndicesOpenForFlow);
const std::vector<size_t>& fractureCellContributingEclipseCells = const std::vector<size_t>& fractureCellContributingEclipseCells =
eclToFractureTransCalc.globalIndiciesToContributingEclipseCells(); eclToFractureTransCalc.globalIndiciesToContributingEclipseCells();
if (!fractureCellContributingEclipseCells.empty()) if (!fractureCellContributingEclipseCells.empty())
{ {
m_singleFractureCellCalculators.emplace_back(eclToFractureTransCalc); m_singleFractureCellCalculators.emplace(i, eclToFractureTransCalc);
} }
} }
} }
@@ -80,62 +89,159 @@ using CellIdxSpace = RigTransmissibilityCondenser::CellAddress;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RigEclipseToStimPlanCalculator::appendDataToTransmissibilityCondenser(const RimFracture* fracture, void RigEclipseToStimPlanCalculator::appendDataToTransmissibilityCondenser(bool useFiniteConductivityInFracture,
bool useFiniteConductivityInFracture,
RigTransmissibilityCondenser* condenser) const RigTransmissibilityCondenser* condenser) const
{ {
for (const auto& eclToFractureTransCalc : m_singleFractureCellCalculators) for (const auto& eclToFractureTransCalc : m_singleFractureCellCalculators)
{ {
const std::vector<size_t>& fractureCellContributingEclipseCells = const std::vector<size_t>& fractureCellContributingEclipseCells =
eclToFractureTransCalc.globalIndiciesToContributingEclipseCells(); eclToFractureTransCalc.second.globalIndiciesToContributingEclipseCells();
const std::vector<double>& fractureCellContributingEclipseCellTransmissibilities = const std::vector<double>& fractureCellContributingEclipseCellTransmissibilities =
eclToFractureTransCalc.contributingEclipseCellTransmissibilities(); eclToFractureTransCalc.second.contributingEclipseCellTransmissibilities();
const auto& fractureCell = eclToFractureTransCalc.fractureCell(); size_t stimPlanCellIndex = eclToFractureTransCalc.first;
size_t stimPlanCellIndex = m_fractureGrid.getGlobalIndexFromIJ(fractureCell.getI(), fractureCell.getJ());
auto truncatedFractureCellIndices = RimFractureContainmentTools::fracturedCellsTruncatedByFaults(m_case, fracture);
for (size_t i = 0; i < fractureCellContributingEclipseCells.size(); i++) for (size_t i = 0; i < fractureCellContributingEclipseCells.size(); i++)
{ {
if (fracture->isEclipseCellWithinContainment( if (useFiniteConductivityInFracture)
m_case->eclipseCaseData()->mainGrid(), truncatedFractureCellIndices, fractureCellContributingEclipseCells[i]))
{ {
if (useFiniteConductivityInFracture) condenser->addNeighborTransmissibility({true, CellIdxSpace::ECLIPSE, fractureCellContributingEclipseCells[i]},
{ {false, CellIdxSpace::STIMPLAN, stimPlanCellIndex},
condenser->addNeighborTransmissibility({true, CellIdxSpace::ECLIPSE, fractureCellContributingEclipseCells[i]}, fractureCellContributingEclipseCellTransmissibilities[i]);
{false, CellIdxSpace::STIMPLAN, stimPlanCellIndex}, }
fractureCellContributingEclipseCellTransmissibilities[i]); else
} {
else condenser->addNeighborTransmissibility({true, CellIdxSpace::ECLIPSE, fractureCellContributingEclipseCells[i]},
{ {true, CellIdxSpace::WELL, 1},
condenser->addNeighborTransmissibility({true, CellIdxSpace::ECLIPSE, fractureCellContributingEclipseCells[i]}, fractureCellContributingEclipseCellTransmissibilities[i]);
{true, CellIdxSpace::WELL, 1},
fractureCellContributingEclipseCellTransmissibilities[i]);
}
} }
} }
} }
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::map<size_t, double> RigEclipseToStimPlanCalculator::eclipseCellAreas() const double RigEclipseToStimPlanCalculator::totalEclipseAreaOpenForFlow() const
{ {
std::map<size_t, double> areaForEclipseReservoirCells; double area = 0.0;
for (const auto& singleCellCalc : m_singleFractureCellCalculators) for (const auto& singleCellCalc : m_singleFractureCellCalculators)
{ {
const auto& cellIndices = singleCellCalc.globalIndiciesToContributingEclipseCells(); const auto& cellAreas = singleCellCalc.second.contributingEclipseCellAreas();
const auto& cellAreas = singleCellCalc.contributingEclipseCellAreas();
for (size_t i = 0; i < cellIndices.size(); i++) for (const auto& cellArea : cellAreas)
{ {
areaForEclipseReservoirCells[cellIndices[i]] += cellAreas[i]; area += cellArea;
} }
} }
return areaForEclipseReservoirCells; return area;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigEclipseToStimPlanCalculator::areaWeightedMatrixTransmissibility() const
{
RiaWeightedAverageCalculator<double> calc;
for (const auto& singleCellCalc : m_singleFractureCellCalculators)
{
const RigEclipseToStimPlanCellTransmissibilityCalculator& calulator = singleCellCalc.second;
calc.addValueAndWeight(calulator.aggregatedMatrixTransmissibility(), calulator.areaOpenForFlow());
}
return calc.weightedAverage();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigEclipseToStimPlanCalculator::areaWeightedWidth() const
{
double width = 0.0;
auto ellipseFractureTemplate = dynamic_cast<const RimEllipseFractureTemplate*>(m_fracture->fractureTemplate());
if (ellipseFractureTemplate)
{
width = ellipseFractureTemplate->width();
}
auto stimPlanFractureTemplate = dynamic_cast<const RimStimPlanFractureTemplate*>(m_fracture->fractureTemplate());
if (stimPlanFractureTemplate)
{
RiaWeightedAverageCalculator<double> calc;
auto widthValues = stimPlanFractureTemplate->widthResultValues();
for (const auto& singleCellCalc : m_singleFractureCellCalculators)
{
double cellArea = singleCellCalc.second.areaOpenForFlow();
size_t globalStimPlanCellIndex = singleCellCalc.first;
double widthValue = widthValues[globalStimPlanCellIndex];
calc.addValueAndWeight(widthValue, cellArea);
}
width = calc.weightedAverage();
}
return width;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigEclipseToStimPlanCalculator::areaWeightedConductivity() const
{
RiaWeightedAverageCalculator<double> calc;
for (const auto& singleCellCalc : m_singleFractureCellCalculators)
{
double cellArea = singleCellCalc.second.areaOpenForFlow();
calc.addValueAndWeight(singleCellCalc.second.fractureCell().getConductivityValue(), cellArea);
}
return calc.weightedAverage();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigEclipseToStimPlanCalculator::longestYSectionOpenForFlow() const
{
// For each I, find the longest aggregated distance along J with continuous fracture cells with conductivity above zero
// connected to Eclipse cells open for flow
double longestRange = 0.0;
for (size_t i = 0; i < m_fractureGrid.iCellCount(); i++)
{
double currentAggregatedDistanceY = 0.0;
for (size_t j = 0; j < m_fractureGrid.jCellCount(); j++)
{
size_t globalStimPlanCellIndex = m_fractureGrid.getGlobalIndexFromIJ(i, j);
auto calculatorForCell = m_singleFractureCellCalculators.find(globalStimPlanCellIndex);
if (calculatorForCell != m_singleFractureCellCalculators.end())
{
currentAggregatedDistanceY += calculatorForCell->second.fractureCell().cellSizeZ();
}
else
{
longestRange = std::max(longestRange, currentAggregatedDistanceY);
currentAggregatedDistanceY = 0.0;
}
}
longestRange = std::max(longestRange, currentAggregatedDistanceY);
}
return longestRange;
} }

View File

@@ -26,7 +26,6 @@
#include "cvfMatrix4.h" #include "cvfMatrix4.h"
#include <map> #include <map>
#include <vector>
class QString; class QString;
@@ -45,24 +44,31 @@ public:
cvf::Mat4d fractureTransform, cvf::Mat4d fractureTransform,
double skinFactor, double skinFactor,
double cDarcy, double cDarcy,
const RigFractureGrid& fractureGrid); const RigFractureGrid& fractureGrid,
const RimFracture* fracture);
void appendDataToTransmissibilityCondenser(const RimFracture* fracture, void appendDataToTransmissibilityCondenser(bool useFiniteConductivityInFracture,
bool useFiniteConductivityInFracture,
RigTransmissibilityCondenser* condenser) const; RigTransmissibilityCondenser* condenser) const;
// Returns the area of each stimplan cell intersecting eclipse cells // Returns the area intersecting eclipse cells open for flow, from both active and inactive cells
std::map<size_t, double> eclipseCellAreas() const; // Truncated parts of the fracture are not included
double totalEclipseAreaOpenForFlow() const;
double areaWeightedMatrixTransmissibility() const;
double areaWeightedWidth() const;
double areaWeightedConductivity() const;
double longestYSectionOpenForFlow() const;
private: private:
void computeValues(); void computeValues();
private: private:
const RimEclipseCase* m_case; const RimEclipseCase* m_case;
const RimFracture* m_fracture;
double m_cDarcy; double m_cDarcy;
double m_fractureSkinFactor; double m_fractureSkinFactor;
cvf::Mat4d m_fractureTransform; cvf::Mat4d m_fractureTransform;
const RigFractureGrid& m_fractureGrid; const RigFractureGrid& m_fractureGrid;
std::vector<RigEclipseToStimPlanCellTransmissibilityCalculator> m_singleFractureCellCalculators; std::map<size_t, RigEclipseToStimPlanCellTransmissibilityCalculator> m_singleFractureCellCalculators;
}; };

View File

@@ -38,18 +38,19 @@
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RigEclipseToStimPlanCellTransmissibilityCalculator::RigEclipseToStimPlanCellTransmissibilityCalculator( RigEclipseToStimPlanCellTransmissibilityCalculator::RigEclipseToStimPlanCellTransmissibilityCalculator(
const RimEclipseCase* caseToApply, const RimEclipseCase* caseToApply,
cvf::Mat4d fractureTransform, cvf::Mat4d fractureTransform,
double skinFactor, double skinFactor,
double cDarcy, double cDarcy,
const RigFractureCell& stimPlanCell) const RigFractureCell& stimPlanCell,
const std::set<size_t>& reservoirCellIndicesOpenForFlow)
: m_case(caseToApply) : m_case(caseToApply)
, m_fractureTransform(fractureTransform) , m_fractureTransform(fractureTransform)
, m_fractureSkinFactor(skinFactor) , m_fractureSkinFactor(skinFactor)
, m_cDarcy(cDarcy) , m_cDarcy(cDarcy)
, m_stimPlanCell(stimPlanCell) , m_stimPlanCell(stimPlanCell)
{ {
calculateStimPlanCellsMatrixTransmissibility(); calculateStimPlanCellsMatrixTransmissibility(reservoirCellIndicesOpenForFlow);
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -76,6 +77,36 @@ const std::vector<double>& RigEclipseToStimPlanCellTransmissibilityCalculator::c
return m_contributingEclipseCellAreas; return m_contributingEclipseCellAreas;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigEclipseToStimPlanCellTransmissibilityCalculator::areaOpenForFlow() const
{
double area = 0.0;
for (const auto& areaForOneEclipseCell : m_contributingEclipseCellAreas)
{
area += areaForOneEclipseCell;
}
return area;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigEclipseToStimPlanCellTransmissibilityCalculator::aggregatedMatrixTransmissibility() const
{
double totalTransmissibility = 0.0;
for (const auto& trans : m_contributingEclipseCellTransmissibilities)
{
totalTransmissibility += trans;
}
return totalTransmissibility;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -115,7 +146,8 @@ std::vector<QString> RigEclipseToStimPlanCellTransmissibilityCalculator::optiona
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RigEclipseToStimPlanCellTransmissibilityCalculator::calculateStimPlanCellsMatrixTransmissibility() void RigEclipseToStimPlanCellTransmissibilityCalculator::calculateStimPlanCellsMatrixTransmissibility(
const std::set<size_t>& reservoirCellIndicesOpenForFlow)
{ {
// Not calculating flow into fracture if stimPlan cell cond value is 0 (assumed to be outside the fracture): // Not calculating flow into fracture if stimPlan cell cond value is 0 (assumed to be outside the fracture):
if (m_stimPlanCell.getConductivityValue() < 1e-7) return; if (m_stimPlanCell.getConductivityValue() < 1e-7) return;
@@ -159,22 +191,7 @@ void RigEclipseToStimPlanCellTransmissibilityCalculator::calculateStimPlanCellsM
std::vector<size_t> reservoirCellIndices = getPotentiallyFracturedCellsForPolygon(stimPlanPolygonTransformed); std::vector<size_t> reservoirCellIndices = getPotentiallyFracturedCellsForPolygon(stimPlanPolygonTransformed);
for (size_t reservoirCellIndex : reservoirCellIndices) for (size_t reservoirCellIndex : reservoirCellIndices)
{ {
bool cellIsActive = activeCellInfo->isActive(reservoirCellIndex); if (reservoirCellIndicesOpenForFlow.count(reservoirCellIndex) == 0) continue;
if (!cellIsActive) continue;
double permX = dataAccessObjectPermX->cellScalarGlobIdx(reservoirCellIndex);
double permY = dataAccessObjectPermY->cellScalarGlobIdx(reservoirCellIndex);
double permZ = dataAccessObjectPermZ->cellScalarGlobIdx(reservoirCellIndex);
double dx = dataAccessObjectDx->cellScalarGlobIdx(reservoirCellIndex);
double dy = dataAccessObjectDy->cellScalarGlobIdx(reservoirCellIndex);
double dz = dataAccessObjectDz->cellScalarGlobIdx(reservoirCellIndex);
double NTG = 1.0;
if (dataAccessObjectNTG.notNull())
{
NTG = dataAccessObjectNTG->cellScalarGlobIdx(reservoirCellIndex);
}
const RigMainGrid* mainGrid = m_case->eclipseCaseData()->mainGrid(); const RigMainGrid* mainGrid = m_case->eclipseCaseData()->mainGrid();
std::array<cvf::Vec3d, 8> hexCorners; std::array<cvf::Vec3d, 8> hexCorners;
@@ -252,15 +269,35 @@ void RigEclipseToStimPlanCellTransmissibilityCalculator::calculateStimPlanCellsM
double fractureAreaWeightedlength = totalAreaXLength / fractureArea; double fractureAreaWeightedlength = totalAreaXLength / fractureArea;
double transmissibility_X = RigFractureTransmissibilityEquations::matrixToFractureTrans( // Transmissibility for inactive cells is set to zero
permY, NTG, Ay, dx, m_fractureSkinFactor, fractureAreaWeightedlength, m_cDarcy); double transmissibility = 0.0;
double transmissibility_Y = RigFractureTransmissibilityEquations::matrixToFractureTrans(
permX, NTG, Ax, dy, m_fractureSkinFactor, fractureAreaWeightedlength, m_cDarcy);
double transmissibility_Z = RigFractureTransmissibilityEquations::matrixToFractureTrans(
permZ, 1.0, Az, dz, m_fractureSkinFactor, fractureAreaWeightedlength, m_cDarcy);
double transmissibility = sqrt(transmissibility_X * transmissibility_X + transmissibility_Y * transmissibility_Y + if (activeCellInfo->isActive(reservoirCellIndex))
transmissibility_Z * transmissibility_Z); {
double permX = dataAccessObjectPermX->cellScalarGlobIdx(reservoirCellIndex);
double permY = dataAccessObjectPermY->cellScalarGlobIdx(reservoirCellIndex);
double permZ = dataAccessObjectPermZ->cellScalarGlobIdx(reservoirCellIndex);
double dx = dataAccessObjectDx->cellScalarGlobIdx(reservoirCellIndex);
double dy = dataAccessObjectDy->cellScalarGlobIdx(reservoirCellIndex);
double dz = dataAccessObjectDz->cellScalarGlobIdx(reservoirCellIndex);
double NTG = 1.0;
if (dataAccessObjectNTG.notNull())
{
NTG = dataAccessObjectNTG->cellScalarGlobIdx(reservoirCellIndex);
}
double transmissibility_X = RigFractureTransmissibilityEquations::matrixToFractureTrans(
permY, NTG, Ay, dx, m_fractureSkinFactor, fractureAreaWeightedlength, m_cDarcy);
double transmissibility_Y = RigFractureTransmissibilityEquations::matrixToFractureTrans(
permX, NTG, Ax, dy, m_fractureSkinFactor, fractureAreaWeightedlength, m_cDarcy);
double transmissibility_Z = RigFractureTransmissibilityEquations::matrixToFractureTrans(
permZ, 1.0, Az, dz, m_fractureSkinFactor, fractureAreaWeightedlength, m_cDarcy);
transmissibility = sqrt(transmissibility_X * transmissibility_X + transmissibility_Y * transmissibility_Y +
transmissibility_Z * transmissibility_Z);
}
m_globalIndiciesToContributingEclipseCells.push_back(reservoirCellIndex); m_globalIndiciesToContributingEclipseCells.push_back(reservoirCellIndex);
m_contributingEclipseCellTransmissibilities.push_back(transmissibility); m_contributingEclipseCellTransmissibilities.push_back(transmissibility);

View File

@@ -34,31 +34,39 @@ class RigResultAccessor;
//================================================================================================== //==================================================================================================
/// ///
/// Calculator used to compute the intersection areas between one RigFractureCell and Eclipse cells
/// Both active and inactive Eclipse cells are included. The transmissibility value for inactive cells are set to zero.
/// Eclipse reservoir cells open for flow is defined by reservoirCellIndicesOpenForFlow
///
//================================================================================================== //==================================================================================================
class RigEclipseToStimPlanCellTransmissibilityCalculator class RigEclipseToStimPlanCellTransmissibilityCalculator
{ {
public: public:
explicit RigEclipseToStimPlanCellTransmissibilityCalculator(const RimEclipseCase* caseToApply, explicit RigEclipseToStimPlanCellTransmissibilityCalculator(const RimEclipseCase* caseToApply,
cvf::Mat4d fractureTransform, cvf::Mat4d fractureTransform,
double skinFactor, double skinFactor,
double cDarcy, double cDarcy,
const RigFractureCell& stimPlanCell); const RigFractureCell& stimPlanCell,
const std::set<size_t>& reservoirCellIndicesOpenForFlow);
// These three vectors have the same size
const std::vector<size_t>& globalIndiciesToContributingEclipseCells() const; const std::vector<size_t>& globalIndiciesToContributingEclipseCells() const;
const std::vector<double>& contributingEclipseCellTransmissibilities() const; const std::vector<double>& contributingEclipseCellTransmissibilities() const;
const std::vector<double>& contributingEclipseCellAreas() const; const std::vector<double>& contributingEclipseCellAreas() const;
const RigFractureCell& fractureCell() const;
double areaOpenForFlow() const;
double aggregatedMatrixTransmissibility() const;
const RigFractureCell& fractureCell() const;
static std::vector<QString> requiredResultNames(); static std::vector<QString> requiredResultNames();
static std::vector<QString> optionalResultNames(); static std::vector<QString> optionalResultNames();
private: private:
void calculateStimPlanCellsMatrixTransmissibility(); void calculateStimPlanCellsMatrixTransmissibility(const std::set<size_t>& reservoirCellIndicesOpenForFlow);
std::vector<size_t> getPotentiallyFracturedCellsForPolygon(const std::vector<cvf::Vec3d>& polygon) const; std::vector<size_t> getPotentiallyFracturedCellsForPolygon(const std::vector<cvf::Vec3d>& polygon) const;
static cvf::ref<RigResultAccessor> createResultAccessor(const RimEclipseCase* eclipseCase, static cvf::ref<RigResultAccessor> createResultAccessor(const RimEclipseCase* eclipseCase, const QString& uiResultName);
const QString& uiResultName);
private: private:
const RimEclipseCase* m_case; const RimEclipseCase* m_case;
@@ -66,7 +74,9 @@ private:
double m_fractureSkinFactor; double m_fractureSkinFactor;
cvf::Mat4d m_fractureTransform; cvf::Mat4d m_fractureTransform;
const RigFractureCell& m_stimPlanCell; const RigFractureCell& m_stimPlanCell;
std::vector<size_t> m_globalIndiciesToContributingEclipseCells;
std::vector<double> m_contributingEclipseCellTransmissibilities; // These three vectors have the same size
std::vector<double> m_contributingEclipseCellAreas; std::vector<size_t> m_globalIndiciesToContributingEclipseCells;
std::vector<double> m_contributingEclipseCellTransmissibilities;
std::vector<double> m_contributingEclipseCellAreas;
}; };