mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-01-19 16:12:58 -06:00
Merge pull request #5089 from totto82/explicit_rockcomp
add option for explicit pressure for rock compaction (only transmissibility)
This commit is contained in:
commit
8a1f4d5455
@ -359,6 +359,7 @@ protected:
|
||||
std::vector<TabulatedTwoDFunction> rockCompTransMultWc_;
|
||||
std::vector<TabulatedFunction> rockCompPoroMult_;
|
||||
std::vector<TabulatedFunction> rockCompTransMult_;
|
||||
std::vector<Scalar> rockCompTransMultVal_;
|
||||
|
||||
PolymerSolutionContainer<Scalar> polymer_;
|
||||
std::vector<Scalar> maxOilSaturation_;
|
||||
|
@ -243,6 +243,10 @@ public:
|
||||
EWOMS_REGISTER_PARAM(TypeTag, int, NumPressurePointsEquil,
|
||||
"Number of pressure points (in each direction) in tables used for equilibration");
|
||||
EWOMS_HIDE_PARAM(TypeTag, NumPressurePointsEquil); // Users will typically not need to modify this parameter..
|
||||
EWOMS_REGISTER_PARAM(TypeTag, bool, ExplicitRockCompaction,
|
||||
"Use pressure from end of the last time step when evaluating rock compaction");
|
||||
EWOMS_HIDE_PARAM(TypeTag, ExplicitRockCompaction); // Users will typically not need to modify this parameter..
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1677,35 +1681,9 @@ public:
|
||||
template <class LhsEval>
|
||||
LhsEval rockCompTransMultiplier(const IntensiveQuantities& intQuants, unsigned elementIdx) const
|
||||
{
|
||||
OPM_TIMEBLOCK_LOCAL(rockCompTransMultiplier);
|
||||
if (this->rockCompTransMult_.empty() && this->rockCompTransMultWc_.empty())
|
||||
return 1.0;
|
||||
|
||||
unsigned tableIdx = 0;
|
||||
if (!this->rockTableIdx_.empty())
|
||||
tableIdx = this->rockTableIdx_[elementIdx];
|
||||
|
||||
const auto& fs = intQuants.fluidState();
|
||||
LhsEval effectivePressure = decay<LhsEval>(fs.pressure(refPressurePhaseIdx_()));
|
||||
|
||||
if (!this->minRefPressure_.empty())
|
||||
// The pore space change is irreversible
|
||||
effectivePressure =
|
||||
min(decay<LhsEval>(fs.pressure(refPressurePhaseIdx_())),
|
||||
this->minRefPressure_[elementIdx]);
|
||||
|
||||
if (!this->overburdenPressure_.empty())
|
||||
effectivePressure -= this->overburdenPressure_[elementIdx];
|
||||
|
||||
if (!this->rockCompTransMult_.empty())
|
||||
return this->rockCompTransMult_[tableIdx].eval(effectivePressure, /*extrapolation=*/true);
|
||||
|
||||
// water compaction
|
||||
assert(!this->rockCompTransMultWc_.empty());
|
||||
LhsEval SwMax = max(decay<LhsEval>(fs.saturation(waterPhaseIdx)), this->maxWaterSaturation_[elementIdx]);
|
||||
LhsEval SwDeltaMax = SwMax - initialFluidStates_[elementIdx].saturation(waterPhaseIdx);
|
||||
|
||||
return this->rockCompTransMultWc_[tableIdx].eval(effectivePressure, SwDeltaMax, /*extrapolation=*/true);
|
||||
bool implicit = !EWOMS_GET_PARAM(TypeTag, bool, ExplicitRockCompaction);
|
||||
return implicit ? this->simulator().problem().template computeRockCompTransMultiplier_<LhsEval>(intQuants, elementIdx)
|
||||
: this->simulator().problem().getRockCompTransMultVal(elementIdx);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1736,7 +1714,9 @@ public:
|
||||
{
|
||||
OPM_TIMEBLOCK_LOCAL(wellTransMultiplier);
|
||||
|
||||
double trans_mult = this->simulator().problem().template rockCompTransMultiplier<double>(intQuants, elementIdx);
|
||||
bool implicit = !EWOMS_GET_PARAM(TypeTag, bool, ExplicitRockCompaction);
|
||||
double trans_mult = implicit ? this->simulator().problem().template computeRockCompTransMultiplier_<double>(intQuants, elementIdx)
|
||||
: this->simulator().problem().getRockCompTransMultVal(elementIdx);
|
||||
trans_mult *= this->simulator().problem().template permFactTransMultiplier<double>(intQuants);
|
||||
|
||||
return trans_mult;
|
||||
@ -1832,6 +1812,8 @@ protected:
|
||||
|
||||
if constexpr (getPropValue<TypeTag, Properties::EnablePolymer>())
|
||||
updateMaxPolymerAdsorption_();
|
||||
|
||||
updateRockCompTransMultVal_();
|
||||
}
|
||||
|
||||
template<class UpdateFunc>
|
||||
@ -2522,6 +2504,15 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
Scalar getRockCompTransMultVal(std::size_t dofIdx) const
|
||||
{
|
||||
if (this->rockCompTransMultVal_.empty())
|
||||
return 1.0;
|
||||
|
||||
return this->rockCompTransMultVal_[dofIdx];
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
struct PffDofData_
|
||||
{
|
||||
@ -2696,6 +2687,57 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void updateRockCompTransMultVal_()
|
||||
{
|
||||
const auto& model = this->simulator().model();
|
||||
std::size_t numGridDof = this->model().numGridDof();
|
||||
this->rockCompTransMultVal_.resize(numGridDof, 1.0);
|
||||
for (std::size_t elementIdx = 0; elementIdx < numGridDof; ++elementIdx) {
|
||||
const auto& iq = *model.cachedIntensiveQuantities(elementIdx, /*timeIdx=*/ 0);
|
||||
Scalar trans_mult = computeRockCompTransMultiplier_<Scalar>(iq, elementIdx);
|
||||
this->rockCompTransMultVal_[elementIdx] = trans_mult;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculate the transmissibility multiplier due to water induced rock compaction.
|
||||
*
|
||||
* TODO: The API of this is a bit ad-hoc, it would be better to use context objects.
|
||||
*/
|
||||
template <class LhsEval>
|
||||
LhsEval computeRockCompTransMultiplier_(const IntensiveQuantities& intQuants, unsigned elementIdx) const
|
||||
{
|
||||
OPM_TIMEBLOCK_LOCAL(computeRockCompTransMultiplier);
|
||||
if (this->rockCompTransMult_.empty() && this->rockCompTransMultWc_.empty())
|
||||
return 1.0;
|
||||
|
||||
unsigned tableIdx = 0;
|
||||
if (!this->rockTableIdx_.empty())
|
||||
tableIdx = this->rockTableIdx_[elementIdx];
|
||||
|
||||
const auto& fs = intQuants.fluidState();
|
||||
LhsEval effectivePressure = decay<LhsEval>(fs.pressure(refPressurePhaseIdx_()));
|
||||
|
||||
if (!this->minRefPressure_.empty())
|
||||
// The pore space change is irreversible
|
||||
effectivePressure =
|
||||
min(decay<LhsEval>(fs.pressure(refPressurePhaseIdx_())),
|
||||
this->minRefPressure_[elementIdx]);
|
||||
|
||||
if (!this->overburdenPressure_.empty())
|
||||
effectivePressure -= this->overburdenPressure_[elementIdx];
|
||||
|
||||
if (!this->rockCompTransMult_.empty())
|
||||
return this->rockCompTransMult_[tableIdx].eval(effectivePressure, /*extrapolation=*/true);
|
||||
|
||||
// water compaction
|
||||
assert(!this->rockCompTransMultWc_.empty());
|
||||
LhsEval SwMax = max(decay<LhsEval>(fs.saturation(waterPhaseIdx)), this->maxWaterSaturation_[elementIdx]);
|
||||
LhsEval SwDeltaMax = SwMax - initialFluidStates_[elementIdx].saturation(waterPhaseIdx);
|
||||
|
||||
return this->rockCompTransMultWc_[tableIdx].eval(effectivePressure, SwDeltaMax, /*extrapolation=*/true);
|
||||
}
|
||||
|
||||
typename Vanguard::TransmissibilityType transmissibilities_;
|
||||
|
||||
std::shared_ptr<EclMaterialLawManager> materialLawManager_;
|
||||
|
@ -139,6 +139,11 @@ template<class TypeTag, class MyTypeTag>
|
||||
struct NumPressurePointsEquil {
|
||||
using type = UndefinedProperty;
|
||||
};
|
||||
// implicit or explicit pressure in rock compaction
|
||||
template<class TypeTag, class MyTypeTag>
|
||||
struct ExplicitRockCompaction {
|
||||
using type = UndefinedProperty;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -608,6 +613,11 @@ template<class TypeTag>
|
||||
struct NumPressurePointsEquil<TypeTag, TTag::EclBaseProblem> {
|
||||
static constexpr int value = ParserKeywords::EQLDIMS::DEPTH_NODES_P::defaultValue;
|
||||
};
|
||||
// By default, use implicit pressure in rock compaction
|
||||
template<class TypeTag>
|
||||
struct ExplicitRockCompaction<TypeTag, TTag::EclBaseProblem> {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
} // namespace Opm::Properties
|
||||
|
||||
|
@ -1604,7 +1604,7 @@ namespace Opm
|
||||
for (int perf = 0; perf < this->number_of_perforations_; ++perf) {
|
||||
const int cell_idx = this->well_cells_[perf];
|
||||
const auto& intQuants = simulator.model().intensiveQuantities(cell_idx, /*timeIdx=*/ 0);
|
||||
const double trans_mult = simulator.problem().template rockCompTransMultiplier<double>(intQuants, cell_idx);
|
||||
const double trans_mult = simulator.problem().template wellTransMultiplier<double>(intQuants, cell_idx);
|
||||
const auto& connection = this->well_ecl_.getConnections()[perf_data.ecl_index[perf]];
|
||||
perf_data.connection_transmissibility_factor[perf] = connection.CF() * trans_mult;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user