#2455 Non-Darcy Flow : Compute D-factor and show in UI

This commit is contained in:
Magne Sjaastad 2018-02-14 13:35:35 +01:00
parent f9bded9c13
commit 8e1a7b2bbb
8 changed files with 281 additions and 20 deletions

View File

@ -38,3 +38,16 @@ QString RiaDefines::unitStringConductivity(RiaEclipseUnitTools::UnitSystem unitS
default: return "";
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaDefines::nonDarcyFlowAlpha(RiaEclipseUnitTools::UnitSystem unitSystem)
{
switch (unitSystem)
{
case RiaEclipseUnitTools::UNITS_METRIC: return 2.24460e-10;
case RiaEclipseUnitTools::UNITS_FIELD: return 6.83352e-8;
default: return 0.0;
}
}

View File

@ -26,4 +26,6 @@ namespace RiaDefines
{
QString conductivityResultName();
QString unitStringConductivity(RiaEclipseUnitTools::UnitSystem unitSystem);
double nonDarcyFlowAlpha(RiaEclipseUnitTools::UnitSystem unitSystem);
};

View File

@ -270,6 +270,18 @@ void RimEllipseFractureTemplate::setupFractureGridCells()
m_fractureGrid->setJCellCount(numberOfCellsY);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
FractureWidthAndConductivity RimEllipseFractureTemplate::widthAndConductivityAtWellPathIntersection() const
{
FractureWidthAndConductivity values;
values.m_width = m_width;
values.m_permeability = m_permeability;
return values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -73,6 +73,9 @@ protected:
private:
void setupFractureGridCells();
virtual FractureWidthAndConductivity widthAndConductivityAtWellPathIntersection() const override;
private:
cvf::ref<RigFractureGrid> m_fractureGrid;

View File

@ -18,6 +18,7 @@
#include "RimFractureTemplate.h"
#include "RiaFractureDefines.h"
#include "RigTesselatorTools.h"
#include "RimFracture.h"
@ -26,6 +27,7 @@
#include "cafPdmObject.h"
#include "cafPdmUiDoubleSliderEditor.h"
#include "cafPdmUiTextEditor.h"
#include "cvfVector3.h"
@ -52,6 +54,15 @@ namespace caf
setDefault(RimFractureTemplate::INFINITE_CONDUCTIVITY);
}
template<>
void caf::AppEnum< RimFractureTemplate::EffectivePermeabilityEnum>::setUp()
{
addItem(RimFractureTemplate::USER_DEFINED_PERMEABILITY, "UserDefinedPermeability", "User Defined");
addItem(RimFractureTemplate::CONDUCTIVITY_FROM_FRACTURE, "FractureConductivity", "Use Fracture Conductivity");
setDefault(RimFractureTemplate::CONDUCTIVITY_FROM_FRACTURE);
}
}
@ -90,11 +101,24 @@ RimFractureTemplate::RimFractureTemplate()
// Non-Darcy Flow options
CAF_PDM_InitField_Basic(&m_useNonDarcyFlow, "UseNonDarcyFlow", false, "Use Non-Darcy Flow");
CAF_PDM_InitField_Basic(&m_fractureWidth, "FractureWidth", 0.0, "Fracture Width");
CAF_PDM_InitField_Basic(&m_inertialCoefficient, "InertialCoefficient", 0.0, "Inertial Coefficient (beta)");
CAF_PDM_InitField_Basic(&m_effectivePermeability, "EffectivePermeability",0.0, "Effective Permeability");
CAF_PDM_InitField_Basic(&m_specificGasGravity, "SpecificGasGravity", 0.0, "Specific Gas Gravity");
CAF_PDM_InitField_Basic(&m_gasViscosity, "GasViscosity", 0.0, "Gas Viscosity");
CAF_PDM_InitField_Basic(&m_inertialCoefficient, "InertialCoefficient", 0.006083236, "Inertial Coefficient");
CAF_PDM_InitFieldNoDefault(&m_permeabilityType, "PermeabilityType", "Type", "", "", "");
CAF_PDM_InitField_Basic(&m_permeabilityScaleFactor,"EffectivePermeabilityScaleFactor", 1.0, "Scale Factor [0..1]");
CAF_PDM_InitField(&m_permeability, "EffectivePermeability", 0.0, "Effective Permeability", "", "", "");
CAF_PDM_InitField(&m_relativeGasDensity, "RelativeGasDensity", 0.8, "Relative Gas Density", "", "Relative density of gas at surface conditions with respect to air at STP", "");
CAF_PDM_InitField(&m_gasViscosity, "GasViscosity", 0.02, "Gas Viscosity", "", "Gas viscosity at bottom hole pressure", "");
CAF_PDM_InitFieldNoDefault(&m_dFactorDisplayField, "dFactorDisplayField", "D Factor", "", "", "");
m_dFactorDisplayField.registerGetMethod(this, &RimFractureTemplate::computeDFactor);
m_dFactorDisplayField.uiCapability()->setUiReadOnly(true);
CAF_PDM_InitFieldNoDefault(&m_dFactorSummaryText, "dFactorSummaryText", "D Factor Summary", "", "", "");
m_dFactorSummaryText.registerGetMethod(this, &RimFractureTemplate::dFactorSummary);
m_dFactorSummaryText.uiCapability()->setUiReadOnly(true);
m_dFactorSummaryText.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName());
m_dFactorSummaryText.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::LabelPosType::TOP);
}
//--------------------------------------------------------------------------------------------------
@ -241,11 +265,24 @@ void RimFractureTemplate::defineUiOrdering(QString uiConfigName, caf::PdmUiOrder
auto group = uiOrdering.addNewGroup("Non-Darcy Flow");
group->setCollapsedByDefault(true);
group->add(&m_useNonDarcyFlow);
group->add(&m_fractureWidth);
group->add(&m_inertialCoefficient);
group->add(&m_effectivePermeability);
group->add(&m_specificGasGravity);
{
auto permGroup = group->addNewGroup("Effective Permeability");
permGroup->add(&m_permeabilityType);
permGroup->add(&m_permeabilityScaleFactor);
permGroup->add(&m_permeability);
}
group->add(&m_relativeGasDensity);
group->add(&m_gasViscosity);
group->add(&m_dFactorDisplayField);
{
auto dFactorGroup = group->addNewGroup("D Factor Details");
dFactorGroup->setCollapsedByDefault(true);
dFactorGroup->add(&m_dFactorSummaryText);
}
uiOrdering.add(&m_fractureTemplateUnit);
}
@ -264,8 +301,20 @@ void RimFractureTemplate::defineEditorAttribute(const caf::PdmFieldHandle* field
myAttr->m_maximum = 1.0;
}
}
}
if (field == &m_dFactorSummaryText)
{
auto myAttr = dynamic_cast<caf::PdmUiTextEditorAttribute*>(attribute);
if (myAttr)
{
myAttr->wrapMode = caf::PdmUiTextEditorAttribute::NoWrap;
QFont font("Monospace", 10);
myAttr->font = font;
myAttr->textMode = caf::PdmUiTextEditorAttribute::HTML;
}
}
}
//--------------------------------------------------------------------------------------------------
///
@ -314,19 +363,127 @@ void RimFractureTemplate::prepareFieldsForUiDisplay()
}
// Non Darcy Flow
m_fractureWidth.uiCapability()->setUiReadOnly(!m_useNonDarcyFlow);
m_inertialCoefficient.uiCapability()->setUiReadOnly(!m_useNonDarcyFlow);
m_effectivePermeability.uiCapability()->setUiReadOnly(!m_useNonDarcyFlow);
m_specificGasGravity.uiCapability()->setUiReadOnly(!m_useNonDarcyFlow);
m_permeabilityType.uiCapability()->setUiReadOnly(!m_useNonDarcyFlow);
m_permeabilityScaleFactor.uiCapability()->setUiReadOnly(!m_useNonDarcyFlow);
m_permeability.uiCapability()->setUiReadOnly(!m_useNonDarcyFlow);
m_relativeGasDensity.uiCapability()->setUiReadOnly(!m_useNonDarcyFlow);
m_gasViscosity.uiCapability()->setUiReadOnly(!m_useNonDarcyFlow);
if (m_orientationType == RimFractureTemplate::ALONG_WELL_PATH)
if (m_useNonDarcyFlow)
{
m_fractureWidth.uiCapability()->setUiHidden(true);
if (m_permeabilityType == RimFractureTemplate::USER_DEFINED_PERMEABILITY)
{
m_permeabilityScaleFactor.uiCapability()->setUiHidden(true);
m_permeability.uiCapability()->setUiReadOnly(false);
}
else
{
m_permeabilityScaleFactor.uiCapability()->setUiHidden(false);
m_permeability.uiCapability()->setUiHidden(true);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFractureTemplate::dFactorSummary() const
{
QString text;
auto dFactor = computeDFactor();
text += QString("D-factor : %1").arg(dFactor);
text += "<br>";
text += "<br>";
auto alpha = RiaDefines::nonDarcyFlowAlpha(m_fractureTemplateUnit());
text += QString("&alpha; : %1").arg(alpha);
text += "<br>";
auto beta = m_inertialCoefficient;
text += QString("&beta; : %1").arg(beta);
text += "<br>";
double effPerm = effectivePermeability();
text += QString("Ke : %1").arg(effPerm);
text += "<br>";
double gamma = m_relativeGasDensity;
text += QString("&gamma; : %1").arg(gamma);
text += "<br>";
auto h = nonDarcyH();
text += QString("h : %1").arg(h);
text += "<br>";
auto wellRadius = m_wellDiameter / 2.0;
text += QString("rw : %1").arg(wellRadius);
text += "<br>";
auto mu = m_gasViscosity;
text += QString("&mu; : %1").arg(mu);
return text;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFractureTemplate::effectivePermeability() const
{
if (m_permeabilityType() == RimFractureTemplate::USER_DEFINED_PERMEABILITY)
{
return m_permeability;
}
else
{
m_fractureWidth.uiCapability()->setUiHidden(false);
auto values = widthAndConductivityAtWellPathIntersection();
auto fracPermeability = values.m_permeability;
return fracPermeability * m_permeabilityScaleFactor;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFractureTemplate::computeDFactor() const
{
auto alpha = RiaDefines::nonDarcyFlowAlpha(m_fractureTemplateUnit());
auto beta = m_inertialCoefficient;
auto effPerm = effectivePermeability();
auto gamma = m_relativeGasDensity;
auto radius = m_wellDiameter / 2.0;
auto mu = m_gasViscosity;
auto h = nonDarcyH();
double numerator = alpha * beta * effPerm * gamma;
double denumerator = h * radius * mu;
if (denumerator < 1e-10) return HUGE_VAL;
return numerator / denumerator;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFractureTemplate::nonDarcyH() const
{
if (m_orientationType() == RimFractureTemplate::ALONG_WELL_PATH)
{
return m_perforationLength();
}
else
{
auto values = widthAndConductivityAtWellPathIntersection();
return values.m_width;
}
}

View File

@ -21,11 +21,12 @@
#include "RiaEclipseUnitTools.h"
#include "cafAppEnum.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include "cafPdmFieldCvfVec3d.h"
#include "cafPdmFieldHandle.h"
#include "cafPdmObject.h"
#include "cafPdmChildField.h"
#include "cafPdmFieldCvfVec3d.h"
#include "cafPdmProxyValueField.h"
#include "cvfBase.h"
#include "cvfVector3.h"
@ -37,6 +38,19 @@ class RimFractureContainment;
class MinMaxAccumulator;
class PosNegAccumulator;
class FractureWidthAndConductivity
{
public:
FractureWidthAndConductivity()
: m_width(0.0)
, m_permeability(0.0)
{
}
double m_width;
double m_permeability;
};
//==================================================================================================
///
///
@ -59,6 +73,12 @@ public:
FINITE_CONDUCTIVITY,
};
enum EffectivePermeabilityEnum
{
USER_DEFINED_PERMEABILITY,
CONDUCTIVITY_FROM_FRACTURE,
};
public:
RimFractureTemplate();
virtual ~RimFractureTemplate();
@ -99,6 +119,14 @@ protected:
private:
void prepareFieldsForUiDisplay();
virtual FractureWidthAndConductivity widthAndConductivityAtWellPathIntersection() const = 0;
QString dFactorSummary() const;
double effectivePermeability() const;
double computeDFactor() const;
double nonDarcyH() const;
protected:
caf::PdmField<QString> m_name;
@ -113,9 +141,16 @@ protected:
caf::PdmChildField<RimFractureContainment*> m_fractureContainment;
caf::PdmField<bool> m_useNonDarcyFlow;
caf::PdmField<double> m_fractureWidth;
caf::PdmField<double> m_inertialCoefficient;
caf::PdmField<double> m_effectivePermeability;
caf::PdmField<double> m_specificGasGravity;
caf::PdmField<caf::AppEnum<EffectivePermeabilityEnum>>
m_permeabilityType;
caf::PdmField<double> m_permeabilityScaleFactor;
caf::PdmField<double> m_permeability;
caf::PdmField<double> m_relativeGasDensity;
caf::PdmField<double> m_gasViscosity;
caf::PdmProxyValueField<double> m_dFactorDisplayField;
caf::PdmProxyValueField<QString> m_dFactorSummaryText;
};

View File

@ -402,6 +402,42 @@ QString RimStimPlanFractureTemplate::getUnitForStimPlanParameter(QString paramet
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
FractureWidthAndConductivity RimStimPlanFractureTemplate::widthAndConductivityAtWellPathIntersection() 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.getConductivtyValue();
std::vector<std::pair<QString, QString> > propertyNamesUnitsOnFile = m_stimPlanFractureDefinitionData->getStimPlanPropertyNamesUnits();
for (const auto& nameUnit : propertyNamesUnitsOnFile)
{
if (nameUnit.first.contains("Width", Qt::CaseInsensitive))
{
auto data = m_stimPlanFractureDefinitionData->fractureGridResults(nameUnit.first, nameUnit.second, m_activeTimeStepIndex);
double width = data[wellCellIndex];
if (fabs(width) > 1e-7)
{
values.m_width = width;
values.m_permeability = conductivity / width;
}
}
}
}
return values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -104,6 +104,9 @@ private:
void setPerforationLength();
QString getUnitForStimPlanParameter(QString parameterName);
virtual FractureWidthAndConductivity widthAndConductivityAtWellPathIntersection() const override;
private:
caf::PdmField<int> m_activeTimeStepIndex;
caf::PdmField<QString> m_conductivityResultNameOnFile;