Add gaswater solvent

Fix some places that assumed 3p + solvent
This commit is contained in:
Tor Harald Sandve 2023-03-29 08:21:54 +02:00
parent 675ce03e52
commit 7cf3f69cf9
16 changed files with 208 additions and 47 deletions

View File

@ -432,7 +432,7 @@ set(FLOW_MODELS blackoil brine energy extbo foam gasoil gaswater
gasoil_energy brine_saltprecipitation
gaswater_saltprec_vapwat gaswater_saltprec_energy brine_precsalt_vapwat
blackoil_legacyassembly gasoildiffuse gaswater_dissolution
gaswater_dissolution_diffuse gaswater_energy)
gaswater_dissolution_diffuse gaswater_energy gaswater_solvent)
set(FLOW_VARIANT_MODELS brine_energy onephase onephase_energy)
set(FLOW_TGTS)

View File

@ -0,0 +1,90 @@
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
// Define making clear that the simulator supports AMG
#define FLOW_SUPPORT_AMG 1
#include <flow/flow_ebos_gaswater_solvent.hpp>
#include <opm/material/common/ResetLocale.hpp>
#include <opm/models/blackoil/blackoiltwophaseindices.hh>
#include <opm/grid/CpGrid.hpp>
#include <opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp>
#include <opm/simulators/flow/Main.hpp>
namespace Opm {
namespace Properties {
namespace TTag {
struct EclFlowGasWaterSolventProblem {
using InheritsFrom = std::tuple<EclFlowProblem>;
};
}
template<class TypeTag>
struct EnableSolvent<TypeTag, TTag::EclFlowGasWaterSolventProblem> {
static constexpr bool value = true;
};
//! The indices required by the model
template<class TypeTag>
struct Indices<TypeTag, TTag::EclFlowGasWaterSolventProblem>
{
private:
// it is unfortunately not possible to simply use 'TypeTag' here because this leads
// to cyclic definitions of some properties. if this happens the compiler error
// messages unfortunately are *really* confusing and not really helpful.
using BaseTypeTag = TTag::EclFlowProblem;
using FluidSystem = GetPropType<BaseTypeTag, Properties::FluidSystem>;
public:
typedef BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
getPropValue<TypeTag, Properties::EnableExtbo>(),
getPropValue<TypeTag, Properties::EnablePolymer>(),
getPropValue<TypeTag, Properties::EnableEnergy>(),
getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0,
/*disabledCompIdx=*/FluidSystem::oilCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()> type;
};
}}
namespace Opm {
// ----------------- Main program -----------------
int flowEbosGasWaterSolventMain(int argc, char** argv, bool outputCout, bool outputFiles)
{
// we always want to use the default locale, and thus spare us the trouble
// with incorrect locale settings.
resetLocale();
FlowMainEbos<Properties::TTag::EclFlowGasWaterSolventProblem>
mainfunc {argc, argv, outputCout, outputFiles} ;
return mainfunc.execute();
}
int flowEbosGasWaterSolventMainStandalone(int argc, char** argv)
{
using TypeTag = Properties::TTag::EclFlowGasWaterSolventProblem;
auto mainObject = Opm::Main(argc, argv);
return mainObject.runStatic<TypeTag>();
}
}

View File

@ -0,0 +1,30 @@
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FLOW_EBOS_GASWATER_SOLVENT_HPP
#define FLOW_EBOS_GASWATER_SOLVENT_HPP
namespace Opm {
//! \brief Main function used in flow binary.
int flowEbosGasWaterSolventMain(int argc, char** argv, bool outputCout, bool outputFiles);
//! \brief Main function used in flow_gaswater_solvent binary.
int flowEbosGasWaterSolventMainStandalone(int argc, char** argv);
}
#endif // FLOW_EBOS_GASWATER_SOLVENT_HPP

View File

@ -0,0 +1,24 @@
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <flow/flow_ebos_gaswater_solvent.hpp>
int main(int argc, char** argv)
{
return Opm::flowEbosGasWaterSolventMainStandalone(argc, argv);
}

View File

@ -30,6 +30,7 @@
#include <flow/flow_ebos_gasoil_energy.hpp>
#include <flow/flow_ebos_oilwater.hpp>
#include <flow/flow_ebos_gaswater.hpp>
#include <flow/flow_ebos_gaswater_solvent.hpp>
#include <flow/flow_ebos_solvent.hpp>
#include <flow/flow_ebos_solvent_foam.hpp>
#include <flow/flow_ebos_polymer.hpp>
@ -592,7 +593,21 @@ private:
if (phases.active(Phase::FOAM)) {
return flowEbosSolventFoamMain(argc_, argv_, outputCout_, outputFiles_);
}
return flowEbosSolventMain(argc_, argv_, outputCout_, outputFiles_);
// solvent + gas + water
if (!phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
return flowEbosGasWaterSolventMain(argc_, argv_, outputCout_, outputFiles_);
}
// solvent + gas + water + oil
if (phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
return flowEbosSolventMain(argc_, argv_, outputCout_, outputFiles_);
}
if (outputCout_)
std::cerr << "No valid configuration is found for solvent simulation, valid options include "
<< "gas + water + solvent and gas + oil + water + solvent" << std::endl;
return EXIT_FAILURE;
}
int runExtendedBlackOil()

View File

@ -1926,14 +1926,10 @@ namespace Opm {
// in the well equations. As a result, for an oil-water-polymer system, this function will return 2.
// In some way, it makes this function appear to be confusing from its name, and we need
// to revisit/revise this function again when extending the variants of system that flow can simulate.
if (numPhases() < 3) {
return numPhases();
}
int numComp = FluidSystem::numComponents;
int numComp = numPhases() < 3? numPhases(): FluidSystem::numComponents;
if constexpr (has_solvent_) {
numComp ++;
numComp++;
}
return numComp;
}

View File

@ -357,6 +357,8 @@ INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,1u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,1u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,true,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<1u,0u,0u,0u,false,false,0u,0u,0u>)
// Blackoil
INSTANCE(BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilIndices<0u,0u,0u,0u,false,false,1u,0u>)

View File

@ -508,6 +508,7 @@ INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,1u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,true,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<1u,0u,0u,0u,false,false,0u,0u,0u>)
// Blackoil
INSTANCE(BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilIndices<0u,0u,0u,0u,true,false,0u,0u>)

View File

@ -634,6 +634,7 @@ INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,2u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,2u,0u,false,false,0u,2u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,true,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<1u,0u,0u,0u,false,false,0u,0u,0u>)
// Blackoil
INSTANCE(BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilIndices<1u,0u,0u,0u,false,false,0u,0u>)

View File

@ -774,6 +774,7 @@ INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,1u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,true,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<1u,0u,0u,0u,false,false,0u,0u,0u>)
// Blackoil
INSTANCE(BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilIndices<0u,0u,0u,0u,true,false,0u,0u>)

View File

@ -273,6 +273,7 @@ INSTANCE(7u, BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,2u,0u>)
INSTANCE(8u, BlackOilTwoPhaseIndices<0u,0u,2u,0u,false,false,0u,2u,0u>)
INSTANCE(7u, BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,0u,0u>)
INSTANCE(8u, BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,true,0u,0u,0u>)
INSTANCE(7u, BlackOilTwoPhaseIndices<1u,0u,0u,0u,false,false,0u,0u,0u>)
// Blackoil
INSTANCE(8u, BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(9u, BlackOilIndices<0u,0u,0u,0u,true,false,0u,0u>)

View File

@ -558,6 +558,8 @@ INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,2u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,2u,0u,false,false,0u,2u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,true,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<1u,0u,0u,0u,false,false,0u,0u,0u>)
// Blackoil
INSTANCE(BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilIndices<1u,0u,0u,0u,false,false,0u,0u>)
@ -568,7 +570,6 @@ INSTANCE(BlackOilIndices<0u,0u,0u,0u,true,false,0u,0u>)
INSTANCE(BlackOilIndices<0u,0u,0u,0u,false,true,0u,0u>)
INSTANCE(BlackOilIndices<0u,0u,0u,1u,false,true,0u,0u>)
INSTANCE(BlackOilIndices<0u,0u,0u,1u,false,false,1u,0u>)
INSTANCE(BlackOilIndices<1u,0u,0u,0u,true,false,0u,0u>)
}

View File

@ -221,6 +221,7 @@ INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,1u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,true,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<1u,0u,0u,0u,false,false,0u,0u,0u>)
// Blackoil
INSTANCE(BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilIndices<0u,0u,0u,0u,true,false,0u,0u>)

View File

@ -175,8 +175,9 @@ update(const WellState& well_state,
(Indices::enableSolvent ? ws.sum_solvent_rates() : 0.0) ) / total_well_rate ;
}
if constexpr (Indices::enableSolvent) {
value_[SFrac] = well_.scalingFactor(pu.phase_pos[Gas]) * ws.sum_solvent_rates() / total_well_rate ;
value_[SFrac] = well_.scalingFactor(Indices::contiSolventEqIdx) * ws.sum_solvent_rates() / total_well_rate ;
}
} else { // total_well_rate == 0
if (well_.isInjector()) {
// only single phase injection handled
@ -355,6 +356,11 @@ copyToWellState(WellState& well_state,
F[gas_pos] = value_[GFrac];
F[water_pos] -= F[gas_pos];
}
if constexpr (Indices::enableSolvent) {
F_solvent = value_[SFrac];
F[water_pos] -= F_solvent;
}
}
else if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
const int gas_pos = pu.phase_pos[Gas];
@ -438,45 +444,31 @@ volumeFraction(const unsigned compIdx) const
return EvalWell(numWellEq_ + Indices::numEq, 1.0);
}
if (has_gfrac_variable && compIdx == Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx)) {
return evaluation_[GFrac];
}
if (Indices::enableSolvent && compIdx == (unsigned)Indices::contiSolventEqIdx) {
return evaluation_[SFrac];
}
if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
if (has_wfrac_variable && compIdx == Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx)) {
return evaluation_[WFrac];
}
if (has_gfrac_variable && compIdx == Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx)) {
return evaluation_[GFrac];
}
if (Indices::enableSolvent && compIdx == (unsigned)Indices::contiSolventEqIdx) {
return evaluation_[SFrac];
}
}
else if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
if (has_gfrac_variable && compIdx == Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx)) {
return evaluation_[GFrac];
}
}
// Oil or WATER fraction
// Compute the Oil fraction if oil is present
// or the WATER fraction for a gas-water case
EvalWell well_fraction(numWellEq_ + Indices::numEq, 1.0);
if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
well_fraction -= evaluation_[WFrac];
}
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
well_fraction -= evaluation_[GFrac];
}
if constexpr (Indices::enableSolvent) {
well_fraction -= evaluation_[SFrac];
}
if (has_wfrac_variable && FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
well_fraction -= evaluation_[WFrac];
}
else if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx) &&
FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
if (has_gfrac_variable) {
well_fraction -= evaluation_[GFrac];
}
if constexpr (Indices::enableSolvent) {
well_fraction -= evaluation_[SFrac];
}
return well_fraction;
}
@ -567,6 +559,8 @@ processFractions()
const auto pu = well_.phaseUsage();
std::vector<double> F(well_.numPhases(), 0.0);
[[maybe_unused]] double F_solvent = 0.0;
if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
F[pu.phase_pos[Oil]] = 1.0;
@ -579,6 +573,10 @@ processFractions()
F[pu.phase_pos[Gas]] = value_[GFrac];
F[pu.phase_pos[Oil]] -= F[pu.phase_pos[Gas]];
}
if constexpr (Indices::enableSolvent) {
F_solvent = value_[SFrac];
F[pu.phase_pos[Oil]] -= F_solvent;
}
}
else if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
F[pu.phase_pos[Water]] = 1.0;
@ -587,17 +585,15 @@ processFractions()
F[pu.phase_pos[Gas]] = value_[GFrac];
F[pu.phase_pos[Water]] -= F[pu.phase_pos[Gas]];
}
if constexpr (Indices::enableSolvent) {
F_solvent = value_[SFrac];
F[pu.phase_pos[Water]] -= F_solvent;
}
}
else if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
F[pu.phase_pos[Gas]] = 1.0;
}
[[maybe_unused]] double F_solvent;
if constexpr (Indices::enableSolvent) {
F_solvent = value_[SFrac];
F[pu.phase_pos[Oil]] -= F_solvent;
}
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
if (F[pu.phase_pos[Water]] < 0.0) {
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
@ -732,6 +728,7 @@ INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,2u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,2u,0u,false,false,0u,2u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,true,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<1u,0u,0u,0u,false,false,0u,0u,0u>)
// Blackoil
INSTANCE(BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilIndices<1u,0u,0u,0u,false,false,0u,0u>)

View File

@ -80,7 +80,7 @@ public:
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;
static constexpr int SFrac = !Indices::enableSolvent ? -1000 : has_wfrac_variable+has_gfrac_variable+1;
//! \brief Evaluation for the well equations.
using EvalWell = DenseAd::DynamicEvaluation<Scalar, numStaticWellEq + Indices::numEq + 1>;

View File

@ -132,6 +132,7 @@ INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,1u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,true,0u,0u,0u>)
INSTANCE(BlackOilTwoPhaseIndices<1u,0u,0u,0u,false,false,0u,0u,0u>)
// Blackoil
INSTANCE(BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>)