28#ifndef OPM_TEMPERATURE_MODEL_HPP
29#define OPM_TEMPERATURE_MODEL_HPP
31#include <opm/common/OpmLog/OpmLog.hpp>
49template<
class TypeTag,
class MyTypeTag>
58template<
typename Scalar,
typename IndexTraits>
class WellState;
65template <class TypeTag, bool enableTempV = getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::SequentialImplicitThermal >
67 GetPropType<TypeTag, Properties::GridView>,
68 GetPropType<TypeTag, Properties::DofMapper>,
69 GetPropType<TypeTag, Properties::Stencil>,
70 GetPropType<TypeTag, Properties::FluidSystem>,
71 GetPropType<TypeTag, Properties::Scalar>>
88 using TemperatureEvaluation = DenseAd::Evaluation<Scalar,1>;
93 using IndexTraits =
typename FluidSystem::IndexTraitsType;
99 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
100 enum { numPhases = FluidSystem::numPhases };
101 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
102 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
103 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
107 :
BaseType(simulator.vanguard().gridView(),
108 simulator.vanguard().eclState(),
109 simulator.vanguard().cartesianIndexMapper(),
110 simulator.model().dofMapper())
116 const unsigned int numCells =
simulator_.model().numTotalDof();
126 for (
unsigned globI = 0; globI < numCells; ++globI) {
134 const auto& elemMapper =
simulator_.model().elementMapper();
145 const unsigned int numCells =
simulator_.model().numTotalDof();
146 for (
unsigned globI = 0; globI < numCells; ++globI) {
153 const int nw =
simulator_.problem().wellModel().wellState().numWells();
167 const unsigned int numCells =
simulator_.model().numTotalDof();
168 for (
unsigned globI = 0; globI < numCells; ++globI) {
176 const int nw = wellState.
numWells();
177 for (
auto wellID = 0*nw; wellID < nw; ++wellID) {
178 auto& ws = wellState.
well(wellID);
187 template <
class Restarter>
197 template <
class Restarter>
205 const unsigned int numCells =
simulator_.model().numTotalDof();
207 #pragma omp parallel for
209 for (
unsigned globI = 0; globI < numCells; ++globI) {
210 Scalar storage = 0.0;
218 const int max_iter = 20;
219 const int min_iter = 1;
221 for (
int iter = 0; iter < max_iter; ++iter) {
223 if (iter >= min_iter &&
converged(iter)) {
232 const unsigned int numCells =
simulator_.model().numTotalDof();
233 EnergyVector dx(numCells);
236 if (
simulator_.gridView().comm().rank() == 0) {
237 OpmLog::warning(
"Temp model: Linear solver did not converge. Temperature values not updated.");
241 for (
unsigned globI = 0; globI < numCells; ++globI) {
251 const unsigned int numCells =
simulator_.model().numTotalDof();
252 Scalar maxNorm = 0.0;
253 Scalar sumNorm = 0.0;
254 const auto& elemMapper =
simulator_.model().elementMapper();
255 for (
const auto& elem : elements(
simulator_.gridView(), Dune::Partitions::interior)) {
256 unsigned globI = elemMapper.index(elem);
257 maxNorm = max(maxNorm, std::abs(this->
energyVector_[globI]));
260 maxNorm =
simulator_.gridView().comm().max(maxNorm);
261 sumNorm =
simulator_.gridView().comm().sum(sumNorm);
262 const int globalNumCells =
simulator_.gridView().comm().sum(numCells);
263 sumNorm /= globalNumCells;
264 const auto tolerance_cnv_energy = Parameters::Get<Parameters::ToleranceCnvEnergy<Scalar>>();
265 const auto tolerance_energy_balance = Parameters::Get<Parameters::ToleranceEnergyBalance<Scalar>>();
266 if (maxNorm < tolerance_cnv_energy || sumNorm < tolerance_energy_balance) {
267 const auto msg = fmt::format(
"Temperature model (TEMP): Newton converged after {} iterations", iter);
274 template<
class LhsEval>
278 const auto& poro = decay<LhsEval>(intQuants.porosity());
280 const auto& fs = intQuants.fluidState();
281 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
282 if (!FluidSystem::phaseIsActive(phaseIdx)) {
286 const auto& u = decay<LhsEval>(fs.internalEnergy(phaseIdx));
287 const auto& S = decay<LhsEval>(fs.saturation(phaseIdx));
288 const auto& rho = decay<LhsEval>(fs.density(phaseIdx));
290 storage += poro*S*u*rho;
294 const Scalar rockFraction = intQuants.rockFraction();
295 const auto& uRock = decay<LhsEval>(intQuants.rockInternalEnergy());
296 storage += rockFraction*uRock;
297 storage*= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
300 template <
class Res
idualNBInfo>
302 const ResidualNBInfo& res_nbinfo,
305 const IntensiveQuantities& intQuantsIn =
intQuants_[globI];
306 const IntensiveQuantities& intQuantsEx =
intQuants_[globJ];
308 RateVector darcyFlux(0.0);
309 LocalResidual::computeFlux(tmp, darcyFlux, globI, globJ, intQuantsIn, intQuantsEx,
310 res_nbinfo,
simulator_.problem().moduleParams());
311 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
312 if (!FluidSystem::phaseIsActive(phaseIdx)) {
316 const unsigned activeCompIdx =
317 FluidSystem::canonicalToActiveCompIdx(FluidSystem::solventComponentIndex(phaseIdx));
319 bool inIsUp = darcyFlux[activeCompIdx] > 0;
320 const IntensiveQuantities& up = inIsUp ? intQuantsIn : intQuantsEx;
321 const auto& fs = up.fluidState();
323 flux += fs.enthalpy(phaseIdx)
324 * fs.density(phaseIdx)
325 * darcyFlux[activeCompIdx];
328 flux += getValue(fs.enthalpy(phaseIdx))
329 * getValue(fs.density(phaseIdx))
330 * getValue(darcyFlux[activeCompIdx]);
333 flux *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
336 template <
class Res
idualNBInfo>
338 const ResidualNBInfo& res_nbinfo,
339 Evaluation& heatFlux)
341 const IntensiveQuantities& intQuantsIn =
intQuants_[globI];
342 const IntensiveQuantities& intQuantsEx =
intQuants_[globJ];
343 const Scalar inAlpha =
simulator_.problem().thermalHalfTransmissibility(globI, globJ);
344 const Scalar outAlpha =
simulator_.problem().thermalHalfTransmissibility(globJ, globI);
345 short interiorDofIdx = 0;
346 short exteriorDofIdx = 1;
347 EnergyModule::ExtensiveQuantities::updateEnergy(heatFlux,
353 intQuantsIn.fluidState(),
354 intQuantsEx.fluidState(),
357 res_nbinfo.faceArea);
358 heatFlux *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>()*res_nbinfo.faceArea;
366 const unsigned int numCells =
simulator_.model().numTotalDof();
368#pragma omp parallel for
370 for (
unsigned globI = 0; globI < numCells; ++globI) {
371 Scalar volume =
simulator_.model().dofTotalVolume(globI);
372 Scalar storefac = volume / dt;
373 Evaluation storage = 0.0;
376 (*this->
energyMatrix_)[globI][globI][0][0] += storefac * storage.derivative(Indices::temperatureIdx);
379 const auto& neighborInfo =
simulator_.model().linearizer().getNeighborInfo();
381#pragma omp parallel for
383 for (
unsigned globI = 0; globI < numCells; ++globI) {
384 const auto& nbInfos = neighborInfo[globI];
385 for (
const auto& nbInfo : nbInfos) {
386 unsigned globJ = nbInfo.neighbor;
387 assert(globJ != globI);
390 Evaluation flux = 0.0;
393 (*this->
energyMatrix_)[globI][globI][0][0] += flux.derivative(Indices::temperatureIdx);
394 (*this->
energyMatrix_)[globJ][globI][0][0] -= flux.derivative(Indices::temperatureIdx);
397 Evaluation heatFlux = 0.0;
400 (*this->
energyMatrix_)[globI][globI][0][0] += heatFlux.derivative(Indices::temperatureIdx);
401 (*this->
energyMatrix_)[globJ][globI][0][0] -= heatFlux.derivative(Indices::temperatureIdx);
406 const auto& wellPtrs =
simulator_.problem().wellModel().localNonshutWells();
407 for (
const auto& wellPtr : wellPtrs) {
411 if (
simulator_.gridView().comm().size() > 1) {
427 const auto& eclWell = well.wellEcl();
428 std::size_t well_index =
simulator_.problem().wellModel().wellState().index(well.name()).value();
429 const auto& ws =
simulator_.problem().wellModel().wellState().well(well_index);
431 for (std::size_t i = 0; i < ws.perf_data.size(); ++i) {
432 const auto globI = ws.perf_data.cell_index[i];
434 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
435 if (!FluidSystem::phaseIsActive(phaseIdx)) {
439 Evaluation rate = well.volumetricSurfaceRateForConnection(globI, phaseIdx);
440 if (rate > 0 && eclWell.isInjector()) {
441 fs.setTemperature(eclWell.inj_temperature());
442 const auto& rho = FluidSystem::density(fs, phaseIdx, fs.pvtRegionIndex());
443 fs.setDensity(phaseIdx, rho);
444 const auto& h = FluidSystem::enthalpy(fs, phaseIdx, fs.pvtRegionIndex());
445 fs.setEnthalpy(phaseIdx, h);
446 rate *= getValue(fs.enthalpy(phaseIdx)) * getValue(fs.density(phaseIdx)) / getValue(fs.invB(phaseIdx));
448 const Evaluation d = 1.0 - fs.Rv() * fs.Rs();
449 if (phaseIdx == gasPhaseIdx && d > 0) {
450 const auto& oilrate = well.volumetricSurfaceRateForConnection(globI, oilPhaseIdx);
451 rate -= oilrate * getValue(fs.Rs());
454 if (phaseIdx == oilPhaseIdx && d > 0) {
455 const auto& gasrate = well.volumetricSurfaceRateForConnection(globI, gasPhaseIdx);
456 rate -= gasrate * getValue(fs.Rv());
459 rate *= fs.enthalpy(phaseIdx) * getValue(fs.density(phaseIdx)) / getValue(fs.invB(phaseIdx));
462 rate *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
464 (*this->
energyMatrix_)[globI][globI][0][0] -= rate.derivative(Indices::temperatureIdx);
477template <
class TypeTag>
492 template <
class Restarter>
502 template <
class Restarter>
Contains the high level supplements required to extend the black oil model by energy.
Definition: blackoilenergymodules.hh:60
Definition: GenericTemperatureModel.hpp:52
Opm::GenericTemperatureModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::energyVector_ EnergyVector energyVector_
Definition: GenericTemperatureModel.hpp:87
Opm::GenericTemperatureModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::energy_rates_ std::vector< GetPropType< TypeTag, Properties::Scalar > > energy_rates_
Definition: GenericTemperatureModel.hpp:90
Opm::GenericTemperatureModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::energyMatrix_ std::unique_ptr< EnergyMatrix > energyMatrix_
Definition: GenericTemperatureModel.hpp:88
Opm::GenericTemperatureModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::EnergyMatrix Dune::BCRSMatrix< Opm::MatrixBlock< GetPropType< TypeTag, Properties::Scalar >, 1, 1 > > EnergyMatrix
Definition: GenericTemperatureModel.hpp:54
Opm::GenericTemperatureModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::linearSolve_ bool linearSolve_(const EnergyMatrix &M, EnergyVector &x, EnergyVector &b)
Definition: GenericTemperatureModel_impl.hpp:165
Opm::GenericTemperatureModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::EnergyVector Dune::BlockVector< Dune::FieldVector< GetPropType< TypeTag, Properties::Scalar >, 1 > > EnergyVector
Definition: GenericTemperatureModel.hpp:55
Opm::GenericTemperatureModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::doTemp bool doTemp()
Definition: GenericTemperatureModel.hpp:59
Opm::GenericTemperatureModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::doInit void doInit(std::size_t numGridDof)
Initialize all internal data structures needed by the temperature module.
Definition: GenericTemperatureModel_impl.hpp:115
Opm::GenericTemperatureModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::maxTempChange_ GetPropType< TypeTag, Properties::Scalar > maxTempChange_
Definition: GenericTemperatureModel.hpp:92
Opm::GenericTemperatureModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::temperature_ std::vector< GetPropType< TypeTag, Properties::Scalar > > temperature_
Definition: GenericTemperatureModel.hpp:89
void beginTimeStep()
Definition: TemperatureModel.hpp:507
void init()
Definition: TemperatureModel.hpp:506
const Scalar temperature(size_t) const
Definition: TemperatureModel.hpp:508
void deserialize(Restarter &)
This method restores the complete state of the temperature from disk.
Definition: TemperatureModel.hpp:503
void serialize(Restarter &)
This method writes the complete state of all temperature to the hard disk.
Definition: TemperatureModel.hpp:493
TemperatureModel(Simulator &)
Definition: TemperatureModel.hpp:485
A class which handles sequential implicit solution of the energy equation as specified in by TEMP.
Definition: TemperatureModel.hpp:72
void serialize(Restarter &)
This method writes the complete state of all temperature to the hard disk.
Definition: TemperatureModel.hpp:188
void assembleEquationWell(const Well &well)
Definition: TemperatureModel.hpp:425
std::vector< int > interiorRows_
Definition: TemperatureModel.hpp:473
EnergyVector storage1_
Definition: TemperatureModel.hpp:470
bool converged(const int iter)
Definition: TemperatureModel.hpp:249
void computeHeatFluxTerm(unsigned globI, unsigned globJ, const ResidualNBInfo &res_nbinfo, Evaluation &heatFlux)
Definition: TemperatureModel.hpp:337
void computeStorageTerm(unsigned globI, LhsEval &storage)
Definition: TemperatureModel.hpp:275
void deserialize(Restarter &)
This method restores the complete state of the temperature from disk.
Definition: TemperatureModel.hpp:198
void endTimeStep(WellStateType &wellState)
Informs the temperature model that a time step has just been finished.
Definition: TemperatureModel.hpp:160
const Simulator & simulator_
Definition: TemperatureModel.hpp:469
void beginTimeStep()
Definition: TemperatureModel.hpp:138
void advanceTemperatureFields()
Definition: TemperatureModel.hpp:216
void updateStorageCache()
Definition: TemperatureModel.hpp:202
void assembleEquations()
Definition: TemperatureModel.hpp:361
void solveAndUpdate()
Definition: TemperatureModel.hpp:230
std::vector< IntensiveQuantities > intQuants_
Definition: TemperatureModel.hpp:471
void computeFluxTerm(unsigned globI, unsigned globJ, const ResidualNBInfo &res_nbinfo, Evaluation &flux)
Definition: TemperatureModel.hpp:301
std::vector< int > overlapRows_
Definition: TemperatureModel.hpp:472
TemperatureModel(Simulator &simulator)
Definition: TemperatureModel.hpp:106
void init()
Definition: TemperatureModel.hpp:114
Definition: WellState.hpp:66
int numWells() const
Definition: WellState.hpp:99
const SingleWellState< Scalar, IndexTraits > & well(std::size_t well_index) const
Definition: WellState.hpp:290
Provides data handles for parallel communication which operate on DOFs.
Definition: blackoilmodel.hh:80
void findOverlapAndInterior(const Grid &grid, const Mapper &mapper, std::vector< int > &overlapRows, std::vector< int > &interiorRows)
Find the rows corresponding to overlap cells.
Definition: findOverlapRowsAndColumns.hpp:92
Definition: blackoilbioeffectsmodules.hh:43
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.
Definition: TemperatureModel.hpp:50
a tag to mark properties as undefined
Definition: propertysystem.hh:38