#11405 Fault reactivation: fix unexpected temperature change outside reservoir.

No change in temperature is expected outside of reservoir between
first (geostatic) and other time steps when exporting reactivation model.
I.e. the temperature gradient and "top of reservoir" temperature from the
geostatic step should be used on all time steps.

Fixes #11405.
This commit is contained in:
Kristian Bendiksen 2024-05-02 09:35:43 +02:00
parent 2e4ca390c7
commit 03e1d4e762
3 changed files with 28 additions and 12 deletions

View File

@ -58,7 +58,8 @@ RimFaultReactivationDataAccess::RimFaultReactivationDataAccess( const RimFaultRe
double seabedDepth = -model.seaBedDepth();
m_accessors.push_back( std::make_shared<RimFaultReactivationDataAccessorPorePressure>( eCase, porePressureGradient, seabedDepth ) );
m_accessors.push_back( std::make_shared<RimFaultReactivationDataAccessorVoidRatio>( eCase, 0.0001 ) );
m_accessors.push_back( std::make_shared<RimFaultReactivationDataAccessorTemperature>( eCase, topTemperature, seabedDepth ) );
m_accessors.push_back(
std::make_shared<RimFaultReactivationDataAccessorTemperature>( eCase, topTemperature, seabedDepth, timeSteps.front() ) );
std::vector<RimFaultReactivation::Property> stressProperties = { RimFaultReactivation::Property::StressTop,
RimFaultReactivation::Property::DepthTop,

View File

@ -42,12 +42,14 @@
//--------------------------------------------------------------------------------------------------
RimFaultReactivationDataAccessorTemperature::RimFaultReactivationDataAccessorTemperature( RimEclipseCase* eclipseCase,
double seabedTemperature,
double seabedDepth )
double seabedDepth,
size_t firstTimeStep )
: m_eclipseCase( eclipseCase )
, m_caseData( nullptr )
, m_mainGrid( nullptr )
, m_seabedTemperature( seabedTemperature )
, m_seabedDepth( seabedDepth )
, m_firstTimeStep( firstTimeStep )
{
if ( m_eclipseCase )
{
@ -75,14 +77,23 @@ void RimFaultReactivationDataAccessorTemperature::updateResultAccessor()
m_resultAccessor =
RigResultAccessorFactory::createFromResultAddress( m_caseData, 0, RiaDefines::PorosityModelType::MATRIX_MODEL, m_timeStep, resVarAddress );
if ( m_resultAccessor.notNull() )
// Only create the first time step accessor once: it is always the same.
if ( m_resultAccessor0.isNull() )
{
auto [wellPaths, extractors] =
RimFaultReactivationDataAccessorWellLogExtraction::createEclipseWellPathExtractors( *m_model, *m_caseData, m_seabedDepth );
m_wellPaths = wellPaths;
m_extractors = extractors;
m_resultAccessor0 = RigResultAccessorFactory::createFromResultAddress( m_caseData,
0,
RiaDefines::PorosityModelType::MATRIX_MODEL,
m_firstTimeStep,
resVarAddress );
if ( m_resultAccessor0.notNull() )
{
auto [wellPaths, extractors] =
RimFaultReactivationDataAccessorWellLogExtraction::createEclipseWellPathExtractors( *m_model, *m_caseData, m_seabedDepth );
m_wellPaths = wellPaths;
m_extractors = extractors;
m_gradient = computeGradient();
m_gradient = computeGradient();
}
}
}
@ -99,7 +110,7 @@ double RimFaultReactivationDataAccessorTemperature::computeGradient() const
auto wellPath = m_wellPaths.find( gridPart )->second;
auto [values, intersections] =
RimFaultReactivationDataAccessorWellLogExtraction::extractValuesAndIntersections( *m_resultAccessor.p(), *extractor.p(), *wellPath );
RimFaultReactivationDataAccessorWellLogExtraction::extractValuesAndIntersections( *m_resultAccessor0.p(), *extractor.p(), *wellPath );
int lastOverburdenIndex = RimFaultReactivationDataAccessorWellLogExtraction::findLastOverburdenIndex( values );
if ( lastOverburdenIndex != -1 )
@ -144,7 +155,7 @@ double RimFaultReactivationDataAccessorTemperature::valueAtPosition( const cvf::
double bottomDepth,
size_t elementIndex ) const
{
if ( ( m_mainGrid != nullptr ) && m_resultAccessor.notNull() )
if ( ( m_mainGrid != nullptr ) && m_resultAccessor.notNull() && m_resultAccessor0.notNull() )
{
auto cellIdx = m_mainGrid->findReservoirCellIndexFromPoint( position );
if ( cellIdx != cvf::UNDEFINED_SIZE_T )
@ -159,8 +170,10 @@ double RimFaultReactivationDataAccessorTemperature::valueAtPosition( const cvf::
CAF_ASSERT( m_wellPaths.find( gridPart ) != m_wellPaths.end() );
auto wellPath = m_wellPaths.find( gridPart )->second;
// Use data from first time step when not in reservoir. This ensures that the only difference between the
// timesteps in the fault-reactivation model is in the reservoir.
auto [values, intersections] =
RimFaultReactivationDataAccessorWellLogExtraction::extractValuesAndIntersections( *m_resultAccessor.p(), *extractor.p(), *wellPath );
RimFaultReactivationDataAccessorWellLogExtraction::extractValuesAndIntersections( *m_resultAccessor0.p(), *extractor.p(), *wellPath );
auto [value, pos] =
RimFaultReactivationDataAccessorWellLogExtraction::calculateTemperature( intersections, position, m_seabedTemperature, m_gradient );

View File

@ -38,7 +38,7 @@ class RigEclipseWellLogExtractor;
class RimFaultReactivationDataAccessorTemperature : public RimFaultReactivationDataAccessor
{
public:
RimFaultReactivationDataAccessorTemperature( RimEclipseCase* eclipseCase, double seabedTemperature, double seabedDepth );
RimFaultReactivationDataAccessorTemperature( RimEclipseCase* eclipseCase, double seabedTemperature, double seabedDepth, size_t firstTimeStep );
~RimFaultReactivationDataAccessorTemperature();
bool isMatching( RimFaultReactivation::Property property ) const override;
@ -60,7 +60,9 @@ private:
double m_seabedTemperature;
double m_seabedDepth;
double m_gradient;
size_t m_firstTimeStep;
cvf::ref<RigResultAccessor> m_resultAccessor0;
cvf::ref<RigResultAccessor> m_resultAccessor;
std::map<RimFaultReactivation::GridPart, cvf::ref<RigWellPath>> m_wellPaths;