blackoilboundaryratevector.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
28#ifndef EWOMS_BLACK_OIL_BOUNDARY_RATE_VECTOR_HH
29#define EWOMS_BLACK_OIL_BOUNDARY_RATE_VECTOR_HH
30
31#include <opm/material/common/Valgrind.hpp>
32#include <opm/material/constraintsolvers/NcpFlash.hpp>
33
36
38
40
42
43#include <algorithm>
44#include <type_traits>
45
46namespace Opm {
47
53template <class TypeTag>
54class BlackOilBoundaryRateVector : public GetPropType<TypeTag, Properties::RateVector>
55{
64
65 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
66 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
67 static constexpr bool enablePolymer = getPropValue<TypeTag, Properties::EnablePolymer>();
68 static constexpr bool enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>();
69 enum { enableFullyImplicitThermal = (getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::FullyImplicitThermal) };
70 enum { contiEnergyEqIdx = Indices::contiEnergyEqIdx };
71 static constexpr bool enableFoam = getPropValue<TypeTag, Properties::EnableFoam>();
72 enum { enableMICP = Indices::enableMICP };
73
74 static constexpr bool blackoilConserveSurfaceVolume =
75 getPropValue<TypeTag, Properties::BlackoilConserveSurfaceVolume>();
76
77 static constexpr EnergyModules energyModuleType = getPropValue<TypeTag, Properties::EnergyModuleType>();
79
80public:
85
89 BlackOilBoundaryRateVector(Scalar value) : ParentType(value)
90 {}
91
97
101 template <class Context, class FluidState>
102 void setFreeFlow(const Context& context,
103 unsigned bfIdx,
104 unsigned timeIdx,
105 const FluidState& fluidState)
106 {
107 ExtensiveQuantities extQuants;
108 extQuants.updateBoundary(context, bfIdx, timeIdx, fluidState);
109 const auto& insideIntQuants = context.intensiveQuantities(bfIdx, timeIdx);
110 const unsigned focusDofIdx = context.focusDofIndex();
111 const unsigned interiorDofIdx = context.interiorScvIndex(bfIdx, timeIdx);
112
114 // advective fluxes of all components in all phases
116 (*this) = 0.0;
117 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
118 if (!FluidSystem::phaseIsActive(phaseIdx)) {
119 continue;
120 }
121 const auto& pBoundary = fluidState.pressure(phaseIdx);
122 const Evaluation& pInside = insideIntQuants.fluidState().pressure(phaseIdx);
123
124 RateVector tmp;
125
126 // mass conservation
127 if (pBoundary < pInside) {
128 // outflux
129 LocalResidual::template evalPhaseFluxes_<Evaluation>(tmp,
130 phaseIdx,
131 insideIntQuants.pvtRegionIndex(),
132 extQuants,
133 insideIntQuants.fluidState());
134 }
135 else if (pBoundary > pInside) {
136 using RhsEval = std::conditional_t<std::is_same_v<typename FluidState::ValueType, Evaluation>,
137 Evaluation, Scalar>;
138 // influx
139 LocalResidual::template evalPhaseFluxes_<RhsEval>(tmp,
140 phaseIdx,
141 insideIntQuants.pvtRegionIndex(),
142 extQuants,
143 fluidState);
144 }
145
146 for (unsigned i = 0; i < tmp.size(); ++i) {
147 (*this)[i] += tmp[i];
148 }
149
150 // energy conservation
151 if constexpr (enableFullyImplicitThermal) {
152 Evaluation density;
153 Evaluation specificEnthalpy;
154 if (pBoundary > pInside) {
155 if (focusDofIdx == interiorDofIdx) {
156 density = fluidState.density(phaseIdx);
157 specificEnthalpy = fluidState.enthalpy(phaseIdx);
158 }
159 else {
160 density = getValue(fluidState.density(phaseIdx));
161 specificEnthalpy = getValue(fluidState.enthalpy(phaseIdx));
162 }
163 }
164 else if (focusDofIdx == interiorDofIdx) {
165 density = insideIntQuants.fluidState().density(phaseIdx);
166 specificEnthalpy = insideIntQuants.fluidState().enthalpy(phaseIdx);
167 }
168 else {
169 density = getValue(insideIntQuants.fluidState().density(phaseIdx));
170 specificEnthalpy = getValue(insideIntQuants.fluidState().enthalpy(phaseIdx));
171 }
172
173 const Evaluation enthalpyRate = density * extQuants.volumeFlux(phaseIdx) * specificEnthalpy;
174 EnergyModule::addToEnthalpyRate(*this, enthalpyRate *
175 getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>());
176 }
177 }
178
179 if constexpr (enableSolvent) {
180 (*this)[Indices::contiSolventEqIdx] = extQuants.solventVolumeFlux();
181 if (blackoilConserveSurfaceVolume) {
182 (*this)[Indices::contiSolventEqIdx] *= insideIntQuants.solventInverseFormationVolumeFactor();
183 }
184 else {
185 (*this)[Indices::contiSolventEqIdx] *= insideIntQuants.solventDensity();
186 }
187 }
188
189 if constexpr (enablePolymer) {
190 (*this)[Indices::contiPolymerEqIdx] = extQuants.volumeFlux(FluidSystem::waterPhaseIdx) *
191 insideIntQuants.polymerConcentration();
192 }
193
194 if constexpr (enableMICP) {
195 (*this)[Indices::contiMicrobialEqIdx] = extQuants.volumeFlux(FluidSystem::waterPhaseIdx) *
196 insideIntQuants.microbialConcentration();
197 (*this)[Indices::contiOxygenEqIdx] = extQuants.volumeFlux(FluidSystem::waterPhaseIdx) *
198 insideIntQuants.oxygenConcentration();
199 (*this)[Indices::contiUreaEqIdx] = extQuants.volumeFlux(FluidSystem::waterPhaseIdx) *
200 insideIntQuants.ureaConcentration();
201 // since the urea concentration can be much larger than 1, then we apply a scaling factor
202 (*this)[Indices::contiUreaEqIdx] *= getPropValue<TypeTag, Properties::BlackOilUreaScalingFactor>();
203 }
204
205 // make sure that the right mass conservation quantities are used
206 LocalResidual::adaptMassConservationQuantities_(*this, insideIntQuants.pvtRegionIndex());
207
208 // heat conduction
209 if constexpr (enableFullyImplicitThermal) {
210 EnergyModule::addToEnthalpyRate(*this, extQuants.energyFlux() *
211 getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>());
212 }
213
214#ifndef NDEBUG
215 for (unsigned i = 0; i < numEq; ++i) {
216 Valgrind::CheckDefined((*this)[i]);
217 }
218 Valgrind::CheckDefined(*this);
219#endif
220 }
221
225 template <class Context, class FluidState>
226 void setInFlow(const Context& context,
227 unsigned bfIdx,
228 unsigned timeIdx,
229 const FluidState& fluidState)
230 {
231 this->setFreeFlow(context, bfIdx, timeIdx, fluidState);
232
233 // we only allow fluxes in the direction opposite to the outer
234 // unit normal
235 std::ranges::for_each(*this,
236 [](auto& val) { val = std::min(Scalar(0), val); });
237 }
238
242 template <class Context, class FluidState>
243 void setOutFlow(const Context& context,
244 unsigned bfIdx,
245 unsigned timeIdx,
246 const FluidState& fluidState)
247 {
248 this->setFreeFlow(context, bfIdx, timeIdx, fluidState);
249
250 // we only allow fluxes in the same direction as the outer
251 // unit normal
252 std::ranges::for_each(*this,
253 [](auto& val) { val = std::max(Scalar(0), val); });
254 }
255
260 { (*this) = Scalar(0); }
261
269 template <class Context, class FluidState>
270 void setThermalFlow([[maybe_unused]] const Context& context,
271 [[maybe_unused]] unsigned bfIdx,
272 [[maybe_unused]] unsigned timeIdx,
273 [[maybe_unused]] const FluidState& boundaryFluidState)
274 {
275 // set the mass no-flow condition
276 setNoFlow();
277
278 // if we do not conserve energy there is nothing we should do in addition
279 if constexpr (enableFullyImplicitThermal) {
280 ExtensiveQuantities extQuants;
281 extQuants.updateBoundary(context, bfIdx, timeIdx, boundaryFluidState);
282
283 (*this)[contiEnergyEqIdx] += extQuants.energyFlux();
284
285#ifndef NDEBUG
286 for (unsigned i = 0; i < numEq; ++i) {
287 Valgrind::CheckDefined((*this)[i]);
288 }
289 Valgrind::CheckDefined(*this);
290#endif
291 }
292 }
293};
294
295} // namespace Opm
296
297#endif
Contains classes extending the black-oil model. \detail This file holds dummy definitions,...
Declares the properties required by the black oil model.
Implements a boundary vector for the fully implicit black-oil model.
Definition: blackoilboundaryratevector.hh:55
BlackOilBoundaryRateVector(Scalar value)
Definition: blackoilboundaryratevector.hh:89
void setOutFlow(const Context &context, unsigned bfIdx, unsigned timeIdx, const FluidState &fluidState)
Specify an outflow boundary.
Definition: blackoilboundaryratevector.hh:243
BlackOilBoundaryRateVector & operator=(const BlackOilBoundaryRateVector &value)=default
BlackOilBoundaryRateVector(const BlackOilBoundaryRateVector &value)=default
Copy constructor.
void setFreeFlow(const Context &context, unsigned bfIdx, unsigned timeIdx, const FluidState &fluidState)
Specify a free-flow boundary.
Definition: blackoilboundaryratevector.hh:102
BlackOilBoundaryRateVector()=default
Default constructor.
void setNoFlow()
Specify a no-flow boundary for all conserved quantities.
Definition: blackoilboundaryratevector.hh:259
void setInFlow(const Context &context, unsigned bfIdx, unsigned timeIdx, const FluidState &fluidState)
Specify an inflow boundary.
Definition: blackoilboundaryratevector.hh:226
void setThermalFlow(const Context &context, unsigned bfIdx, unsigned timeIdx, const FluidState &boundaryFluidState)
an energy flux that corresponds to the thermal conduction from
Definition: blackoilboundaryratevector.hh:270
Definition: blackoilmodules.hpp:63
Declare the properties used by the infrastructure code of the finite volume discretizations.
Defines the common properties required by the porous medium multi-phase models.
Definition: blackoilbioeffectsmodules.hh:45
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233
The Opm property system, traits with inheritance.