mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-05 21:53:27 -06:00
Merge pull request #6372 from OPM/stimplan-detailed-fluid-loss-6364
Stimplan detailed fluid loss 6364
This commit is contained in:
commit
100c1b9e14
@ -41,6 +41,16 @@ void AppEnum<RiaDefines::CurveProperty>::setUp()
|
||||
addItem( RiaDefines::CurveProperty::K0, "K0", "k0" );
|
||||
addItem( RiaDefines::CurveProperty::FLUID_LOSS_COEFFICIENT, "FLUID_LOSS_COEFFICIENT", "Fluid Loss Coefficient" );
|
||||
addItem( RiaDefines::CurveProperty::SPURT_LOSS, "SPURT_LOSS", "Spurt Loss" );
|
||||
addItem( RiaDefines::CurveProperty::TEMPERATURE, "TEMPERATURE", "Temperature" );
|
||||
addItem( RiaDefines::CurveProperty::RELATIVE_PERMEABILITY_FACTOR,
|
||||
"RELATIVE_PERMEABILITY_FACTOR",
|
||||
"Relative Permeability Factor" );
|
||||
addItem( RiaDefines::CurveProperty::PORO_ELASTIC_CONSTANT, "PORO_ELASTIC_CONSTANT", "Poro-Elastic Constant" );
|
||||
addItem( RiaDefines::CurveProperty::THERMAL_EXPANSION_COEFFICIENT,
|
||||
"THERMAL_EXPANSION_COEFFICIENT",
|
||||
"Thermal Expansion Coefficient" );
|
||||
addItem( RiaDefines::CurveProperty::IMMOBILE_FLUID_SATURATION, "IMMOBILE_FLUID_SATURATION", "Immobile Fluid Saturation" );
|
||||
|
||||
setDefault( RiaDefines::CurveProperty::UNDEFINED );
|
||||
}
|
||||
}; // namespace caf
|
||||
|
@ -43,6 +43,11 @@ enum class CurveProperty
|
||||
BIOT_COEFFICIENT,
|
||||
K0,
|
||||
FLUID_LOSS_COEFFICIENT,
|
||||
SPURT_LOSS
|
||||
SPURT_LOSS,
|
||||
TEMPERATURE,
|
||||
RELATIVE_PERMEABILITY_FACTOR,
|
||||
PORO_ELASTIC_CONSTANT,
|
||||
THERMAL_EXPANSION_COEFFICIENT,
|
||||
IMMOBILE_FLUID_SATURATION,
|
||||
};
|
||||
}; // namespace RiaDefines
|
||||
|
@ -140,7 +140,11 @@ RimFractureModelPlot*
|
||||
RiaDefines::CurveProperty::BIOT_COEFFICIENT,
|
||||
RiaDefines::CurveProperty::K0,
|
||||
RiaDefines::CurveProperty::FLUID_LOSS_COEFFICIENT,
|
||||
RiaDefines::CurveProperty::SPURT_LOSS};
|
||||
RiaDefines::CurveProperty::SPURT_LOSS,
|
||||
RiaDefines::CurveProperty::RELATIVE_PERMEABILITY_FACTOR,
|
||||
RiaDefines::CurveProperty::PORO_ELASTIC_CONSTANT,
|
||||
RiaDefines::CurveProperty::THERMAL_EXPANSION_COEFFICIENT,
|
||||
RiaDefines::CurveProperty::IMMOBILE_FLUID_SATURATION};
|
||||
|
||||
for ( auto result : results )
|
||||
{
|
||||
@ -152,6 +156,7 @@ RimFractureModelPlot*
|
||||
auto task = progInfo.task( "Creating stress track", 2 );
|
||||
createStressTrack( plot, fractureModel, eclipseCase, timeStep, RiaDefines::CurveProperty::STRESS );
|
||||
createStressTrack( plot, fractureModel, eclipseCase, timeStep, RiaDefines::CurveProperty::STRESS_GRADIENT );
|
||||
createStressTrack( plot, fractureModel, eclipseCase, timeStep, RiaDefines::CurveProperty::TEMPERATURE );
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -96,7 +96,8 @@ void RicElasticPropertiesImportTools::importElasticPropertiesFromFile( const QSt
|
||||
item.biotCoefficient,
|
||||
item.k0,
|
||||
item.fluidLossCoefficient,
|
||||
item.spurtLoss );
|
||||
item.spurtLoss,
|
||||
item.immobileFluidSaturation );
|
||||
}
|
||||
|
||||
rimElasticProperties->setPropertiesForFacies( key, rigElasticProperties );
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "RiaApplication.h"
|
||||
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelPlot.h"
|
||||
|
||||
#include "RifFractureModelPlotExporter.h"
|
||||
@ -61,7 +62,9 @@ void RicExportFractureModelPlotToFileFeature::onActionTriggered( bool isChecked
|
||||
|
||||
if ( fileName.isEmpty() ) return;
|
||||
|
||||
RifFractureModelPlotExporter::writeToFile( fractureModelPlot, fileName );
|
||||
RifFractureModelPlotExporter::writeToFile( fractureModelPlot,
|
||||
fractureModelPlot->fractureModel()->useDetailedFluidLoss(),
|
||||
fileName );
|
||||
|
||||
// Remember the path to next time
|
||||
app->setLastUsedDialogDirectory( "FRACTURE_MODEL_PLOT", QFileInfo( fileName ).absolutePath() );
|
||||
|
@ -79,7 +79,7 @@ RifElasticProperties
|
||||
{
|
||||
QStringList tokens = tokenize( line, "," );
|
||||
|
||||
if ( tokens.size() != 12 )
|
||||
if ( tokens.size() != 13 )
|
||||
{
|
||||
throw FileParseException( QString( "Incomplete data on line %1: %2" ).arg( lineNumber ).arg( filePath ) );
|
||||
}
|
||||
@ -97,7 +97,8 @@ RifElasticProperties
|
||||
<< "Biot Coefficient"
|
||||
<< "k0"
|
||||
<< "Fluid Loss Coefficient"
|
||||
<< "Spurt Loss";
|
||||
<< "Spurt Loss"
|
||||
<< "Immobile Fluid Saturation";
|
||||
verifyNonEmptyTokens( tokens, nameOfNonEmptyTokens, lineNumber, filePath );
|
||||
|
||||
RifElasticProperties elasticProperties;
|
||||
@ -113,6 +114,8 @@ RifElasticProperties
|
||||
elasticProperties.k0 = parseDouble( tokens[9], "k0", lineNumber, filePath );
|
||||
elasticProperties.fluidLossCoefficient = parseDouble( tokens[10], "Fluid Loss Coefficient", lineNumber, filePath );
|
||||
elasticProperties.spurtLoss = parseDouble( tokens[11], "Spurt Loss", lineNumber, filePath );
|
||||
elasticProperties.immobileFluidSaturation =
|
||||
parseDouble( tokens[12], "Immobile Fluid Saturation", lineNumber, filePath );
|
||||
|
||||
return elasticProperties;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ struct RifElasticProperties
|
||||
double k0;
|
||||
double fluidLossCoefficient;
|
||||
double spurtLoss;
|
||||
double immobileFluidSaturation;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
|
@ -26,7 +26,7 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifFractureModelPlotExporter::writeToFile( RimFractureModelPlot* plot, const QString& filepath )
|
||||
bool RifFractureModelPlotExporter::writeToFile( RimFractureModelPlot* plot, bool useDetailedLoss, const QString& filepath )
|
||||
{
|
||||
std::vector<QString> labels;
|
||||
// TVD depth of top of zone (ft)
|
||||
@ -56,13 +56,15 @@ bool RifFractureModelPlotExporter::writeToFile( RimFractureModelPlot* plot, cons
|
||||
// Proppand Embedmeent (lb/ft^2)
|
||||
labels.push_back( "pembed" );
|
||||
|
||||
bool useDetailedLoss = false;
|
||||
if ( useDetailedLoss )
|
||||
{
|
||||
// B2 Detailed Loss
|
||||
// Reservoir Pressure (psi)
|
||||
labels.push_back( "zoneResPres" );
|
||||
|
||||
// Immobile Fluid Saturation (fraction)
|
||||
labels.push_back( "zoneWaterSat" );
|
||||
|
||||
// Porosity (fraction)
|
||||
labels.push_back( "zonePorosity" );
|
||||
|
||||
@ -71,22 +73,39 @@ bool RifFractureModelPlotExporter::writeToFile( RimFractureModelPlot* plot, cons
|
||||
|
||||
// Vertical Perm (md)
|
||||
labels.push_back( "zoneVertPerm" );
|
||||
|
||||
// Temperature (F)
|
||||
labels.push_back( "zoneTemp" );
|
||||
|
||||
// Relative permeability
|
||||
labels.push_back( "zoneRelPerm" );
|
||||
|
||||
// Poro-Elastic constant
|
||||
labels.push_back( "zonePoroElas" );
|
||||
|
||||
// Thermal Epansion Coefficient (1/F)
|
||||
labels.push_back( "zoneThermalExp" );
|
||||
}
|
||||
|
||||
std::map<QString, std::vector<double>> values;
|
||||
values["dpthlyr"] = plot->calculateTrueVerticalDepth();
|
||||
values["strs"] = plot->calculateStress();
|
||||
values["strsg"] = plot->calculateStressGradient();
|
||||
values["elyr"] = plot->calculateYoungsModulus();
|
||||
values["poissonr"] = plot->calculatePoissonsRatio();
|
||||
values["tuflyr"] = plot->calculateKIc();
|
||||
values["clyrc"] = plot->calculateFluidLossCoefficient();
|
||||
values["clyrs"] = plot->calculateSpurtLoss();
|
||||
values["pembed"] = plot->calculateProppandEmbedment();
|
||||
values["zoneResPres"] = plot->calculateReservoirPressure();
|
||||
values["zonePorosity"] = plot->calculatePorosity();
|
||||
values["zoneHorizPerm"] = plot->calculateHorizontalPermeability();
|
||||
values["zoneVertPerm"] = plot->calculateVerticalPermeability();
|
||||
values["dpthlyr"] = plot->calculateTrueVerticalDepth();
|
||||
values["strs"] = plot->calculateStress();
|
||||
values["strsg"] = plot->calculateStressGradient();
|
||||
values["elyr"] = plot->calculateYoungsModulus();
|
||||
values["poissonr"] = plot->calculatePoissonsRatio();
|
||||
values["tuflyr"] = plot->calculateKIc();
|
||||
values["clyrc"] = plot->calculateFluidLossCoefficient();
|
||||
values["clyrs"] = plot->calculateSpurtLoss();
|
||||
values["pembed"] = plot->calculateProppandEmbedment();
|
||||
values["zoneResPres"] = plot->calculateReservoirPressure();
|
||||
values["zoneWaterSat"] = plot->calculateImmobileFluidSaturation();
|
||||
values["zonePorosity"] = plot->calculatePorosity();
|
||||
values["zoneHorizPerm"] = plot->calculateHorizontalPermeability();
|
||||
values["zoneVertPerm"] = plot->calculateVerticalPermeability();
|
||||
values["zoneTemp"] = plot->calculateTemperature();
|
||||
values["zoneRelPerm"] = plot->calculateRelativePermeabilityFactor();
|
||||
values["zonePoroElas"] = plot->calculatePoroElasticConstant();
|
||||
values["zoneThermalExp"] = plot->calculateThermalExpansionCoefficient();
|
||||
|
||||
QFile data( filepath );
|
||||
if ( !data.open( QFile::WriteOnly | QFile::Truncate ) )
|
||||
|
@ -30,7 +30,7 @@ class QTextStream;
|
||||
class RifFractureModelPlotExporter
|
||||
{
|
||||
public:
|
||||
static bool writeToFile( RimFractureModelPlot* plot, const QString& filepath );
|
||||
static bool writeToFile( RimFractureModelPlot* plot, bool useDetailedFluidLoss, const QString& filepath );
|
||||
|
||||
private:
|
||||
static void appendToStream( QTextStream& stream, const QString& label, const std::vector<double>& values );
|
||||
|
@ -85,7 +85,7 @@ RigFemScalarResultFrames*
|
||||
|
||||
frameCountProgress.incrementProgress();
|
||||
|
||||
// Biot porelastic coeffisient (alpha)
|
||||
// Biot porelastic coefficient (alpha)
|
||||
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
|
||||
RigFemScalarResultFrames* biotCoefficient = nullptr;
|
||||
if ( !m_resultCollection->biotResultAddress().isEmpty() )
|
||||
|
@ -168,6 +168,40 @@ RimFractureModel::RimFractureModel()
|
||||
"",
|
||||
"" );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_referenceTemperature, "ReferenceTemperature", 20.0, "Temperature [C]", "", "", "" );
|
||||
CAF_PDM_InitScriptableField( &m_referenceTemperatureGradient,
|
||||
"ReferenceTemperatureGradient",
|
||||
0.025,
|
||||
"Temperature Gradient [C/m]",
|
||||
"",
|
||||
"",
|
||||
"" );
|
||||
CAF_PDM_InitScriptableField( &m_referenceTemperatureDepth,
|
||||
"ReferenceTemperatureDepth",
|
||||
1000.0,
|
||||
"Temperature Depth [m]",
|
||||
"",
|
||||
"",
|
||||
"" );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_useDetailedFluidLoss, "UseDetailedFluidLoss", true, "Use Detailed Fluid Loss", "", "", "" );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_relativePermeabilityFactorDefault,
|
||||
"RelativePermeabilityFactor",
|
||||
0.5,
|
||||
"Relative Permeability Factor",
|
||||
"",
|
||||
"",
|
||||
"" );
|
||||
CAF_PDM_InitScriptableField( &m_poroElasticConstantDefault, "PoroElasticConstant", 0.0, "Poro-Elastic Constant", "", "", "" );
|
||||
CAF_PDM_InitScriptableField( &m_thermalExpansionCoeffientDefault,
|
||||
"ThermalExpansionCoefficient",
|
||||
0.0,
|
||||
"Thermal Expansion Coefficient [1/C]",
|
||||
"",
|
||||
"",
|
||||
"" );
|
||||
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_elasticProperties, "ElasticProperties", "Elastic Properties", "", "", "" );
|
||||
m_elasticProperties.uiCapability()->setUiHidden( true );
|
||||
m_elasticProperties.uiCapability()->setUiTreeHidden( true );
|
||||
@ -188,6 +222,14 @@ bool RimFractureModel::isEnabled() const
|
||||
return isChecked();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModel::useDetailedFluidLoss() const
|
||||
{
|
||||
return m_useDetailedFluidLoss();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -712,6 +754,42 @@ double RimFractureModel::getUnderburdenGradient( const QString& keyword ) const
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModel::getDefaultValueForProperty( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
if ( curveProperty == RiaDefines::CurveProperty::RELATIVE_PERMEABILITY_FACTOR )
|
||||
{
|
||||
return m_relativePermeabilityFactorDefault;
|
||||
}
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::PORO_ELASTIC_CONSTANT )
|
||||
{
|
||||
return m_poroElasticConstantDefault;
|
||||
}
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::THERMAL_EXPANSION_COEFFICIENT )
|
||||
{
|
||||
return m_thermalExpansionCoeffientDefault;
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error(
|
||||
QString( "Missing default for %1." ).arg( caf::AppEnum<RiaDefines::CurveProperty>( curveProperty ).uiText() ) );
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModel::hasDefaultValueForProperty( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
auto withDefaults = {RiaDefines::CurveProperty::RELATIVE_PERMEABILITY_FACTOR,
|
||||
RiaDefines::CurveProperty::PORO_ELASTIC_CONSTANT,
|
||||
RiaDefines::CurveProperty::THERMAL_EXPANSION_COEFFICIENT};
|
||||
return std::find( withDefaults.begin(), withDefaults.end(), curveProperty ) != withDefaults.end();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -840,3 +918,27 @@ void RimFractureModel::setMD( double md )
|
||||
updatePositionFromMeasuredDepth();
|
||||
updateThicknessDirection();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModel::referenceTemperature() const
|
||||
{
|
||||
return m_referenceTemperature;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModel::referenceTemperatureGradient() const
|
||||
{
|
||||
return m_referenceTemperatureGradient;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModel::referenceTemperatureDepth() const
|
||||
{
|
||||
return m_referenceTemperatureDepth;
|
||||
}
|
||||
|
@ -85,6 +85,12 @@ public:
|
||||
QString underburdenFormation() const;
|
||||
QString underburdenFacies() const;
|
||||
|
||||
double referenceTemperature() const;
|
||||
double referenceTemperatureGradient() const;
|
||||
double referenceTemperatureDepth() const;
|
||||
|
||||
bool useDetailedFluidLoss() const;
|
||||
|
||||
// RimWellPathCompletionsInterface overrides.
|
||||
RiaDefines::WellPathComponentType componentType() const override;
|
||||
QString componentLabel() const override;
|
||||
@ -103,6 +109,9 @@ public:
|
||||
void setElasticProperties( RimElasticProperties* elasticProperties );
|
||||
RimElasticProperties* elasticProperties() const;
|
||||
|
||||
double getDefaultValueForProperty( RiaDefines::CurveProperty ) const;
|
||||
bool hasDefaultValueForProperty( RiaDefines::CurveProperty ) const;
|
||||
|
||||
RiaDefines::CurveProperty getDefaultPropertyForMissingValues( const QString& keyword ) const;
|
||||
double getDefaultForMissingOverburdenValue( const QString& keyword ) const;
|
||||
double getDefaultForMissingUnderburdenValue( const QString& keyword ) const;
|
||||
@ -151,4 +160,11 @@ protected:
|
||||
caf::PdmField<QString> m_underburdenFormation;
|
||||
caf::PdmField<QString> m_underburdenFacies;
|
||||
caf::PdmField<double> m_underburdenFluidDensity;
|
||||
caf::PdmField<double> m_referenceTemperature;
|
||||
caf::PdmField<double> m_referenceTemperatureGradient;
|
||||
caf::PdmField<double> m_referenceTemperatureDepth;
|
||||
caf::PdmField<double> m_relativePermeabilityFactorDefault;
|
||||
caf::PdmField<double> m_poroElasticConstantDefault;
|
||||
caf::PdmField<double> m_thermalExpansionCoeffientDefault;
|
||||
caf::PdmField<bool> m_useDetailedFluidLoss;
|
||||
};
|
||||
|
@ -136,6 +136,7 @@ QString RimElasticProperties::generatePropertiesTable()
|
||||
" <th>k0</th>"
|
||||
" <th>Fluid Loss<br>Coefficient</th>"
|
||||
" <th>Spurt Loss</th>"
|
||||
" <th>Immobile Fluid<br>Saturation</th>"
|
||||
" </tr>"
|
||||
" </thead>"
|
||||
" <tbody>" );
|
||||
@ -143,16 +144,17 @@ QString RimElasticProperties::generatePropertiesTable()
|
||||
QString body;
|
||||
for ( auto prop : m_properties )
|
||||
{
|
||||
const QString& fieldName = prop.second.fieldName();
|
||||
const std::vector<double>& porosity = prop.second.porosity();
|
||||
const std::vector<double>& youngsModulus = prop.second.youngsModulus();
|
||||
const std::vector<double>& poissonsRatio = prop.second.poissonsRatio();
|
||||
const std::vector<double>& K_Ic = prop.second.K_Ic();
|
||||
const std::vector<double>& proppantEmbedment = prop.second.proppantEmbedment();
|
||||
const std::vector<double>& biotCoefficient = prop.second.biotCoefficient();
|
||||
const std::vector<double>& k0 = prop.second.k0();
|
||||
const std::vector<double>& fluidLossCoefficient = prop.second.fluidLossCoefficient();
|
||||
const std::vector<double>& spurtLoss = prop.second.spurtLoss();
|
||||
const QString& fieldName = prop.second.fieldName();
|
||||
const std::vector<double>& porosity = prop.second.porosity();
|
||||
const std::vector<double>& youngsModulus = prop.second.youngsModulus();
|
||||
const std::vector<double>& poissonsRatio = prop.second.poissonsRatio();
|
||||
const std::vector<double>& K_Ic = prop.second.K_Ic();
|
||||
const std::vector<double>& proppantEmbedment = prop.second.proppantEmbedment();
|
||||
const std::vector<double>& biotCoefficient = prop.second.biotCoefficient();
|
||||
const std::vector<double>& k0 = prop.second.k0();
|
||||
const std::vector<double>& fluidLossCoefficient = prop.second.fluidLossCoefficient();
|
||||
const std::vector<double>& spurtLoss = prop.second.spurtLoss();
|
||||
const std::vector<double>& immobileFluidSaturation = prop.second.immobileFluidSaturation();
|
||||
|
||||
for ( size_t i = 0; i < porosity.size(); i++ )
|
||||
{
|
||||
@ -169,6 +171,7 @@ QString RimElasticProperties::generatePropertiesTable()
|
||||
" <td align=right>%10</td>"
|
||||
" <td align=right>%11</td>"
|
||||
" <td align=right>%12</td>"
|
||||
" <td align=right>%13</td>"
|
||||
"</tr>" );
|
||||
|
||||
QString line = format.arg( fieldName )
|
||||
@ -182,7 +185,8 @@ QString RimElasticProperties::generatePropertiesTable()
|
||||
.arg( biotCoefficient[i] )
|
||||
.arg( k0[i] )
|
||||
.arg( fluidLossCoefficient[i] )
|
||||
.arg( spurtLoss[i] );
|
||||
.arg( spurtLoss[i] )
|
||||
.arg( immobileFluidSaturation[i] );
|
||||
|
||||
body.append( line );
|
||||
}
|
||||
|
@ -309,6 +309,16 @@ void RimElasticPropertiesCurve::performDataExtraction( bool* isUsingPseudoLength
|
||||
double val = rigElasticProperties.getSpurtLoss( porosity );
|
||||
values.push_back( val );
|
||||
}
|
||||
else if ( m_curveProperty() == RiaDefines::CurveProperty::IMMOBILE_FLUID_SATURATION )
|
||||
{
|
||||
double val = rigElasticProperties.getImmobileFluidSaturation( porosity );
|
||||
values.push_back( val );
|
||||
}
|
||||
else if ( m_fractureModel->hasDefaultValueForProperty( curveProperty() ) )
|
||||
{
|
||||
double val = m_fractureModel->getDefaultValueForProperty( curveProperty() );
|
||||
values.push_back( val );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "RimFractureModelPlot.h"
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaFractureModelDefines.h"
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RicfCommandObject.h"
|
||||
@ -59,6 +60,14 @@ void RimFractureModelPlot::setFractureModel( RimFractureModel* fractureModel )
|
||||
m_fractureModel = fractureModel;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFractureModel* RimFractureModelPlot::fractureModel()
|
||||
{
|
||||
return m_fractureModel;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -310,7 +319,15 @@ std::vector<double> RimFractureModelPlot::calculatePorosity() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateReservoirPressure() const
|
||||
{
|
||||
return findCurveAndComputeTopOfLayer( RiaDefines::CurveProperty::PRESSURE );
|
||||
std::vector<double> pressureBar = findCurveAndComputeTopOfLayer( RiaDefines::CurveProperty::PRESSURE );
|
||||
|
||||
std::vector<double> pressurePsi;
|
||||
for ( double p : pressureBar )
|
||||
{
|
||||
pressurePsi.push_back( RiaEclipseUnitTools::barToPsi( p ) );
|
||||
}
|
||||
|
||||
return pressurePsi;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -472,6 +489,37 @@ std::vector<double> RimFractureModelPlot::calculateStressGradient() const
|
||||
return stressGradients;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelPlot::calculateTemperature( std::vector<double>& temperatures ) const
|
||||
{
|
||||
// Reference temperature. Unit: degrees celsius
|
||||
const double referenceTemperature = m_fractureModel->referenceTemperature();
|
||||
|
||||
// Reference temperature gradient. Unit: degrees Celsius per meter
|
||||
const double referenceTemperatureGradient = m_fractureModel->referenceTemperatureGradient();
|
||||
|
||||
// Reference depth for temperature. Unit: meter.
|
||||
const double referenceTemperatureDepth = m_fractureModel->referenceTemperatureDepth();
|
||||
|
||||
std::vector<std::pair<double, double>> layerBoundaryDepths;
|
||||
std::vector<std::pair<size_t, size_t>> layerBoundaryIndexes;
|
||||
calculateLayers( layerBoundaryDepths, layerBoundaryIndexes );
|
||||
|
||||
// Calculate the temperatures
|
||||
for ( size_t i = 0; i < layerBoundaryDepths.size(); i++ )
|
||||
{
|
||||
double depthTopOfZone = layerBoundaryDepths[i].first;
|
||||
|
||||
// Use difference between reference depth and depth of top of zone
|
||||
double depthDiff = depthTopOfZone - referenceTemperatureDepth;
|
||||
double temperature = referenceTemperature + referenceTemperatureGradient * depthDiff;
|
||||
|
||||
temperatures.push_back( temperature );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -526,3 +574,64 @@ std::vector<double> RimFractureModelPlot::calculateProppandEmbedment() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::PROPPANT_EMBEDMENT );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateImmobileFluidSaturation() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::IMMOBILE_FLUID_SATURATION );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateTemperature() const
|
||||
{
|
||||
std::vector<double> temperaturesCelsius;
|
||||
calculateTemperature( temperaturesCelsius );
|
||||
|
||||
// Convert to Fahrenheit
|
||||
std::vector<double> temperaturesFahrenheit;
|
||||
for ( double t : temperaturesCelsius )
|
||||
{
|
||||
temperaturesFahrenheit.push_back( t * 1.8 + 32.0 );
|
||||
}
|
||||
|
||||
return temperaturesFahrenheit;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateRelativePermeabilityFactor() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::RELATIVE_PERMEABILITY_FACTOR );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculatePoroElasticConstant() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::PORO_ELASTIC_CONSTANT );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateThermalExpansionCoefficient() const
|
||||
{
|
||||
// SI unit is 1/Celsius
|
||||
std::vector<double> coefficientCelsius =
|
||||
findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::THERMAL_EXPANSION_COEFFICIENT );
|
||||
|
||||
// Field unit is 1/Fahrenheit
|
||||
std::vector<double> coefficientFahrenheit;
|
||||
for ( double c : coefficientCelsius )
|
||||
{
|
||||
coefficientFahrenheit.push_back( c / 1.8 );
|
||||
}
|
||||
|
||||
return coefficientFahrenheit;
|
||||
}
|
||||
|
@ -56,7 +56,8 @@ public:
|
||||
|
||||
RimFractureModelPlot();
|
||||
|
||||
void setFractureModel( RimFractureModel* fractureModel );
|
||||
void setFractureModel( RimFractureModel* fractureModel );
|
||||
RimFractureModel* fractureModel();
|
||||
|
||||
void getPorosityValues( std::vector<double>& values ) const;
|
||||
void getFaciesValues( std::vector<double>& values ) const;
|
||||
@ -76,6 +77,14 @@ public:
|
||||
std::vector<double> calculateSpurtLoss() const;
|
||||
std::vector<double> calculateProppandEmbedment() const;
|
||||
|
||||
std::vector<double> calculateImmobileFluidSaturation() const;
|
||||
std::vector<double> calculateTemperature() const;
|
||||
std::vector<double> calculateRelativePermeabilityFactor() const;
|
||||
std::vector<double> calculatePoroElasticConstant() const;
|
||||
std::vector<double> calculateThermalExpansionCoefficient() const;
|
||||
|
||||
void calculateTemperature( std::vector<double>& temperatures ) const;
|
||||
|
||||
protected:
|
||||
std::vector<double> findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty curveProperty ) const;
|
||||
std::vector<double> findCurveXValuesByProperty( RiaDefines::CurveProperty curveProperty ) const;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "RimFractureModelStressCurve.h"
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaFractureModelDefines.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigEclipseWellLogExtractor.h"
|
||||
#include "RigResultAccessorFactory.h"
|
||||
@ -121,15 +122,19 @@ void RimFractureModelStressCurve::performDataExtraction( bool* isUsingPseudoLeng
|
||||
tvDepthValues.push_back( RiaEclipseUnitTools::feetToMeter( f ) );
|
||||
}
|
||||
|
||||
std::vector<double> stressGradients = fractureModelPlot->calculateStressGradient();
|
||||
if ( m_curveProperty() == RiaDefines::CurveProperty::STRESS )
|
||||
{
|
||||
values = fractureModelPlot->calculateStress();
|
||||
values = fractureModelPlot->calculateStress();
|
||||
std::vector<double> stressGradients = fractureModelPlot->calculateStressGradient();
|
||||
addDatapointsForBottomOfLayers( tvDepthValues, values, stressGradients );
|
||||
}
|
||||
else
|
||||
else if ( m_curveProperty() == RiaDefines::CurveProperty::STRESS_GRADIENT )
|
||||
{
|
||||
values = stressGradients;
|
||||
values = fractureModelPlot->calculateStressGradient();
|
||||
}
|
||||
else if ( m_curveProperty() == RiaDefines::CurveProperty::TEMPERATURE )
|
||||
{
|
||||
fractureModelPlot->calculateTemperature( values );
|
||||
}
|
||||
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>( m_case.value() );
|
||||
|
@ -44,7 +44,9 @@ caf::PdmObjectHandle* RimcFractureModelPlot_exportToFile::execute()
|
||||
{
|
||||
RimFractureModelPlot* fractureModelPlot = self<RimFractureModelPlot>();
|
||||
|
||||
RifFractureModelPlotExporter::writeToFile( fractureModelPlot, m_filePath() );
|
||||
RifFractureModelPlotExporter::writeToFile( fractureModelPlot,
|
||||
fractureModelPlot->fractureModel()->useDetailedFluidLoss(),
|
||||
m_filePath() );
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -126,6 +126,14 @@ const std::vector<double>& RigElasticProperties::spurtLoss() const
|
||||
return m_spurtLoss;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<double>& RigElasticProperties::immobileFluidSaturation() const
|
||||
{
|
||||
return m_immobileFluidSaturation;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -137,7 +145,8 @@ void RigElasticProperties::appendValues( double porosity,
|
||||
double biotCoefficient,
|
||||
double k0,
|
||||
double fluidLossCoefficient,
|
||||
double spurtLoss )
|
||||
double spurtLoss,
|
||||
double immobileFluidSaturation )
|
||||
{
|
||||
m_porosity.push_back( porosity );
|
||||
m_youngsModulus.push_back( youngsModulus );
|
||||
@ -148,6 +157,7 @@ void RigElasticProperties::appendValues( double porosity,
|
||||
m_k0.push_back( k0 );
|
||||
m_fluidLossCoefficient.push_back( fluidLossCoefficient );
|
||||
m_spurtLoss.push_back( spurtLoss );
|
||||
m_immobileFluidSaturation.push_back( immobileFluidSaturation );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -213,3 +223,11 @@ double RigElasticProperties::getSpurtLoss( double porosity ) const
|
||||
{
|
||||
return RiaInterpolationTools::linear( m_porosity, m_spurtLoss, porosity );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigElasticProperties::getImmobileFluidSaturation( double porosity ) const
|
||||
{
|
||||
return RiaInterpolationTools::linear( m_porosity, m_immobileFluidSaturation, porosity );
|
||||
}
|
||||
|
@ -41,7 +41,8 @@ public:
|
||||
double biotCoefficient,
|
||||
double k0,
|
||||
double fluidLossCoefficient,
|
||||
double spurtLoss );
|
||||
double spurtLoss,
|
||||
double immobileFluidSaturation );
|
||||
double getYoungsModulus( double porosity ) const;
|
||||
double getPoissonsRatio( double porosity ) const;
|
||||
double getK_Ic( double porosity ) const;
|
||||
@ -50,6 +51,7 @@ public:
|
||||
double getK0( double porosity ) const;
|
||||
double getFluidLossCoefficient( double porosity ) const;
|
||||
double getSpurtLoss( double porosity ) const;
|
||||
double getImmobileFluidSaturation( double porosity ) const;
|
||||
|
||||
const std::vector<double>& porosity() const;
|
||||
const std::vector<double>& youngsModulus() const;
|
||||
@ -60,6 +62,7 @@ public:
|
||||
const std::vector<double>& k0() const;
|
||||
const std::vector<double>& fluidLossCoefficient() const;
|
||||
const std::vector<double>& spurtLoss() const;
|
||||
const std::vector<double>& immobileFluidSaturation() const;
|
||||
|
||||
private:
|
||||
QString m_fieldName;
|
||||
@ -75,4 +78,5 @@ private:
|
||||
std::vector<double> m_k0;
|
||||
std::vector<double> m_fluidLossCoefficient;
|
||||
std::vector<double> m_spurtLoss;
|
||||
std::vector<double> m_immobileFluidSaturation;
|
||||
};
|
||||
|
@ -37,8 +37,8 @@ TEST( RifElasticPropertiesReaderTest, ReadCorrectInputFile )
|
||||
|
||||
{
|
||||
QTextStream out( &file );
|
||||
out << "Norne,Not,Sand,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6\n"
|
||||
<< "Norne,Not,Sand,0.10,19,0.27,2099,0.3,0.4,0.5,0.2,0.5\n";
|
||||
out << "Norne,Not,Sand,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6,0.4\n"
|
||||
<< "Norne,Not,Sand,0.10,19,0.27,2099,0.3,0.4,0.5,0.2,0.5,0.55\n";
|
||||
}
|
||||
|
||||
QStringList filePaths;
|
||||
@ -72,6 +72,9 @@ TEST( RifElasticPropertiesReaderTest, ReadCorrectInputFile )
|
||||
|
||||
ASSERT_DOUBLE_EQ( 0.2, elasticProperties[0].proppantEmbedment );
|
||||
ASSERT_DOUBLE_EQ( 0.3, elasticProperties[1].proppantEmbedment );
|
||||
|
||||
ASSERT_DOUBLE_EQ( 0.4, elasticProperties[0].immobileFluidSaturation );
|
||||
ASSERT_DOUBLE_EQ( 0.55, elasticProperties[1].immobileFluidSaturation );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -119,7 +122,7 @@ TEST( RifElasticPropertiesReaderTest, ReadShortLinesFileThrows )
|
||||
|
||||
{
|
||||
QTextStream out( &file );
|
||||
out << "Norne,Not,Sand,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6\n"
|
||||
out << "Norne,Not,Sand,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6,0.7\n"
|
||||
<< "Norne,Not,Sand,0.10,19,0.27\n";
|
||||
}
|
||||
|
||||
@ -140,8 +143,8 @@ TEST( RifElasticPropertiesReaderTest, ReadEmptyFieldNameThrows )
|
||||
|
||||
{
|
||||
QTextStream out( &file );
|
||||
out << "Norne,Not,Sand,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6\n"
|
||||
<< ",Not,Sand,0.10,19,0.27,2099,0.3,0.3,0.4,0.5,0.6\n";
|
||||
out << "Norne,Not,Sand,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6,0.89\n"
|
||||
<< ",Not,Sand,0.10,19,0.27,2099,0.3,0.3,0.4,0.5,0.6,0.89\n";
|
||||
}
|
||||
|
||||
QStringList filePaths;
|
||||
@ -161,8 +164,8 @@ TEST( RifElasticPropertiesReaderTest, ReadInvalidMeasureDepthThrows )
|
||||
|
||||
{
|
||||
QTextStream out( &file );
|
||||
out << "Norne,Not,Sand,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6\n"
|
||||
<< "Norne,Not,Sand, not a number,23.4,0.27,2099,0.3,0.3,0.4,0.5,0.6\n";
|
||||
out << "Norne,Not,Sand,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6,0.9\n"
|
||||
<< "Norne,Not,Sand, not a number,23.4,0.27,2099,0.3,0.3,0.4,0.5,0.6,0.77\n";
|
||||
}
|
||||
|
||||
QStringList filePaths;
|
||||
@ -191,14 +194,14 @@ TEST( RifElasticPropertiesReaderTest, CommentsAndEmptyLinesAreIgnored )
|
||||
out << "\t\n";
|
||||
out << " \n";
|
||||
// Then some data
|
||||
out << "Norne,Not,Sand,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6\n";
|
||||
out << "Norne,Not,Sand,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6,0.7\n";
|
||||
// Comment in-between data should be ignored
|
||||
out << "# One more comment in-between the data\n";
|
||||
out << "Norne,Not,Silt,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6\n";
|
||||
out << "Norne,Not,Silt,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6,0.7\n";
|
||||
// Empty line in-between data should be ignored
|
||||
out << "\n";
|
||||
// Data with comment sign inside it is not ignored
|
||||
out << "Norne,Not,Shale,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6\n";
|
||||
out << "Norne,Not,Shale,0.00,25,0.25,2000,0.2,0.3,0.4,0.5,0.6,0.8\n";
|
||||
// Trailing empty lines should be ignored
|
||||
out << "\n\n\n";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user