Merge pull request #3454 from plgbrts/gw1

adjustments needed for gas-water system
This commit is contained in:
Tor Harald Sandve 2021-08-03 12:01:34 +02:00 committed by GitHub
commit 43d129861f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 68 additions and 52 deletions

View File

@ -2544,9 +2544,17 @@ private:
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx))
dofFluidState.setSaturation(FluidSystem::waterPhaseIdx,
waterSaturationData[dofIdx]);
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx))
dofFluidState.setSaturation(FluidSystem::gasPhaseIdx,
gasSaturationData[dofIdx]);
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)){
if (!FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)){
dofFluidState.setSaturation(FluidSystem::gasPhaseIdx,
1.0
- waterSaturationData[dofIdx]);
}
else
dofFluidState.setSaturation(FluidSystem::gasPhaseIdx,
gasSaturationData[dofIdx]);
}
if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx))
dofFluidState.setSaturation(FluidSystem::oilPhaseIdx,
1.0

View File

@ -171,10 +171,14 @@ int main(int argc, char **argv)
return Opm::ebosGasOilMain(argc, argv);
}
else if (waterActive && gasActive) {
notSupportedErrorStream << "\n"
<< "water-gas simulations are currently unsupported\n";
std::cerr << notSupportedErrorStream.str() << std::endl;
std::abort();
// run ebos_gaswater
if (myRank == 0)
std::cout << "Using gas-water mode" << std::endl;
Opm::ebosGasWaterSetDeck(std::move(deck),
std::move(parseContext),
std::move(errorGuard),
externalSetupTimer.elapsed());
return Opm::ebosGasWaterMain(argc, argv);
}
}
else if (foamActive) {

View File

@ -53,12 +53,6 @@ PhaseUsage phaseUsage(const Phases& phases)
}
}
// We need oil systems, since we do not support the keywords needed for
// water-gas systems.
if (!pu.phase_used[BlackoilPhases::Liquid] && !(pu.num_phases == 1)) {
OPM_THROW(std::runtime_error, "Cannot handle cases with no OIL, i.e. water-gas systems.");
}
// Add solvent info
pu.has_solvent = phases.active(Phase::SOLVENT);
if (pu.has_solvent) {

View File

@ -455,7 +455,10 @@ namespace Opm {
oilSaturationNew -= saturationsNew[FluidSystem::waterPhaseIdx];
}
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx) && priVarsNew.primaryVarsMeaning() == PrimaryVariables::Sw_po_Sg) {
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx) &&
FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) &&
priVarsNew.primaryVarsMeaning() == PrimaryVariables::Sw_po_Sg) {
assert(Indices::compositionSwitchIdx >= 0 );
saturationsNew[FluidSystem::gasPhaseIdx] = priVarsNew[Indices::compositionSwitchIdx];
oilSaturationNew -= saturationsNew[FluidSystem::gasPhaseIdx];
}
@ -484,8 +487,10 @@ namespace Opm {
}
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx) &&
FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) &&
priVarsOld.primaryVarsMeaning() == PrimaryVariables::Sw_po_Sg)
{
assert(Indices::compositionSwitchIdx >= 0 );
saturationsOld[FluidSystem::gasPhaseIdx] = priVarsOld[Indices::compositionSwitchIdx];
oilSaturationOld -= saturationsOld[FluidSystem::gasPhaseIdx];
}

View File

@ -224,9 +224,6 @@ namespace Opm
}
// gas-water
else if ( phases.active( Phase::GAS ) && phases.active( Phase::WATER ) ) {
if (outputCout_)
std::cerr << "Gas-water systems are not yet supported" << std::endl;
return EXIT_FAILURE;
flowEbosGasWaterSetDeck(setupTime_, std::move(deck_), std::move(eclipseState_), std::move(schedule_), std::move(summaryConfig_));
return flowEbosGasWaterMain(argc_, argv_, outputCout_, outputFiles_);
}

View File

@ -113,20 +113,6 @@ namespace Opm
// based on the solution strategy, there might be other well equations be introduced
static const int numStaticWellEq = numWellConservationEq + numWellControlEq;
// the positions of the primary variables for StandardWell
// the first one is the weighted total rate (WQ_t), the second and the third ones are F_w and F_g,
// which represent the fraction of Water and Gas based on the weighted total rate, the last one is BHP.
// correspondingly, we have four well equations for blackoil model, the first three are mass
// converstation equations, and the last one is the well control equation.
// primary variables related to other components, will be before the Bhp and after F_g.
// well control equation is always the last well equation.
// TODO: in the current implementation, we use the well rate as the first primary variables for injectors,
// instead of G_t.
static const bool gasoil = numPhases == 2 && (Indices::compositionSwitchIdx >= 0);
static const int WQTotal = 0;
static const int WFrac = gasoil? -1000: 1;
static const int GFrac = gasoil? 1: 2;
static const int SFrac = !has_solvent ? -1000 : 3;
// the index for Bhp in primary variables and also the index of well control equation
// they both will be the last one in their respective system.
// TODO: we should have indices for the well equations and well primary variables separately

View File

@ -90,19 +90,20 @@ relaxationFactorFractionsProducer(const std::vector<double>& primary_variables,
double relaxation_factor = 1.0;
if (FluidSystem::numActivePhases() > 1) {
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
if constexpr (has_wfrac_variable) {
const double relaxation_factor_w = StandardWellGeneric<Scalar>::
relaxationFactorFraction(primary_variables[WFrac], dwells[0][WFrac]);
relaxation_factor = std::min(relaxation_factor, relaxation_factor_w);
}
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
if constexpr (has_gfrac_variable) {
const double relaxation_factor_g = StandardWellGeneric<Scalar>::
relaxationFactorFraction(primary_variables[GFrac], dwells[0][GFrac]);
relaxation_factor = std::min(relaxation_factor, relaxation_factor_g);
}
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx) && FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
if constexpr (has_wfrac_variable && has_gfrac_variable) {
// We need to make sure the even with the relaxation_factor, the sum of F_w and F_g is below one, so there will
// not be negative oil fraction later
const double original_sum = primary_variables[WFrac] + primary_variables[GFrac];
@ -132,11 +133,11 @@ wellVolumeFraction(const unsigned compIdx) const
}
if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx) && compIdx == Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx)) {
if (has_wfrac_variable && compIdx == Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx)) {
return primary_variables_evaluation_[WFrac];
}
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx) && compIdx == Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx)) {
if (has_gfrac_variable && compIdx == Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx)) {
return primary_variables_evaluation_[GFrac];
}
@ -145,7 +146,7 @@ wellVolumeFraction(const unsigned compIdx) const
}
}
else if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx) && compIdx == Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx)) {
if (has_gfrac_variable && compIdx == Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx)) {
return primary_variables_evaluation_[GFrac];
}
}
@ -287,10 +288,10 @@ updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_log
}
if (std::abs(total_well_rate) > 0.) {
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
if constexpr (has_wfrac_variable) {
primary_variables_[WFrac] = baseif_.scalingFactor(pu.phase_pos[Water]) * well_state.wellRates(well_index)[pu.phase_pos[Water]] / total_well_rate;
}
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
if constexpr (has_gfrac_variable) {
primary_variables_[GFrac] = baseif_.scalingFactor(pu.phase_pos[Gas]) * (well_state.wellRates(well_index)[pu.phase_pos[Gas]]
- (Indices::enableSolvent ? well_state.solventWellRate(well_index) : 0.0) ) / total_well_rate ;
}
@ -326,10 +327,11 @@ updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_log
// this will happen.
} else if (baseif_.isProducer()) { // producers
// TODO: the following are not addressed for the solvent case yet
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
if constexpr (has_wfrac_variable) {
primary_variables_[WFrac] = 1.0 / np;
}
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
if constexpr (has_gfrac_variable) {
primary_variables_[GFrac] = 1.0 / np;
}
} else {
@ -530,11 +532,12 @@ processFractions() const
F[pu.phase_pos[Oil]] = 0.0;
}
}
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
if constexpr (has_wfrac_variable) {
primary_variables_[WFrac] = F[pu.phase_pos[Water]];
}
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
if constexpr (has_gfrac_variable) {
primary_variables_[GFrac] = F[pu.phase_pos[Gas]];
}
if constexpr (Indices::enableSolvent) {
@ -727,14 +730,15 @@ updatePrimaryVariablesNewton(const BVectorWell& dwells,
: 1.0;
// update the second and third well variable (The flux fractions)
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
if constexpr (has_wfrac_variable) {
const int sign2 = dwells[0][WFrac] > 0 ? 1: -1;
const double dx2_limited = sign2 * std::min(std::abs(dwells[0][WFrac] * relaxation_factor_fractions), dFLimit);
// primary_variables_[WFrac] = old_primary_variables[WFrac] - dx2_limited;
primary_variables_[WFrac] = old_primary_variables[WFrac] - dx2_limited;
}
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
if constexpr (has_gfrac_variable) {
const int sign3 = dwells[0][GFrac] > 0 ? 1: -1;
const double dx3_limited = sign3 * std::min(std::abs(dwells[0][GFrac] * relaxation_factor_fractions), dFLimit);
primary_variables_[GFrac] = old_primary_variables[GFrac] - dx3_limited;

View File

@ -67,10 +67,28 @@ protected:
// well control equation is always the last well equation.
// TODO: in the current implementation, we use the well rate as the first primary variables for injectors,
// instead of G_t.
static constexpr bool gasoil = Indices::numPhases == 2 && (Indices::compositionSwitchIdx >= 0);
static constexpr int WQTotal = 0;
static constexpr int WFrac = gasoil ? -1000 : 1;
static constexpr int GFrac = gasoil ? 1 : 2;
// Table showing the primary variable indices, depending on what phases are present:
//
// WOG OG WG WO W/O/G (single phase)
// GTotal 0 0 0 0 0
// WFrac 1 -1000 -1000 1 -1000
// GFrac 2 1 1 -1000 -1000
// Spres 3 2 2 2 1
static const int WQTotal = 0;
// In the implementation, one should use has_wfrac_variable
// rather than has_water to check if you should do something
// with the variable at the WFrac location, similar for GFrac.
// (following implementation MultisegmentWellEval.hpp)
static const bool waterEnabled = Indices::waterEnabled;
static const bool gasEnabled = Indices::gasEnabled;
static const bool oilEnabled = Indices::oilEnabled;
static constexpr bool has_wfrac_variable = Indices::waterEnabled && Indices::oilEnabled;;
static constexpr bool has_gfrac_variable = Indices::gasEnabled && Indices::numPhases > 1;
static constexpr int WFrac = has_wfrac_variable ? 1 : -1000;
static constexpr int GFrac = has_gfrac_variable ? has_wfrac_variable + 1 : -1000;
static constexpr int SFrac = !Indices::enableSolvent ? -1000 : 3;
public:

View File

@ -121,9 +121,9 @@ public:
static const int contiPolymerMWEqIdx = Indices::contiPolymerMWEqIdx;
static const int contiFoamEqIdx = Indices::contiFoamEqIdx;
static const int contiBrineEqIdx = Indices::contiBrineEqIdx;
static const bool compositionSwitchEnabled = Indices::compositionSwitchIdx >= 0;
// For the conversion between the surface volume rate and reservoir voidage rate
static const bool compositionSwitchEnabled = Indices::gasEnabled;
// For the conversion between the surface volume rate and reservoir voidage rate
using FluidState = BlackOilFluidState<Eval,
FluidSystem,
has_temperature,