mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Refactoring ExportFractureCompletionImpl
This commit is contained in:
@@ -212,20 +212,9 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
|
||||
bool useFiniteConductivityInFracture = (fracTemplate->conductivityType() == RimFractureTemplate::FINITE_CONDUCTIVITY);
|
||||
|
||||
// If finite cond chosen and conductivity not present in stimplan file, do not calculate trans for this fracture
|
||||
if (useFiniteConductivityInFracture)
|
||||
if (useFiniteConductivityInFracture && !checkForStimPlanConductivity(fracTemplate, fracture))
|
||||
{
|
||||
auto fracTemplateStimPlan = dynamic_cast<const RimStimPlanFractureTemplate*>(fracTemplate);
|
||||
if (fracTemplateStimPlan)
|
||||
{
|
||||
if (!fracTemplateStimPlan->hasConductivity())
|
||||
{
|
||||
RiaLogging::error("Trying to export completion data for stimPlan fracture without conductivity data for " +
|
||||
fracture->name());
|
||||
RiaLogging::error("No transmissibilities will be calculated for " + fracture->name());
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
RigTransmissibilityCondenser transCondenser;
|
||||
@@ -237,183 +226,24 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
|
||||
|
||||
eclToFractureCalc.appendDataToTransmissibilityCondenser(fracture, useFiniteConductivityInFracture, &transCondenser);
|
||||
|
||||
//////
|
||||
// Calculate Transmissibility in the fracture: From one StimPlan Cell to the other
|
||||
|
||||
if (useFiniteConductivityInFracture)
|
||||
{
|
||||
for (size_t i = 0; i < fractureGrid->iCellCount(); i++)
|
||||
{
|
||||
for (size_t j = 0; j < fractureGrid->jCellCount(); j++)
|
||||
{
|
||||
size_t fractureCellIndex = fractureGrid->getGlobalIndexFromIJ(i, j);
|
||||
|
||||
const RigFractureCell& fractureCell = fractureGrid->cellFromIndex(fractureCellIndex);
|
||||
|
||||
if (!fractureCell.hasNonZeroConductivity()) continue;
|
||||
|
||||
if (i < fractureGrid->iCellCount() - 1)
|
||||
{
|
||||
size_t fractureCellNeighbourXIndex = fractureGrid->getGlobalIndexFromIJ(i + 1, j);
|
||||
const RigFractureCell& fractureCellNeighbourX = fractureGrid->cellFromIndex(fractureCellNeighbourXIndex);
|
||||
|
||||
double horizontalTransToXneigbour = RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans(
|
||||
fractureCell.getConductivityValue(),
|
||||
fractureCell.cellSizeX(),
|
||||
fractureCell.cellSizeZ(),
|
||||
fractureCellNeighbourX.getConductivityValue(),
|
||||
fractureCellNeighbourX.cellSizeX(),
|
||||
fractureCellNeighbourX.cellSizeZ(),
|
||||
cDarcyInCorrectUnit);
|
||||
|
||||
transCondenser.addNeighborTransmissibility(
|
||||
{false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellIndex},
|
||||
{false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellNeighbourXIndex},
|
||||
horizontalTransToXneigbour);
|
||||
}
|
||||
|
||||
if (j < fractureGrid->jCellCount() - 1)
|
||||
{
|
||||
size_t fractureCellNeighbourZIndex = fractureGrid->getGlobalIndexFromIJ(i, j + 1);
|
||||
const RigFractureCell& fractureCellNeighbourZ = fractureGrid->cellFromIndex(fractureCellNeighbourZIndex);
|
||||
|
||||
double verticalTransToZneigbour = RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans(
|
||||
fractureCell.getConductivityValue(),
|
||||
fractureCell.cellSizeZ(),
|
||||
fractureCell.cellSizeX(),
|
||||
fractureCellNeighbourZ.getConductivityValue(),
|
||||
fractureCellNeighbourZ.cellSizeZ(),
|
||||
fractureCellNeighbourZ.cellSizeX(),
|
||||
cDarcyInCorrectUnit);
|
||||
|
||||
transCondenser.addNeighborTransmissibility(
|
||||
{false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellIndex},
|
||||
{false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellNeighbourZIndex},
|
||||
verticalTransToZneigbour);
|
||||
}
|
||||
}
|
||||
}
|
||||
calculateInternalFractureTransmissibilities(fractureGrid, cDarcyInCorrectUnit, transCondenser);
|
||||
}
|
||||
|
||||
/////
|
||||
// Calculate transmissibility into the well
|
||||
|
||||
if (useFiniteConductivityInFracture)
|
||||
{
|
||||
////
|
||||
// If fracture has orientation Azimuth or Transverse, assume only radial inflow
|
||||
|
||||
if (fracTemplate->orientationType() == RimFractureTemplate::AZIMUTH ||
|
||||
fracTemplate->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH)
|
||||
{
|
||||
std::pair<size_t, size_t> wellCellIJ = fractureGrid->fractureCellAtWellCenter();
|
||||
size_t wellCellIndex = fractureGrid->getGlobalIndexFromIJ(wellCellIJ.first, wellCellIJ.second);
|
||||
|
||||
const RigFractureCell& wellCell = fractureGrid->cellFromIndex(wellCellIndex);
|
||||
|
||||
double radialTrans =
|
||||
RigFractureTransmissibilityEquations::fractureCellToWellRadialTrans(wellCell.getConductivityValue(),
|
||||
wellCell.cellSizeX(),
|
||||
wellCell.cellSizeZ(),
|
||||
fracture->wellRadius(),
|
||||
fracTemplate->skinFactor(),
|
||||
cDarcyInCorrectUnit);
|
||||
|
||||
transCondenser.addNeighborTransmissibility(
|
||||
{true, RigTransmissibilityCondenser::CellAddress::WELL, 1},
|
||||
{false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, wellCellIndex},
|
||||
radialTrans);
|
||||
}
|
||||
else if (fracTemplate->orientationType() == RimFractureTemplate::ALONG_WELL_PATH)
|
||||
{
|
||||
////
|
||||
// If fracture has orientation along well, linear inflow along well and radial flow at endpoints
|
||||
|
||||
RigWellPathStimplanIntersector wellFractureIntersector(wellPathGeometry, fracture);
|
||||
const std::map<size_t, RigWellPathStimplanIntersector::WellCellIntersection>& fractureWellCells =
|
||||
wellFractureIntersector.intersections();
|
||||
|
||||
for (const auto& fracCellIdxIsectDataPair : fractureWellCells)
|
||||
{
|
||||
size_t fracWellCellIdx = fracCellIdxIsectDataPair.first;
|
||||
|
||||
RigWellPathStimplanIntersector::WellCellIntersection intersection = fracCellIdxIsectDataPair.second;
|
||||
|
||||
const RigFractureCell& fractureWellCell = fractureGrid->cellFromIndex(fracWellCellIdx);
|
||||
|
||||
double linearTrans = 0.0;
|
||||
if (intersection.hlength > 0.0 || intersection.vlength > 0.0)
|
||||
{
|
||||
linearTrans = RigFractureTransmissibilityEquations::fractureCellToWellLinearTrans(
|
||||
fractureWellCell.getConductivityValue(),
|
||||
fractureWellCell.cellSizeX(),
|
||||
fractureWellCell.cellSizeZ(),
|
||||
intersection.vlength,
|
||||
intersection.hlength,
|
||||
fracture->perforationEfficiency(),
|
||||
fracTemplate->skinFactor(),
|
||||
cDarcyInCorrectUnit);
|
||||
}
|
||||
|
||||
transCondenser.addNeighborTransmissibility(
|
||||
{true, RigTransmissibilityCondenser::CellAddress::WELL, 1},
|
||||
{false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fracWellCellIdx},
|
||||
linearTrans);
|
||||
}
|
||||
}
|
||||
calculateFractureToWellTransmissibilities(fracTemplate, fractureGrid, fracture, cDarcyInCorrectUnit, wellPathGeometry, transCondenser);
|
||||
}
|
||||
|
||||
/////
|
||||
// Insert total transmissibility from eclipse-cell to well for this fracture into the map
|
||||
|
||||
std::vector<RigCompletionData> allCompletionsForOneFracture;
|
||||
|
||||
std::set<RigTransmissibilityCondenser::CellAddress> externalCells = transCondenser.externalCells();
|
||||
for (RigTransmissibilityCondenser::CellAddress externalCell : externalCells)
|
||||
{
|
||||
if (externalCell.m_cellIndexSpace == RigTransmissibilityCondenser::CellAddress::ECLIPSE)
|
||||
{
|
||||
double trans = transCondenser.condensedTransmissibility(
|
||||
externalCell, {true, RigTransmissibilityCondenser::CellAddress::WELL, 1});
|
||||
|
||||
// eclCellIdxToTransPrFractureMap[externalCell.m_globalCellIdx][fracture] = trans;
|
||||
|
||||
RigCompletionData compDat(wellPathName,
|
||||
RigCompletionDataGridCell(externalCell.m_globalCellIdx, caseToApply->mainGrid()),
|
||||
fracture->fractureMD());
|
||||
|
||||
double diameter = 2.0 * fracture->wellRadius();
|
||||
compDat.setFromFracture(trans, fracTemplate->skinFactor(), diameter);
|
||||
compDat.addMetadata(fracture->name(), QString::number(trans));
|
||||
allCompletionsForOneFracture.push_back(compDat);
|
||||
}
|
||||
}
|
||||
|
||||
/////
|
||||
// Compute Non-Dracy Flow parameters
|
||||
std::map<size_t, double> matrixToWellTrans = calculateMatrixToWellTransmissibilities(transCondenser);
|
||||
std::vector<RigCompletionData> allCompletionsForOneFracture = generateCompdatValuesForFracture(matrixToWellTrans, wellPathName, caseToApply, fracture, fracTemplate);
|
||||
|
||||
if (fracTemplate->isNonDarcyFlowEnabled())
|
||||
{
|
||||
double dFactorForFracture = fracture->nonDarcyProperties().dFactor;
|
||||
double khForFracture = fracture->nonDarcyProperties().conductivity;
|
||||
|
||||
double sumOfTransmissibilitiesInFracture = 0.0;
|
||||
for (const auto& c : allCompletionsForOneFracture)
|
||||
{
|
||||
sumOfTransmissibilitiesInFracture += c.transmissibility();
|
||||
}
|
||||
|
||||
for (auto& c : allCompletionsForOneFracture)
|
||||
{
|
||||
// NOTE : What is supposed to happen when the transmissibility is close to zero?
|
||||
|
||||
double dFactorForOneConnection = dFactorForFracture * sumOfTransmissibilitiesInFracture / c.transmissibility();
|
||||
c.setDFactor(dFactorForOneConnection);
|
||||
|
||||
double khForOneConnection = khForFracture * c.transmissibility() / sumOfTransmissibilitiesInFracture;
|
||||
|
||||
c.setKh(khForOneConnection);
|
||||
}
|
||||
computeNonDarcyFlowParameters(fracture, allCompletionsForOneFracture);
|
||||
}
|
||||
|
||||
if (fractureDataReportItems)
|
||||
@@ -421,92 +251,16 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
|
||||
QString fractureTemplateName = fracTemplate->name();
|
||||
RicWellPathFractureReportItem reportItem(wellPathName, fracture->name(), fractureTemplateName);
|
||||
|
||||
double transmissibility = 0.0;
|
||||
double fcd = -1.0;
|
||||
double area = 0.0;
|
||||
|
||||
for (const auto& c : allCompletionsForOneFracture)
|
||||
{
|
||||
transmissibility += c.transmissibility();
|
||||
}
|
||||
|
||||
auto cellAreas = eclToFractureCalc.eclipseCellAreas();
|
||||
for (const auto& cellArea : cellAreas)
|
||||
{
|
||||
area += cellArea.second;
|
||||
}
|
||||
|
||||
double fcd = -1.0;
|
||||
double area = sumUpCellAreas(cellAreas);
|
||||
double transmissibility = sumUpTransmissibilities(allCompletionsForOneFracture);
|
||||
|
||||
reportItem.setData(transmissibility, allCompletionsForOneFracture.size(), fcd, area);
|
||||
|
||||
double conductivity = 0.0;
|
||||
double width = 0.0;
|
||||
double height = 0.0;
|
||||
double halfLength = 0.0;
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem = RiaEclipseUnitTools::UNITS_METRIC;
|
||||
|
||||
{
|
||||
auto* ellipseTemplate = dynamic_cast<const RimEllipseFractureTemplate*>(fracTemplate);
|
||||
if (ellipseTemplate)
|
||||
{
|
||||
unitSystem = ellipseTemplate->fractureTemplateUnit();
|
||||
conductivity = ellipseTemplate->conductivity();
|
||||
width = ellipseTemplate->width();
|
||||
height = ellipseTemplate->height();
|
||||
halfLength = ellipseTemplate->halfLength();
|
||||
}
|
||||
|
||||
auto* stimplanTemplate = dynamic_cast<const RimStimPlanFractureTemplate*>(fracTemplate);
|
||||
if (stimplanTemplate)
|
||||
{
|
||||
unitSystem = stimplanTemplate->fractureTemplateUnit();
|
||||
conductivity = stimplanTemplate->areaWeightedConductivity();
|
||||
width = stimplanTemplate->areaWeightedWidth();
|
||||
|
||||
height = stimplanTemplate->longestYRange();
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
calculateAndSetLengthsAndConductivity(fracTemplate, area, reportItem);
|
||||
calculateAndSetAreaWeightedTransmissibility(caseToApply, cellAreas, area, reportItem);
|
||||
|
||||
fractureDataReportItems->push_back(reportItem);
|
||||
}
|
||||
@@ -519,23 +273,7 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
|
||||
{
|
||||
#pragma omp critical(critical_section_outputStreamForIntermediateResultsText)
|
||||
{
|
||||
(*outputStreamForIntermediateResultsText)
|
||||
<< "\n"
|
||||
<< "\n"
|
||||
<< "\n----------- All Transmissibilities " << fracture->name() << " -------------------- \n\n";
|
||||
|
||||
(*outputStreamForIntermediateResultsText)
|
||||
<< QString::fromStdString(transCondenser.neighborTransDebugOutput(mainGrid, fractureGrid));
|
||||
|
||||
(*outputStreamForIntermediateResultsText)
|
||||
<< "\n"
|
||||
<< "\n"
|
||||
<< "\n----------- Condensed Results " << fracture->name() << " -------------------- \n\n";
|
||||
|
||||
(*outputStreamForIntermediateResultsText)
|
||||
<< QString::fromStdString(transCondenser.condensedTransDebugOutput(mainGrid, fractureGrid));
|
||||
|
||||
(*outputStreamForIntermediateResultsText) << "\n";
|
||||
outputIntermediateResultsText(outputStreamForIntermediateResultsText, fracture, transCondenser, mainGrid, fractureGrid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -546,3 +284,362 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
|
||||
}
|
||||
return fractureCompletions;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicExportFractureCompletionsImpl::checkForStimPlanConductivity(const RimFractureTemplate* fracTemplate, const RimFracture* fracture)
|
||||
{
|
||||
auto fracTemplateStimPlan = dynamic_cast<const RimStimPlanFractureTemplate*>(fracTemplate);
|
||||
if (fracTemplateStimPlan)
|
||||
{
|
||||
if (!fracTemplateStimPlan->hasConductivity())
|
||||
{
|
||||
RiaLogging::error("Trying to export completion data for stimPlan fracture without conductivity data for " +
|
||||
fracture->name());
|
||||
RiaLogging::error("No transmissibilities will be calculated for " + fracture->name());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicExportFractureCompletionsImpl::calculateInternalFractureTransmissibilities(const RigFractureGrid* fractureGrid, double cDarcyInCorrectUnit, RigTransmissibilityCondenser &transCondenser)
|
||||
{
|
||||
for (size_t i = 0; i < fractureGrid->iCellCount(); i++)
|
||||
{
|
||||
for (size_t j = 0; j < fractureGrid->jCellCount(); j++)
|
||||
{
|
||||
size_t fractureCellIndex = fractureGrid->getGlobalIndexFromIJ(i, j);
|
||||
|
||||
const RigFractureCell& fractureCell = fractureGrid->cellFromIndex(fractureCellIndex);
|
||||
|
||||
if (!fractureCell.hasNonZeroConductivity()) continue;
|
||||
|
||||
if (i < fractureGrid->iCellCount() - 1)
|
||||
{
|
||||
size_t fractureCellNeighbourXIndex = fractureGrid->getGlobalIndexFromIJ(i + 1, j);
|
||||
const RigFractureCell& fractureCellNeighbourX = fractureGrid->cellFromIndex(fractureCellNeighbourXIndex);
|
||||
|
||||
double horizontalTransToXneigbour = RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans(
|
||||
fractureCell.getConductivityValue(),
|
||||
fractureCell.cellSizeX(),
|
||||
fractureCell.cellSizeZ(),
|
||||
fractureCellNeighbourX.getConductivityValue(),
|
||||
fractureCellNeighbourX.cellSizeX(),
|
||||
fractureCellNeighbourX.cellSizeZ(),
|
||||
cDarcyInCorrectUnit);
|
||||
|
||||
transCondenser.addNeighborTransmissibility(
|
||||
{ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellIndex },
|
||||
{ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellNeighbourXIndex },
|
||||
horizontalTransToXneigbour);
|
||||
}
|
||||
|
||||
if (j < fractureGrid->jCellCount() - 1)
|
||||
{
|
||||
size_t fractureCellNeighbourZIndex = fractureGrid->getGlobalIndexFromIJ(i, j + 1);
|
||||
const RigFractureCell& fractureCellNeighbourZ = fractureGrid->cellFromIndex(fractureCellNeighbourZIndex);
|
||||
|
||||
double verticalTransToZneigbour = RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans(
|
||||
fractureCell.getConductivityValue(),
|
||||
fractureCell.cellSizeZ(),
|
||||
fractureCell.cellSizeX(),
|
||||
fractureCellNeighbourZ.getConductivityValue(),
|
||||
fractureCellNeighbourZ.cellSizeZ(),
|
||||
fractureCellNeighbourZ.cellSizeX(),
|
||||
cDarcyInCorrectUnit);
|
||||
|
||||
transCondenser.addNeighborTransmissibility(
|
||||
{ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellIndex },
|
||||
{ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellNeighbourZIndex },
|
||||
verticalTransToZneigbour);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
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 (fracTemplate->orientationType() == RimFractureTemplate::AZIMUTH ||
|
||||
fracTemplate->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH)
|
||||
{
|
||||
std::pair<size_t, size_t> wellCellIJ = fractureGrid->fractureCellAtWellCenter();
|
||||
size_t wellCellIndex = fractureGrid->getGlobalIndexFromIJ(wellCellIJ.first, wellCellIJ.second);
|
||||
|
||||
const RigFractureCell& wellCell = fractureGrid->cellFromIndex(wellCellIndex);
|
||||
|
||||
double radialTrans =
|
||||
RigFractureTransmissibilityEquations::fractureCellToWellRadialTrans(wellCell.getConductivityValue(),
|
||||
wellCell.cellSizeX(),
|
||||
wellCell.cellSizeZ(),
|
||||
fracture->wellRadius(),
|
||||
fracTemplate->skinFactor(),
|
||||
cDarcyInCorrectUnit);
|
||||
|
||||
transCondenser.addNeighborTransmissibility(
|
||||
{ true, RigTransmissibilityCondenser::CellAddress::WELL, 1 },
|
||||
{ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, wellCellIndex },
|
||||
radialTrans);
|
||||
}
|
||||
else if (fracTemplate->orientationType() == RimFractureTemplate::ALONG_WELL_PATH)
|
||||
{
|
||||
////
|
||||
// If fracture has orientation along well, linear inflow along well and radial flow at endpoints
|
||||
|
||||
RigWellPathStimplanIntersector wellFractureIntersector(wellPathGeometry, fracture);
|
||||
const std::map<size_t, RigWellPathStimplanIntersector::WellCellIntersection>& fractureWellCells =
|
||||
wellFractureIntersector.intersections();
|
||||
|
||||
for (const auto& fracCellIdxIsectDataPair : fractureWellCells)
|
||||
{
|
||||
size_t fracWellCellIdx = fracCellIdxIsectDataPair.first;
|
||||
|
||||
RigWellPathStimplanIntersector::WellCellIntersection intersection = fracCellIdxIsectDataPair.second;
|
||||
|
||||
const RigFractureCell& fractureWellCell = fractureGrid->cellFromIndex(fracWellCellIdx);
|
||||
|
||||
double linearTrans = 0.0;
|
||||
if (intersection.hlength > 0.0 || intersection.vlength > 0.0)
|
||||
{
|
||||
linearTrans = RigFractureTransmissibilityEquations::fractureCellToWellLinearTrans(
|
||||
fractureWellCell.getConductivityValue(),
|
||||
fractureWellCell.cellSizeX(),
|
||||
fractureWellCell.cellSizeZ(),
|
||||
intersection.vlength,
|
||||
intersection.hlength,
|
||||
fracture->perforationEfficiency(),
|
||||
fracTemplate->skinFactor(),
|
||||
cDarcyInCorrectUnit);
|
||||
}
|
||||
|
||||
transCondenser.addNeighborTransmissibility(
|
||||
{ true, RigTransmissibilityCondenser::CellAddress::WELL, 1 },
|
||||
{ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fracWellCellIdx },
|
||||
linearTrans);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::map<size_t, double> RicExportFractureCompletionsImpl::calculateMatrixToWellTransmissibilities(RigTransmissibilityCondenser &transCondenser)
|
||||
{
|
||||
std::map<size_t, double> matrixToWellTransmissibilities;
|
||||
|
||||
std::set<RigTransmissibilityCondenser::CellAddress> externalCells = transCondenser.externalCells();
|
||||
for (RigTransmissibilityCondenser::CellAddress externalCell : externalCells)
|
||||
{
|
||||
if (externalCell.m_cellIndexSpace == RigTransmissibilityCondenser::CellAddress::ECLIPSE)
|
||||
{
|
||||
double trans = transCondenser.condensedTransmissibility(
|
||||
externalCell, { true, RigTransmissibilityCondenser::CellAddress::WELL, 1 });
|
||||
|
||||
matrixToWellTransmissibilities.insert(std::make_pair(externalCell.m_globalCellIdx, trans));
|
||||
|
||||
}
|
||||
}
|
||||
return matrixToWellTransmissibilities;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
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;
|
||||
for (const auto& matrixToWellTransmissibility : matrixToWellTransmissibilites)
|
||||
{
|
||||
size_t globalCellIndex = matrixToWellTransmissibility.first;
|
||||
double trans = matrixToWellTransmissibility.second;
|
||||
RigCompletionData compDat(wellPathName,
|
||||
RigCompletionDataGridCell(globalCellIndex, caseToApply->mainGrid()),
|
||||
fracture->fractureMD());
|
||||
|
||||
double diameter = 2.0 * fracture->wellRadius();
|
||||
compDat.setFromFracture(trans, fracTemplate->skinFactor(), diameter);
|
||||
compDat.addMetadata(fracture->name(), QString::number(trans));
|
||||
allCompletionsForOneFracture.push_back(compDat);
|
||||
}
|
||||
return allCompletionsForOneFracture;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicExportFractureCompletionsImpl::computeNonDarcyFlowParameters(const RimFracture* fracture, std::vector<RigCompletionData> allCompletionsForOneFracture)
|
||||
{
|
||||
double dFactorForFracture = fracture->nonDarcyProperties().dFactor;
|
||||
double khForFracture = fracture->nonDarcyProperties().conductivity;
|
||||
|
||||
double sumOfTransmissibilitiesInFracture = 0.0;
|
||||
for (const auto& c : allCompletionsForOneFracture)
|
||||
{
|
||||
sumOfTransmissibilitiesInFracture += c.transmissibility();
|
||||
}
|
||||
|
||||
for (auto& c : allCompletionsForOneFracture)
|
||||
{
|
||||
// NOTE : What is supposed to happen when the transmissibility is close to zero?
|
||||
|
||||
double dFactorForOneConnection = dFactorForFracture * sumOfTransmissibilitiesInFracture / c.transmissibility();
|
||||
c.setDFactor(dFactorForOneConnection);
|
||||
|
||||
double khForOneConnection = khForFracture * c.transmissibility() / sumOfTransmissibilitiesInFracture;
|
||||
|
||||
c.setKh(khForOneConnection);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RicExportFractureCompletionsImpl::sumUpCellAreas(const std::map<size_t, double>& cellAreas)
|
||||
{
|
||||
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;
|
||||
for (const auto& c : allCompletionsForOneFracture)
|
||||
{
|
||||
transmissibility += c.transmissibility();
|
||||
}
|
||||
return transmissibility;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicExportFractureCompletionsImpl::calculateAndSetLengthsAndConductivity(const RimFractureTemplate* fracTemplate,
|
||||
double area,
|
||||
RicWellPathFractureReportItem& reportItem)
|
||||
{
|
||||
double conductivity = 0.0;
|
||||
double width = 0.0;
|
||||
double height = 0.0;
|
||||
double halfLength = 0.0;
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem = RiaEclipseUnitTools::UNITS_METRIC;
|
||||
|
||||
{
|
||||
auto* ellipseTemplate = dynamic_cast<const RimEllipseFractureTemplate*>(fracTemplate);
|
||||
if (ellipseTemplate)
|
||||
{
|
||||
unitSystem = ellipseTemplate->fractureTemplateUnit();
|
||||
conductivity = ellipseTemplate->conductivity();
|
||||
width = ellipseTemplate->width();
|
||||
height = ellipseTemplate->height();
|
||||
halfLength = ellipseTemplate->halfLength();
|
||||
}
|
||||
|
||||
auto* stimplanTemplate = dynamic_cast<const RimStimPlanFractureTemplate*>(fracTemplate);
|
||||
if (stimplanTemplate)
|
||||
{
|
||||
unitSystem = stimplanTemplate->fractureTemplateUnit();
|
||||
conductivity = stimplanTemplate->areaWeightedConductivity();
|
||||
width = stimplanTemplate->areaWeightedWidth();
|
||||
|
||||
height = stimplanTemplate->longestYRange();
|
||||
|
||||
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,
|
||||
std::map<size_t, double> cellAreas,
|
||||
double area,
|
||||
RicWellPathFractureReportItem& reportItem)
|
||||
{
|
||||
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)
|
||||
<< "\n"
|
||||
<< "\n"
|
||||
<< "\n----------- All Transmissibilities " << fracture->name() << " -------------------- \n\n";
|
||||
|
||||
(*outputStreamForIntermediateResultsText)
|
||||
<< QString::fromStdString(transCondenser.neighborTransDebugOutput(mainGrid, fractureGrid));
|
||||
|
||||
(*outputStreamForIntermediateResultsText)
|
||||
<< "\n"
|
||||
<< "\n"
|
||||
<< "\n----------- Condensed Results " << fracture->name() << " -------------------- \n\n";
|
||||
|
||||
(*outputStreamForIntermediateResultsText)
|
||||
<< QString::fromStdString(transCondenser.condensedTransDebugOutput(mainGrid, fractureGrid));
|
||||
|
||||
(*outputStreamForIntermediateResultsText) << "\n";
|
||||
}
|
||||
|
||||
@@ -20,17 +20,22 @@
|
||||
|
||||
#include "RigCompletionData.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class RigFractureGrid;
|
||||
class RicWellPathFractureReportItem;
|
||||
class RigWellPath;
|
||||
class RigTransmissibilityCondenser;
|
||||
|
||||
class RimEclipseCase;
|
||||
class RimFracture;
|
||||
class RimFractureTemplate;
|
||||
class RimSimWellInView;
|
||||
class RimWellPath;
|
||||
|
||||
class QTextStream;
|
||||
|
||||
class QString;
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -63,4 +68,22 @@ private:
|
||||
const std::vector<const RimFracture*>& fractures,
|
||||
std::vector<RicWellPathFractureReportItem>* fractureDataReportItems,
|
||||
QTextStream* outputStreamForIntermediateResultsText);
|
||||
|
||||
static bool checkForStimPlanConductivity(const RimFractureTemplate* fracTemplate, const RimFracture* fracture);
|
||||
|
||||
static void calculateInternalFractureTransmissibilities(const RigFractureGrid* fractureGrid, double cDarcyInCorrectUnit, RigTransmissibilityCondenser &transCondenser);
|
||||
static void calculateFractureToWellTransmissibilities(const RimFractureTemplate* fracTemplate, const RigFractureGrid* fractureGrid, const RimFracture* fracture, double cDarcyInCorrectUnit, const RigWellPath* wellPathGeometry, RigTransmissibilityCondenser &transCondenser);
|
||||
|
||||
static std::map<size_t, double> calculateMatrixToWellTransmissibilities(RigTransmissibilityCondenser &transCondenser);
|
||||
static std::vector<RigCompletionData> generateCompdatValuesForFracture(const std::map<size_t, double>& matrixToWellTransmissibilites, const QString& wellPathName, const RimEclipseCase* caseToApply, const RimFracture* fracture, const RimFractureTemplate* fracTemplate);
|
||||
|
||||
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 void calculateAndSetLengthsAndConductivity(const RimFractureTemplate* fracTemplate, double area, 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);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user