Merge pull request #6372 from OPM/stimplan-detailed-fluid-loss-6364

Stimplan detailed fluid loss 6364
This commit is contained in:
Kristian Bendiksen 2020-08-26 12:50:43 +02:00 committed by GitHub
commit 100c1b9e14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 382 additions and 53 deletions

View File

@ -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

View File

@ -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

View File

@ -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 );
}
{

View File

@ -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 );

View File

@ -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() );

View File

@ -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;
}

View File

@ -36,6 +36,7 @@ struct RifElasticProperties
double k0;
double fluidLossCoefficient;
double spurtLoss;
double immobileFluidSaturation;
};
//==================================================================================================

View File

@ -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 ) )

View File

@ -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 );

View File

@ -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() )

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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 );
}

View File

@ -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
{

View File

@ -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;
}

View File

@ -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;

View File

@ -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() );

View File

@ -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;
}

View File

@ -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 );
}

View File

@ -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;
};

View File

@ -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";
}