mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#3089 Non-Darcy longitudinal : Add support for longitudinal fractures
- move non-darcy data from template to fracture, as this data is now depending of fracutre - compute weighted average of stimplan width and conductivity based on fracture perforation length - use referringPtrFields() to find fractures using this fracture template
This commit is contained in:
parent
4c75e2514d
commit
2ddc3d77df
@ -67,10 +67,12 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
|
||||
|
||||
if (wellPath->fractureCollection()->isChecked())
|
||||
{
|
||||
for (const auto& frac : wellPath->fractureCollection()->fractures)
|
||||
for (auto& frac : wellPath->fractureCollection()->fractures)
|
||||
{
|
||||
if (frac->isChecked())
|
||||
{
|
||||
frac->ensureValidNonDarcyProperties();
|
||||
|
||||
fracturesAlongWellPath.push_back(frac);
|
||||
}
|
||||
}
|
||||
@ -174,11 +176,8 @@ std::vector<RigCompletionData>
|
||||
|
||||
//////
|
||||
// Calculate Matrix To Fracture Trans
|
||||
RigEclipseToStimPlanCalculator eclToFractureCalc(caseToApply,
|
||||
fracture->transformMatrix(),
|
||||
fracture->fractureTemplate()->skinFactor(),
|
||||
cDarcyInCorrectUnit,
|
||||
*fractureGrid);
|
||||
RigEclipseToStimPlanCalculator eclToFractureCalc(
|
||||
caseToApply, fracture->transformMatrix(), fracTemplate->skinFactor(), cDarcyInCorrectUnit, *fractureGrid);
|
||||
|
||||
eclToFractureCalc.appendDataToTransmissibilityCondenser(fracture, useFiniteConductivityInFracture, &transCondenser);
|
||||
|
||||
@ -248,32 +247,28 @@ std::vector<RigCompletionData>
|
||||
////
|
||||
// If fracture has orientation Azimuth or Transverse, assume only radial inflow
|
||||
|
||||
if (fracture->fractureTemplate()->orientationType() == RimFractureTemplate::AZIMUTH ||
|
||||
fracture->fractureTemplate()->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH)
|
||||
if (fracTemplate->orientationType() == RimFractureTemplate::AZIMUTH ||
|
||||
fracTemplate->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH)
|
||||
{
|
||||
const RigFractureGrid* fracGrid = fracture->fractureTemplate()->fractureGrid();
|
||||
if (fracGrid)
|
||||
{
|
||||
std::pair<size_t, size_t> wellCellIJ = fracGrid->fractureCellAtWellCenter();
|
||||
size_t wellCellIndex = fracGrid->getGlobalIndexFromIJ(wellCellIJ.first, wellCellIJ.second);
|
||||
std::pair<size_t, size_t> wellCellIJ = fractureGrid->fractureCellAtWellCenter();
|
||||
size_t wellCellIndex = fractureGrid->getGlobalIndexFromIJ(wellCellIJ.first, wellCellIJ.second);
|
||||
|
||||
const RigFractureCell& wellCell = fractureGrid->cellFromIndex(wellCellIndex);
|
||||
const RigFractureCell& wellCell = fractureGrid->cellFromIndex(wellCellIndex);
|
||||
|
||||
double radialTrans =
|
||||
RigFractureTransmissibilityEquations::fractureCellToWellRadialTrans(wellCell.getConductivityValue(),
|
||||
wellCell.cellSizeX(),
|
||||
wellCell.cellSizeZ(),
|
||||
fracture->wellRadius(),
|
||||
fracTemplate->skinFactor(),
|
||||
cDarcyInCorrectUnit);
|
||||
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);
|
||||
}
|
||||
transCondenser.addNeighborTransmissibility(
|
||||
{true, RigTransmissibilityCondenser::CellAddress::WELL, 1},
|
||||
{false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, wellCellIndex},
|
||||
radialTrans);
|
||||
}
|
||||
else if (fracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH)
|
||||
else if (fracTemplate->orientationType() == RimFractureTemplate::ALONG_WELL_PATH)
|
||||
{
|
||||
////
|
||||
// If fracture has orientation along well, linear inflow along well and radial flow at endpoints
|
||||
@ -332,7 +327,7 @@ std::vector<RigCompletionData>
|
||||
fracture->fractureMD());
|
||||
|
||||
double diameter = 2.0 * fracture->wellRadius();
|
||||
compDat.setFromFracture(trans, fracture->fractureTemplate()->skinFactor(), diameter);
|
||||
compDat.setFromFracture(trans, fracTemplate->skinFactor(), diameter);
|
||||
compDat.addMetadata(fracture->name(), QString::number(trans));
|
||||
allCompletionsForOneFracture.push_back(compDat);
|
||||
}
|
||||
@ -341,10 +336,10 @@ std::vector<RigCompletionData>
|
||||
/////
|
||||
// Compute Non-Dracy Flow parameters
|
||||
|
||||
if (fracture->fractureTemplate()->isNonDarcyFlowEnabled())
|
||||
if (fracTemplate->isNonDarcyFlowEnabled())
|
||||
{
|
||||
double dFactorForFracture = fracture->fractureTemplate()->dFactor();
|
||||
double khForFracture = fracture->fractureTemplate()->kh();
|
||||
double dFactorForFracture = fracture->nonDarcyProperties().dFactor;
|
||||
double khForFracture = fracture->nonDarcyProperties().conductivity;
|
||||
|
||||
double sumOfTransmissibilitiesInFracture = 0.0;
|
||||
for (const auto& c : allCompletionsForOneFracture)
|
||||
@ -367,11 +362,7 @@ std::vector<RigCompletionData>
|
||||
|
||||
if (fractureDataReportItems)
|
||||
{
|
||||
QString fractureTemplateName;
|
||||
if (fracture->fractureTemplate())
|
||||
{
|
||||
fractureTemplateName = fracture->fractureTemplate()->name();
|
||||
}
|
||||
QString fractureTemplateName = fracTemplate->name();
|
||||
RicWellPathFractureReportItem reportItem(wellPathName, fracture->name(), fractureTemplateName);
|
||||
|
||||
double transmissibility = 0.0;
|
||||
|
@ -290,8 +290,6 @@ QString RicWellPathFractureTextReportFeatureImpl::createStimPlanFractureText(
|
||||
RifEclipseOutputTableColumn(" "),
|
||||
floatNumberColumn("WDiam"),
|
||||
floatNumberColumn("Skin"),
|
||||
floatNumberColumn("Dfac"),
|
||||
floatNumberColumn("LPerf"),
|
||||
};
|
||||
|
||||
formatter.header(header);
|
||||
@ -302,8 +300,6 @@ QString RicWellPathFractureTextReportFeatureImpl::createStimPlanFractureText(
|
||||
formatter.add("Orientation"); // Orientation
|
||||
formatter.add("[m]"); // WDiam
|
||||
formatter.add("[] "); // Skin
|
||||
formatter.add("[...]"); // DFac
|
||||
formatter.add("[m]"); // LPerf
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
|
||||
@ -316,17 +312,6 @@ QString RicWellPathFractureTextReportFeatureImpl::createStimPlanFractureText(
|
||||
formatter.add(stimPlanTemplate->wellDiameter());
|
||||
formatter.add(stimPlanTemplate->skinFactor());
|
||||
|
||||
if (stimPlanTemplate->isNonDarcyFlowEnabled())
|
||||
{
|
||||
formatter.add(stimPlanTemplate->dFactor());
|
||||
formatter.add(stimPlanTemplate->perforationLength());
|
||||
}
|
||||
else
|
||||
{
|
||||
formatter.add("NA");
|
||||
formatter.add("NA");
|
||||
}
|
||||
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
|
||||
@ -358,8 +343,6 @@ QString RicWellPathFractureTextReportFeatureImpl::createEllipseFractureText(
|
||||
floatNumberColumn("Wf"),
|
||||
floatNumberColumn("WDiam"),
|
||||
floatNumberColumn("Skin"),
|
||||
floatNumberColumn("Dfac"),
|
||||
floatNumberColumn("LPerf"),
|
||||
};
|
||||
|
||||
formatter.header(header);
|
||||
@ -374,8 +357,6 @@ QString RicWellPathFractureTextReportFeatureImpl::createEllipseFractureText(
|
||||
formatter.add("[m]"); // Wf
|
||||
formatter.add("[m]"); // WDiam
|
||||
formatter.add("[] "); // Skin
|
||||
formatter.add("[...]"); // DFac
|
||||
formatter.add("[m]"); // LPerf
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
|
||||
@ -394,17 +375,6 @@ QString RicWellPathFractureTextReportFeatureImpl::createEllipseFractureText(
|
||||
formatter.add(ellipseTemplate->wellDiameter());
|
||||
formatter.add(ellipseTemplate->skinFactor());
|
||||
|
||||
if (ellipseTemplate->isNonDarcyFlowEnabled())
|
||||
{
|
||||
formatter.add(ellipseTemplate->dFactor());
|
||||
formatter.add(ellipseTemplate->perforationLength());
|
||||
}
|
||||
else
|
||||
{
|
||||
formatter.add("NA");
|
||||
formatter.add("NA");
|
||||
}
|
||||
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
|
||||
|
@ -231,7 +231,7 @@ void RimEllipseFractureTemplate::assignConductivityToCellsInsideEllipse()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
FractureWidthAndConductivity RimEllipseFractureTemplate::widthAndConductivityAtWellPathIntersection() const
|
||||
FractureWidthAndConductivity RimEllipseFractureTemplate::widthAndConductivityAtWellPathIntersection(const RimFracture* fractureInstance) const
|
||||
{
|
||||
FractureWidthAndConductivity values;
|
||||
values.m_width = m_width;
|
||||
|
@ -76,7 +76,7 @@ private:
|
||||
void assignConductivityToCellsInsideEllipse();
|
||||
std::vector<cvf::Vec3f> fractureBorderPolygon() const;
|
||||
|
||||
FractureWidthAndConductivity widthAndConductivityAtWellPathIntersection() const override;
|
||||
FractureWidthAndConductivity widthAndConductivityAtWellPathIntersection(const RimFracture* fractureInstance) const override;
|
||||
|
||||
private:
|
||||
cvf::ref<RigFractureGrid> m_fractureGrid;
|
||||
|
@ -213,6 +213,8 @@ void RimFracture::fieldChangedByUi(const caf::PdmFieldHandle* changedField, cons
|
||||
changedField == this->objectToggleField() || changedField == &m_dip || changedField == &m_tilt ||
|
||||
changedField == &m_perforationLength)
|
||||
{
|
||||
clearCachedNonDarcyProperties();
|
||||
|
||||
RimEclipseView* rimView = nullptr;
|
||||
this->firstAncestorOrThisOfType(rimView);
|
||||
if (rimView)
|
||||
@ -243,6 +245,46 @@ cvf::Vec3d RimFracture::fracturePosition() const
|
||||
return m_anchorPosition;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const NonDarcyData& RimFracture::nonDarcyProperties() const
|
||||
{
|
||||
CVF_ASSERT(!m_cachedFractureProperties.isDirty());
|
||||
|
||||
return m_cachedFractureProperties;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFracture::ensureValidNonDarcyProperties()
|
||||
{
|
||||
if (m_cachedFractureProperties.isDirty())
|
||||
{
|
||||
NonDarcyData props;
|
||||
|
||||
if (m_fractureTemplate)
|
||||
{
|
||||
props.width = m_fractureTemplate->computeFractureWidth(this);
|
||||
props.conductivity = m_fractureTemplate->computeKh(this);
|
||||
props.dFactor = m_fractureTemplate->computeDFactor(this);
|
||||
props.effectivePermeability = m_fractureTemplate->computeEffectivePermeability(this);
|
||||
|
||||
props.isDataDirty = false;
|
||||
}
|
||||
m_cachedFractureProperties = props;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFracture::clearCachedNonDarcyProperties()
|
||||
{
|
||||
m_cachedFractureProperties = NonDarcyData();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -644,6 +686,8 @@ void RimFracture::setFractureTemplate(RimFractureTemplate* fractureTemplate)
|
||||
}
|
||||
this->m_wellDiameter = fractureTemplate->wellDiameter();
|
||||
this->m_perforationLength = fractureTemplate->perforationLength();
|
||||
|
||||
clearCachedNonDarcyProperties();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -41,6 +41,29 @@ class RimFractureTemplate;
|
||||
class RigFracturedEclipseCellExportData;
|
||||
class RigMainGrid;
|
||||
|
||||
class NonDarcyData
|
||||
{
|
||||
public:
|
||||
NonDarcyData()
|
||||
: width(std::numeric_limits<double>::infinity())
|
||||
, conductivity(std::numeric_limits<double>::infinity())
|
||||
, effectivePermeability(std::numeric_limits<double>::infinity())
|
||||
, dFactor(std::numeric_limits<double>::infinity())
|
||||
, isDataDirty(true)
|
||||
{
|
||||
}
|
||||
|
||||
bool isDirty() const
|
||||
{
|
||||
return isDataDirty;
|
||||
}
|
||||
|
||||
double width;
|
||||
double conductivity;
|
||||
double effectivePermeability;
|
||||
double dFactor;
|
||||
bool isDataDirty;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -91,6 +114,12 @@ public:
|
||||
|
||||
virtual void loadDataAndUpdate() = 0;
|
||||
virtual std::vector<cvf::Vec3d> perforationLengthCenterLineCoords() const = 0;
|
||||
|
||||
|
||||
// Fracture properties
|
||||
const NonDarcyData& nonDarcyProperties() const;
|
||||
void ensureValidNonDarcyProperties();
|
||||
void clearCachedNonDarcyProperties();
|
||||
|
||||
friend class RimFractureTemplate;
|
||||
|
||||
@ -130,4 +159,6 @@ private:
|
||||
caf::PdmField<cvf::Vec3d> m_anchorPosition;
|
||||
|
||||
cvf::ref<RivWellFracturePartMgr> m_fracturePartMgr;
|
||||
|
||||
NonDarcyData m_cachedFractureProperties;
|
||||
};
|
||||
|
@ -147,11 +147,13 @@ RimFractureTemplate::RimFractureTemplate()
|
||||
CAF_PDM_InitField(&m_relativeGasDensity, "RelativeGasDensity", 0.8, "<html>Relative Gas Density (γ)</html>", "", "Relative density of gas at surface conditions with respect to air at STP", "");
|
||||
CAF_PDM_InitField(&m_gasViscosity, "GasViscosity", 0.02, "<html>Gas Viscosity (μ)</html> [cP]", "", "Gas viscosity at bottom hole pressure", "");
|
||||
|
||||
/*
|
||||
CAF_PDM_InitFieldNoDefault(&m_dFactorDisplayField, "dFactorDisplayField", "D Factor", "", "", "");
|
||||
m_dFactorDisplayField.registerGetMethod(this, &RimFractureTemplate::dFactor);
|
||||
m_dFactorDisplayField.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleValueEditor::uiEditorTypeName());
|
||||
m_dFactorDisplayField.uiCapability()->setUiReadOnly(true);
|
||||
m_dFactorDisplayField.xmlCapability()->disableIO();
|
||||
*/
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_dFactorSummaryText, "dFactorSummaryText", "D Factor Summary", "", "", "");
|
||||
m_dFactorSummaryText.registerGetMethod(this, &RimFractureTemplate::dFactorSummary);
|
||||
@ -244,35 +246,22 @@ void RimFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* changedFie
|
||||
bool createDisplayModelAndRedraw = false;
|
||||
if (changedField == &m_azimuthAngle || changedField == &m_orientationType)
|
||||
{
|
||||
// Changes to one of these parameters should change all fractures with this fracture template attached.
|
||||
RimProject* proj;
|
||||
this->firstAncestorOrThisOfType(proj);
|
||||
if (proj)
|
||||
for (RimFracture* fracture : fracturesUsingThisTemplate())
|
||||
{
|
||||
// Regenerate geometry
|
||||
std::vector<RimFracture*> fractures;
|
||||
proj->descendantsIncludingThisOfType(fractures);
|
||||
|
||||
for (RimFracture* fracture : fractures)
|
||||
if (changedField == &m_azimuthAngle && (fabs(oldValue.toDouble() - fracture->m_azimuth()) < 1e-5))
|
||||
{
|
||||
if (fracture->fractureTemplate() == this)
|
||||
{
|
||||
if (changedField == &m_azimuthAngle && (fabs(oldValue.toDouble() - fracture->m_azimuth()) < 1e-5))
|
||||
{
|
||||
fracture->m_azimuth = m_azimuthAngle;
|
||||
}
|
||||
fracture->m_azimuth = m_azimuthAngle;
|
||||
}
|
||||
|
||||
if (changedField == &m_orientationType)
|
||||
{
|
||||
if (newValue == AZIMUTH)
|
||||
{
|
||||
fracture->m_azimuth = m_azimuthAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
fracture->updateAzimuthBasedOnWellAzimuthAngle();
|
||||
}
|
||||
}
|
||||
if (changedField == &m_orientationType)
|
||||
{
|
||||
if (newValue == AZIMUTH)
|
||||
{
|
||||
fracture->m_azimuth = m_azimuthAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
fracture->updateAzimuthBasedOnWellAzimuthAngle();
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,33 +271,29 @@ void RimFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* changedFie
|
||||
|
||||
if (changedField == &m_perforationLength || changedField == &m_perforationEfficiency || changedField == &m_wellDiameter)
|
||||
{
|
||||
RimProject* proj;
|
||||
this->firstAncestorOrThisOfType(proj);
|
||||
if (!proj) return;
|
||||
std::vector<RimFracture*> fractures;
|
||||
proj->descendantsIncludingThisOfType(fractures);
|
||||
|
||||
for (RimFracture* fracture : fractures)
|
||||
for (RimFracture* fracture : fracturesUsingThisTemplate())
|
||||
{
|
||||
if (fracture->fractureTemplate() == this)
|
||||
if (changedField == &m_perforationLength && (fabs(oldValue.toDouble() - fracture->m_perforationLength()) < 1e-5))
|
||||
{
|
||||
if (changedField == &m_perforationLength && (fabs(oldValue.toDouble() - fracture->m_perforationLength()) < 1e-5))
|
||||
{
|
||||
fracture->m_perforationLength = m_perforationLength;
|
||||
}
|
||||
if (changedField == &m_perforationEfficiency &&
|
||||
(fabs(oldValue.toDouble() - fracture->m_perforationEfficiency()) < 1e-5))
|
||||
{
|
||||
fracture->m_perforationEfficiency = m_perforationEfficiency;
|
||||
}
|
||||
if (changedField == &m_wellDiameter && (fabs(oldValue.toDouble() - fracture->m_wellDiameter()) < 1e-5))
|
||||
{
|
||||
fracture->m_wellDiameter = m_wellDiameter;
|
||||
}
|
||||
fracture->m_perforationLength = m_perforationLength;
|
||||
}
|
||||
if (changedField == &m_perforationEfficiency &&
|
||||
(fabs(oldValue.toDouble() - fracture->m_perforationEfficiency()) < 1e-5))
|
||||
{
|
||||
fracture->m_perforationEfficiency = m_perforationEfficiency;
|
||||
}
|
||||
if (changedField == &m_wellDiameter && (fabs(oldValue.toDouble() - fracture->m_wellDiameter()) < 1e-5))
|
||||
{
|
||||
fracture->m_wellDiameter = m_wellDiameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (RimFracture* fracture : fracturesUsingThisTemplate())
|
||||
{
|
||||
fracture->clearCachedNonDarcyProperties();
|
||||
}
|
||||
|
||||
if (changedField == &m_perforationLength)
|
||||
{
|
||||
createDisplayModelAndRedraw = true;
|
||||
@ -370,7 +355,7 @@ void RimFractureTemplate::defineUiOrdering(QString uiConfigName, caf::PdmUiOrder
|
||||
|
||||
nonDarcyFlowGroup->add(&m_relativeGasDensity);
|
||||
nonDarcyFlowGroup->add(&m_gasViscosity);
|
||||
nonDarcyFlowGroup->add(&m_dFactorDisplayField);
|
||||
// nonDarcyFlowGroup->add(&m_dFactorDisplayField);
|
||||
|
||||
{
|
||||
auto group = nonDarcyFlowGroup->addNewGroup("D Factor Details");
|
||||
@ -434,16 +419,7 @@ QList<caf::PdmOptionItemInfo> RimFractureTemplate::calculateValueOptions(const c
|
||||
if (fieldNeedingOptions == &m_fractureWidthType)
|
||||
{
|
||||
options.push_back(caf::PdmOptionItemInfo(caf::AppEnum<WidthEnum>::uiText(USER_DEFINED_WIDTH), USER_DEFINED_WIDTH));
|
||||
|
||||
auto widthAndCond = widthAndConductivityAtWellPathIntersection();
|
||||
if (widthAndCond.isWidthAndPermeabilityDefined())
|
||||
{
|
||||
options.push_back(caf::PdmOptionItemInfo(caf::AppEnum<WidthEnum>::uiText(WIDTH_FROM_FRACTURE), WIDTH_FROM_FRACTURE));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fractureWidthType = USER_DEFINED_WIDTH;
|
||||
}
|
||||
options.push_back(caf::PdmOptionItemInfo(caf::AppEnum<WidthEnum>::uiText(WIDTH_FROM_FRACTURE), WIDTH_FROM_FRACTURE));
|
||||
}
|
||||
|
||||
return options;
|
||||
@ -499,20 +475,12 @@ void RimFractureTemplate::prepareFieldsForUiDisplay()
|
||||
|
||||
// Non Darcy Flow
|
||||
|
||||
auto values = widthAndConductivityAtWellPathIntersection();
|
||||
if (!values.isWidthAndPermeabilityDefined())
|
||||
{
|
||||
m_fractureWidthType = RimFractureTemplate::USER_DEFINED_WIDTH;
|
||||
}
|
||||
|
||||
if (m_fractureWidthType == RimFractureTemplate::USER_DEFINED_WIDTH)
|
||||
{
|
||||
m_fractureWidth.uiCapability()->setUiReadOnly(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fractureWidth = values.m_width;
|
||||
|
||||
m_fractureWidth.uiCapability()->setUiReadOnly(true);
|
||||
}
|
||||
|
||||
@ -528,6 +496,11 @@ void RimFractureTemplate::prepareFieldsForUiDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
QString indentedText(const QString& text)
|
||||
{
|
||||
return QString("<pre> %1</pre>").arg(text);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -535,37 +508,39 @@ QString RimFractureTemplate::dFactorSummary() const
|
||||
{
|
||||
QString text;
|
||||
|
||||
auto val = dFactor();
|
||||
text += QString("D-factor : %1").arg(val);
|
||||
auto fractures = fracturesUsingThisTemplate();
|
||||
for (auto f : fractures)
|
||||
{
|
||||
f->ensureValidNonDarcyProperties();
|
||||
|
||||
text += "<br>";
|
||||
text += "<br>";
|
||||
auto alpha = RiaDefines::nonDarcyFlowAlpha(m_fractureTemplateUnit());
|
||||
text += QString("α : %1").arg(alpha);
|
||||
text += QString("Fracture name : %1").arg(f->name());
|
||||
|
||||
text += "<br>";
|
||||
auto beta = m_inertialCoefficient;
|
||||
text += QString("β : %1").arg(beta);
|
||||
auto val = f->nonDarcyProperties().dFactor;
|
||||
text += indentedText(QString("D-factor : %1").arg(val));
|
||||
|
||||
text += "<br>";
|
||||
double effPerm = effectivePermeability();
|
||||
text += QString("Ke : %1").arg(effPerm);
|
||||
auto alpha = RiaDefines::nonDarcyFlowAlpha(m_fractureTemplateUnit());
|
||||
text += indentedText(QString("α : %1").arg(alpha));
|
||||
|
||||
text += "<br>";
|
||||
double gamma = m_relativeGasDensity;
|
||||
text += QString("γ : %1").arg(gamma);
|
||||
auto beta = m_inertialCoefficient;
|
||||
text += indentedText(QString("β : %1").arg(beta));
|
||||
|
||||
text += "<br>";
|
||||
auto h = fractureWidth();
|
||||
text += QString("h : %1").arg(h);
|
||||
double effPerm = f->nonDarcyProperties().effectivePermeability;
|
||||
text += indentedText(QString("Ke : %1").arg(effPerm));
|
||||
|
||||
text += "<br>";
|
||||
auto wellRadius = m_wellDiameter / 2.0;
|
||||
text += QString("rw : %1").arg(wellRadius);
|
||||
double gamma = m_relativeGasDensity;
|
||||
text += indentedText(QString("γ : %1").arg(gamma));
|
||||
|
||||
text += "<br>";
|
||||
auto mu = m_gasViscosity;
|
||||
text += QString("μ : %1").arg(mu);
|
||||
auto h = f->nonDarcyProperties().width;
|
||||
text += indentedText(QString("h : %1").arg(h));
|
||||
|
||||
auto wellRadius = m_wellDiameter / 2.0;
|
||||
text += indentedText(QString("rw : %1").arg(wellRadius));
|
||||
|
||||
auto mu = m_gasViscosity;
|
||||
text += indentedText(QString("μ : %1").arg(mu));
|
||||
|
||||
text += "<br>";
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
@ -573,7 +548,7 @@ QString RimFractureTemplate::dFactorSummary() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureTemplate::effectivePermeability() const
|
||||
double RimFractureTemplate::computeEffectivePermeability(const RimFracture* fractureInstance) const
|
||||
{
|
||||
if (m_permeabilityType() == RimFractureTemplate::USER_DEFINED_PERMEABILITY)
|
||||
{
|
||||
@ -582,7 +557,7 @@ double RimFractureTemplate::effectivePermeability() const
|
||||
else
|
||||
{
|
||||
double fracPermeability = 0.0;
|
||||
auto values = widthAndConductivityAtWellPathIntersection();
|
||||
auto values = widthAndConductivityAtWellPathIntersection(fractureInstance);
|
||||
if (values.isWidthAndPermeabilityDefined())
|
||||
{
|
||||
fracPermeability = values.m_permeability;
|
||||
@ -590,7 +565,7 @@ double RimFractureTemplate::effectivePermeability() const
|
||||
else
|
||||
{
|
||||
auto conductivity = values.m_conductivity;
|
||||
auto width = fractureWidth();
|
||||
auto width = computeFractureWidth(fractureInstance);
|
||||
|
||||
if (fabs(width) < 1e-10) return HUGE_VAL;
|
||||
|
||||
@ -604,7 +579,7 @@ double RimFractureTemplate::effectivePermeability() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureTemplate::dFactor() const
|
||||
double RimFractureTemplate::computeDFactor(const RimFracture* fractureInstance) const
|
||||
{
|
||||
double d;
|
||||
|
||||
@ -614,14 +589,26 @@ double RimFractureTemplate::dFactor() const
|
||||
}
|
||||
else
|
||||
{
|
||||
double radius = 0.0;
|
||||
|
||||
if (m_orientationType == ALONG_WELL_PATH && fractureInstance)
|
||||
{
|
||||
auto perforationLength = fractureInstance->perforationLength();
|
||||
|
||||
radius = perforationLength / cvf::PI_D;
|
||||
}
|
||||
else
|
||||
{
|
||||
radius = m_wellDiameter / 2.0;
|
||||
}
|
||||
|
||||
auto alpha = RiaDefines::nonDarcyFlowAlpha(m_fractureTemplateUnit());
|
||||
auto beta = m_inertialCoefficient;
|
||||
auto effPerm = effectivePermeability();
|
||||
auto effPerm = computeEffectivePermeability(fractureInstance);
|
||||
auto gamma = m_relativeGasDensity;
|
||||
|
||||
auto radius = m_wellDiameter / 2.0;
|
||||
auto mu = m_gasViscosity;
|
||||
auto h = fractureWidth();
|
||||
auto mu = m_gasViscosity;
|
||||
auto h = computeFractureWidth(fractureInstance);
|
||||
|
||||
double numerator = alpha * beta * effPerm * gamma;
|
||||
double denumerator = h * radius * mu;
|
||||
@ -629,6 +616,14 @@ double RimFractureTemplate::dFactor() const
|
||||
if (denumerator < 1e-10) return HUGE_VAL;
|
||||
|
||||
d = numerator / denumerator;
|
||||
|
||||
if (m_orientationType == ALONG_WELL_PATH)
|
||||
{
|
||||
// Correction for linear inflow into the well
|
||||
// Dlinear = cgeometric * Dradial
|
||||
// Dlinear = 1.2 * Dradial
|
||||
d *= 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
return d * m_dFactorScaleFactor;
|
||||
@ -637,19 +632,19 @@ double RimFractureTemplate::dFactor() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureTemplate::kh() const
|
||||
double RimFractureTemplate::computeKh(const RimFracture* fractureInstance) const
|
||||
{
|
||||
// kh = permeability * h
|
||||
// conductivity = permeability * h
|
||||
|
||||
auto values = widthAndConductivityAtWellPathIntersection();
|
||||
auto values = widthAndConductivityAtWellPathIntersection(fractureInstance);
|
||||
if (values.isConductivityDefined())
|
||||
{
|
||||
// If conductivity is found in stim plan file, use this directly
|
||||
return values.m_conductivity;
|
||||
}
|
||||
|
||||
return effectivePermeability() * fractureWidth();
|
||||
return computeEffectivePermeability(fractureInstance) * computeFractureWidth(fractureInstance);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -679,12 +674,8 @@ void RimFractureTemplate::disconnectAllFracturesAndRedrawViews() const
|
||||
// The unit has changed. Disconnect all fractures referencing this fracture template to avoid mix of units between fracture
|
||||
// and template
|
||||
|
||||
std::vector<caf::PdmObjectHandle*> referringObjects;
|
||||
this->objectsWithReferringPtrFields(referringObjects);
|
||||
|
||||
for (auto objHandle : referringObjects)
|
||||
for (auto fracture : fracturesUsingThisTemplate())
|
||||
{
|
||||
RimFracture* fracture = dynamic_cast<RimFracture*>(objHandle);
|
||||
if (fracture)
|
||||
{
|
||||
fracture->setFractureTemplate(nullptr);
|
||||
@ -716,6 +707,11 @@ void RimFractureTemplate::setScaleFactors(double widthScale, double heightScale,
|
||||
m_heightScaleFactor = heightScale;
|
||||
m_dFactorScaleFactor = dFactorScale;
|
||||
m_conductivityScaleFactor = conductivityScale;
|
||||
|
||||
for (RimFracture* fracture : fracturesUsingThisTemplate())
|
||||
{
|
||||
fracture->clearCachedNonDarcyProperties();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -753,11 +749,11 @@ void RimFractureTemplate::setContainmentBaseKLayer(int baseKLayer)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureTemplate::fractureWidth() const
|
||||
double RimFractureTemplate::computeFractureWidth(const RimFracture* fractureInstance) const
|
||||
{
|
||||
if (m_fractureWidthType == RimFractureTemplate::WIDTH_FROM_FRACTURE)
|
||||
{
|
||||
auto values = widthAndConductivityAtWellPathIntersection();
|
||||
auto values = widthAndConductivityAtWellPathIntersection(fractureInstance);
|
||||
|
||||
return values.m_width;
|
||||
}
|
||||
@ -765,6 +761,27 @@ double RimFractureTemplate::fractureWidth() const
|
||||
return m_fractureWidth;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimFracture*> RimFractureTemplate::fracturesUsingThisTemplate() const
|
||||
{
|
||||
std::vector<RimFracture*> fractures;
|
||||
|
||||
std::vector<caf::PdmObjectHandle*> objects;
|
||||
this->objectsWithReferringPtrFields(objects);
|
||||
for (auto object : objects)
|
||||
{
|
||||
auto f = dynamic_cast<RimFracture*>(object);
|
||||
if (f)
|
||||
{
|
||||
fractures.push_back(f);
|
||||
}
|
||||
}
|
||||
|
||||
return fractures;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -38,6 +38,7 @@ class RigFractureGrid;
|
||||
class RimFractureContainment;
|
||||
class MinMaxAccumulator;
|
||||
class PosNegAccumulator;
|
||||
class RimFracture;
|
||||
|
||||
class FractureWidthAndConductivity
|
||||
{
|
||||
@ -146,8 +147,6 @@ public:
|
||||
void setDefaultWellDiameterFromUnit();
|
||||
|
||||
bool isNonDarcyFlowEnabled() const;
|
||||
double dFactor() const;
|
||||
double kh() const;
|
||||
|
||||
virtual void convertToUnitSystem(RiaEclipseUnitTools::UnitSystem neededUnit);
|
||||
|
||||
@ -162,6 +161,11 @@ public:
|
||||
void setContainmentTopKLayer(int topKLayer);
|
||||
void setContainmentBaseKLayer(int baseKLayer);
|
||||
|
||||
double computeDFactor(const RimFracture* fractureInstance) const;
|
||||
double computeKh(const RimFracture* fractureInstance) const;
|
||||
double computeEffectivePermeability(const RimFracture* fractureInstance) const;
|
||||
double computeFractureWidth(const RimFracture* fractureInstance) const;
|
||||
|
||||
protected:
|
||||
virtual caf::PdmFieldHandle* userDescriptionField() override;
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
@ -169,14 +173,13 @@ protected:
|
||||
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override;
|
||||
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
|
||||
|
||||
std::vector<RimFracture*> fracturesUsingThisTemplate() const;
|
||||
|
||||
private:
|
||||
void prepareFieldsForUiDisplay();
|
||||
virtual FractureWidthAndConductivity widthAndConductivityAtWellPathIntersection() const = 0;
|
||||
virtual FractureWidthAndConductivity widthAndConductivityAtWellPathIntersection(const RimFracture* fractureInstance) const = 0;
|
||||
|
||||
QString dFactorSummary() const;
|
||||
double effectivePermeability() const;
|
||||
|
||||
double fractureWidth() const;
|
||||
|
||||
protected:
|
||||
caf::PdmField<int> m_id;
|
||||
@ -206,7 +209,7 @@ protected:
|
||||
caf::PdmField<double> m_relativeGasDensity;
|
||||
caf::PdmField<double> m_gasViscosity;
|
||||
|
||||
caf::PdmProxyValueField<double> m_dFactorDisplayField;
|
||||
//caf::PdmProxyValueField<double> m_dFactorDisplayField;
|
||||
caf::PdmProxyValueField<QString> m_dFactorSummaryText;
|
||||
|
||||
caf::PdmField<double> m_heightScaleFactor;
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "RigFractureGrid.h"
|
||||
#include "RigStimPlanFractureDefinition.h"
|
||||
#include "RigWellPathStimplanIntersector.h"
|
||||
|
||||
#include "RigFractureCell.h"
|
||||
#include "RimEclipseView.h"
|
||||
@ -42,6 +43,7 @@
|
||||
#include "cafPdmUiDoubleSliderEditor.h"
|
||||
#include "cafPdmUiFilePathEditor.h"
|
||||
|
||||
#include "cvfMath.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
@ -279,6 +281,11 @@ void RimStimPlanFractureTemplate::loadDataAndUpdate()
|
||||
|
||||
updateFractureGrid();
|
||||
|
||||
for (RimFracture* fracture : fracturesUsingThisTemplate())
|
||||
{
|
||||
fracture->clearCachedNonDarcyProperties();
|
||||
}
|
||||
|
||||
// Todo: Must update all views using this fracture template
|
||||
RimEclipseView* activeView = dynamic_cast<RimEclipseView*>(RiaApplication::instance()->activeReservoirView());
|
||||
if (activeView) activeView->fractureColors()->loadDataAndUpdate();
|
||||
@ -405,47 +412,134 @@ QString RimStimPlanFractureTemplate::getUnitForStimPlanParameter(QString paramet
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
FractureWidthAndConductivity RimStimPlanFractureTemplate::widthAndConductivityAtWellPathIntersection() const
|
||||
std::vector<double>
|
||||
RimStimPlanFractureTemplate::fractureGridResultsForUnitSystem(const QString& resultName,
|
||||
const QString& unitName,
|
||||
size_t timeStepIndex,
|
||||
RiaEclipseUnitTools::UnitSystem requiredUnitSystem) const
|
||||
{
|
||||
auto resultValues = m_stimPlanFractureDefinitionData->fractureGridResults(resultName, unitName, m_activeTimeStepIndex);
|
||||
|
||||
if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_METRIC)
|
||||
{
|
||||
for (auto& v : resultValues)
|
||||
{
|
||||
v = RiaEclipseUnitTools::convertToMeter(v, unitName);
|
||||
}
|
||||
}
|
||||
else if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_FIELD)
|
||||
{
|
||||
for (auto& v : resultValues)
|
||||
{
|
||||
v = RiaEclipseUnitTools::convertToFeet(v, unitName);
|
||||
}
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
FractureWidthAndConductivity
|
||||
RimStimPlanFractureTemplate::widthAndConductivityAtWellPathIntersection(const RimFracture* fractureInstance) const
|
||||
{
|
||||
FractureWidthAndConductivity values;
|
||||
|
||||
if (m_fractureGrid.notNull())
|
||||
{
|
||||
std::pair<size_t, size_t> wellCellIJ = m_fractureGrid->fractureCellAtWellCenter();
|
||||
size_t wellCellIndex = m_fractureGrid->getGlobalIndexFromIJ(wellCellIJ.first, wellCellIJ.second);
|
||||
const RigFractureCell& wellCell = m_fractureGrid->cellFromIndex(wellCellIndex);
|
||||
|
||||
double conductivity = wellCell.getConductivityValue();
|
||||
values.m_conductivity = conductivity;
|
||||
|
||||
auto nameUnit = widthParameterNameAndUnit();
|
||||
if (!nameUnit.first.isEmpty())
|
||||
if (orientationType() == ALONG_WELL_PATH)
|
||||
{
|
||||
double widthInRequiredUnit = HUGE_VAL;
|
||||
CVF_ASSERT(fractureInstance);
|
||||
|
||||
RimWellPath* rimWellPath = nullptr;
|
||||
fractureInstance->firstAncestorOrThisOfType(rimWellPath);
|
||||
|
||||
if (rimWellPath && rimWellPath->wellPathGeometry())
|
||||
{
|
||||
auto resultValues =
|
||||
m_stimPlanFractureDefinitionData->fractureGridResults(nameUnit.first, nameUnit.second, m_activeTimeStepIndex);
|
||||
RigWellPathStimplanIntersector intersector(rimWellPath->wellPathGeometry(), fractureInstance);
|
||||
|
||||
double widthInFileUnitSystem = resultValues[wellCellIndex];
|
||||
|
||||
if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_METRIC)
|
||||
double totalLength = 0.0;
|
||||
for (const auto& v : intersector.intersections())
|
||||
{
|
||||
QString unitText = nameUnit.second;
|
||||
|
||||
widthInRequiredUnit = RiaEclipseUnitTools::convertToMeter(widthInFileUnitSystem, unitText);
|
||||
totalLength += v.second.computeLength();
|
||||
}
|
||||
else if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_FIELD)
|
||||
{
|
||||
QString unitText = nameUnit.second;
|
||||
|
||||
widthInRequiredUnit = RiaEclipseUnitTools::convertToFeet(widthInFileUnitSystem, unitText);
|
||||
std::vector<double> widthResultValues;
|
||||
{
|
||||
auto nameUnit = widthParameterNameAndUnit();
|
||||
widthResultValues = fractureGridResultsForUnitSystem(
|
||||
nameUnit.first, nameUnit.second, m_activeTimeStepIndex, fractureTemplateUnit());
|
||||
}
|
||||
|
||||
std::vector<double> conductivityResultValues;
|
||||
{
|
||||
auto nameUnit = conductivityParameterNameAndUnit();
|
||||
conductivityResultValues = fractureGridResultsForUnitSystem(
|
||||
nameUnit.first, nameUnit.second, m_activeTimeStepIndex, fractureTemplateUnit());
|
||||
}
|
||||
|
||||
double weightedConductivity = 0.0;
|
||||
double weightedWidth = 0.0;
|
||||
|
||||
for (const auto& v : intersector.intersections())
|
||||
{
|
||||
size_t fractureGlobalCellIndex = v.first;
|
||||
|
||||
if (fractureGlobalCellIndex < widthResultValues.size())
|
||||
{
|
||||
weightedWidth += widthResultValues[fractureGlobalCellIndex] * v.second.computeLength();
|
||||
}
|
||||
|
||||
if (fractureGlobalCellIndex < conductivityResultValues.size())
|
||||
{
|
||||
weightedConductivity += conductivityResultValues[fractureGlobalCellIndex] * v.second.computeLength();
|
||||
}
|
||||
}
|
||||
|
||||
if (totalLength > 1e-7)
|
||||
{
|
||||
weightedWidth /= totalLength;
|
||||
weightedConductivity /= totalLength;
|
||||
|
||||
values.m_width = weightedWidth;
|
||||
values.m_conductivity = weightedConductivity;
|
||||
}
|
||||
|
||||
if (weightedWidth > 1e-7)
|
||||
{
|
||||
values.m_permeability = weightedConductivity / weightedWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::pair<size_t, size_t> wellCellIJ = m_fractureGrid->fractureCellAtWellCenter();
|
||||
size_t wellCellIndex = m_fractureGrid->getGlobalIndexFromIJ(wellCellIJ.first, wellCellIJ.second);
|
||||
const RigFractureCell& wellCell = m_fractureGrid->cellFromIndex(wellCellIndex);
|
||||
|
||||
if (widthInRequiredUnit != HUGE_VAL && fabs(widthInRequiredUnit) > 1e-20)
|
||||
double conductivity = wellCell.getConductivityValue();
|
||||
values.m_conductivity = conductivity;
|
||||
|
||||
auto nameUnit = widthParameterNameAndUnit();
|
||||
if (!nameUnit.first.isEmpty())
|
||||
{
|
||||
values.m_width = widthInRequiredUnit;
|
||||
values.m_permeability = conductivity / widthInRequiredUnit;
|
||||
double widthInRequiredUnit = HUGE_VAL;
|
||||
{
|
||||
auto resultValues = fractureGridResultsForUnitSystem(
|
||||
nameUnit.first, nameUnit.second, m_activeTimeStepIndex, fractureTemplateUnit());
|
||||
|
||||
if (wellCellIndex < resultValues.size())
|
||||
{
|
||||
widthInRequiredUnit = resultValues[wellCellIndex];
|
||||
}
|
||||
}
|
||||
|
||||
if (widthInRequiredUnit != HUGE_VAL && fabs(widthInRequiredUnit) > 1e-20)
|
||||
{
|
||||
values.m_width = widthInRequiredUnit;
|
||||
values.m_permeability = conductivity / widthInRequiredUnit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -480,6 +574,28 @@ std::pair<QString, QString> RimStimPlanFractureTemplate::widthParameterNameAndUn
|
||||
return std::pair<QString, QString>();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<QString, QString> RimStimPlanFractureTemplate::conductivityParameterNameAndUnit() const
|
||||
{
|
||||
if (m_stimPlanFractureDefinitionData.notNull())
|
||||
{
|
||||
std::vector<std::pair<QString, QString>> propertyNamesUnitsOnFile =
|
||||
m_stimPlanFractureDefinitionData->getStimPlanPropertyNamesUnits();
|
||||
|
||||
for (const auto& nameUnit : propertyNamesUnitsOnFile)
|
||||
{
|
||||
if (nameUnit.first.contains(m_conductivityResultNameOnFile, Qt::CaseInsensitive))
|
||||
{
|
||||
return nameUnit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::pair<QString, QString>();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -786,8 +902,8 @@ void RimStimPlanFractureTemplate::updateFractureGrid()
|
||||
auto nameUnit = widthParameterNameAndUnit();
|
||||
if (!nameUnit.first.isEmpty())
|
||||
{
|
||||
auto resultValues =
|
||||
m_stimPlanFractureDefinitionData->fractureGridResults(nameUnit.first, nameUnit.second, m_activeTimeStepIndex);
|
||||
auto resultValues = fractureGridResultsForUnitSystem(
|
||||
nameUnit.first, nameUnit.second, m_activeTimeStepIndex, fractureTemplateUnit());
|
||||
|
||||
for (size_t i = 0; i < areaPerCell.size(); i++)
|
||||
{
|
||||
|
@ -109,10 +109,12 @@ private:
|
||||
void computePerforationLength();
|
||||
QString getUnitForStimPlanParameter(QString parameterName);
|
||||
|
||||
std::vector<double> fractureGridResultsForUnitSystem(const QString& resultName, const QString& unitName, size_t timeStepIndex, RiaEclipseUnitTools::UnitSystem requiredUnitSystem) const;
|
||||
|
||||
virtual FractureWidthAndConductivity widthAndConductivityAtWellPathIntersection() const override;
|
||||
virtual FractureWidthAndConductivity widthAndConductivityAtWellPathIntersection(const RimFracture* fractureInstance) const override;
|
||||
|
||||
std::pair<QString, QString> widthParameterNameAndUnit() const;
|
||||
std::pair<QString, QString> conductivityParameterNameAndUnit() const;
|
||||
|
||||
private:
|
||||
caf::PdmField<int> m_activeTimeStepIndex;
|
||||
|
@ -41,6 +41,11 @@ public:
|
||||
double hlength;
|
||||
double vlength;
|
||||
int endpointCount;
|
||||
|
||||
double computeLength() const
|
||||
{
|
||||
return cvf::Math::sqrt(hlength * hlength + vlength * vlength);
|
||||
}
|
||||
};
|
||||
|
||||
RigWellPathStimplanIntersector(const RigWellPath* wellpathGeom, const RimFracture* rimFracture);
|
||||
|
Loading…
Reference in New Issue
Block a user