blackoilenergymodules.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_ENERGY_MODULE_HH
29#define EWOMS_BLACK_OIL_ENERGY_MODULE_HH
30
31#include <dune/common/fvector.hh>
32
33#include <opm/common/ErrorMacros.hpp>
34#include <opm/common/utility/gpuDecorators.hpp>
35
36#include <opm/material/common/Tabulated1DFunction.hpp>
37#include <opm/material/common/Valgrind.hpp>
38#include <opm/material/fluidstates/BlackOilFluidState.hpp>
39
45#include <opm/material/thermal/EnergyModuleType.hpp>
46
47#include <cassert>
48#include <cmath>
49#include <istream>
50#include <memory>
51#include <ostream>
52#include <stdexcept>
53#include <string>
54
55
56namespace Opm {
57
63template <class TypeTag>
64class BlackOilEnergyModule<TypeTag, EnergyModules::FullyImplicitThermal>
65{
77
78 static constexpr unsigned temperatureIdx = Indices::temperatureIdx;
79 static constexpr unsigned contiEnergyEqIdx = Indices::contiEnergyEqIdx;
80
81 static constexpr unsigned enableFullyImplicitThermal = true;
82 static constexpr unsigned numEq = getPropValue<TypeTag, Properties::NumEq>();
83 static constexpr unsigned numPhases = FluidSystem::numPhases;
84
85public:
87
91 static void registerParameters()
92 {
94 }
95
99 static void registerOutputModules(Model& model,
100 Simulator& simulator)
101 {
102 model.addOutputModule(std::make_unique<VtkBlackOilEnergyModule<TypeTag>>(simulator));
103 }
104
105 static OPM_HOST_DEVICE bool primaryVarApplies(unsigned pvIdx)
106 {
107 return pvIdx == temperatureIdx;
108 }
109
110 static std::string primaryVarName([[maybe_unused]] unsigned pvIdx)
111 {
112 assert(primaryVarApplies(pvIdx));
113
114 return "temperature";
115 }
116
117 static Scalar primaryVarWeight([[maybe_unused]] unsigned pvIdx)
118 {
119 assert(primaryVarApplies(pvIdx));
120
121 // TODO: it may be beneficial to chose this differently.
122 return static_cast<Scalar>(1.0);
123 }
124
125 static OPM_HOST_DEVICE bool eqApplies(unsigned eqIdx)
126 {
127 return eqIdx == contiEnergyEqIdx;
128 }
129
130 static std::string eqName([[maybe_unused]] unsigned eqIdx)
131 {
132 assert(eqApplies(eqIdx));
133
134 return "conti^energy";
135 }
136
137 static Scalar eqWeight([[maybe_unused]] unsigned eqIdx)
138 {
139 assert(eqApplies(eqIdx));
140
141 return 1.0;
142 }
143
144 // must be called after water storage is computed
145 template <class StorageType>
146 OPM_HOST_DEVICE static void addStorage(StorageType& storage,
147 const IntensiveQuantities& intQuants)
148 {
149 using LhsEval = typename StorageType::value_type;
150 const FluidSystem& fsys = intQuants.getFluidSystem();
151
152 const auto& poro = decay<LhsEval>(intQuants.porosity());
153
154 // accumulate the internal energy of the fluids
155 const auto& fs = intQuants.fluidState();
156 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
157 if (!fsys.phaseIsActive(phaseIdx)) {
158 continue;
159 }
160
161 const auto& u = decay<LhsEval>(fs.internalEnergy(phaseIdx));
162 const auto& S = decay<LhsEval>(fs.saturation(phaseIdx));
163 const auto& rho = decay<LhsEval>(fs.density(phaseIdx));
164
165 storage[contiEnergyEqIdx] += poro*S*u*rho;
166 }
167
168 // add the internal energy of the rock
169 const Scalar rockFraction = intQuants.rockFraction();
170 const auto& uRock = decay<LhsEval>(intQuants.rockInternalEnergy());
171 storage[contiEnergyEqIdx] += rockFraction * uRock;
172 storage[contiEnergyEqIdx] *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
173 }
174
175 OPM_HOST_DEVICE static void computeFlux(RateVector& flux,
176 const ElementContext& elemCtx,
177 unsigned scvfIdx,
178 unsigned timeIdx)
179 {
180 flux[contiEnergyEqIdx] = 0.0;
181
182 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
183 const unsigned focusIdx = elemCtx.focusDofIndex();
184 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
185 if (!FluidSystem::phaseIsActive(phaseIdx)) {
186 continue;
187 }
188
189 const unsigned upIdx = extQuants.upstreamIndex(phaseIdx);
190 if (upIdx == focusIdx) {
191 addPhaseEnthalpyFlux_<Evaluation>(flux, phaseIdx, elemCtx, scvfIdx, timeIdx);
192 }
193 else {
194 addPhaseEnthalpyFlux_<Scalar>(flux, phaseIdx, elemCtx, scvfIdx, timeIdx);
195 }
196 }
197
198 // diffusive energy flux
199 flux[contiEnergyEqIdx] += extQuants.energyFlux();
200 flux[contiEnergyEqIdx] *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
201 }
202
203 template<class RateVectorT>
204 OPM_HOST_DEVICE static void addHeatFlux(RateVectorT& flux,
205 const Evaluation& heatFlux)
206 {
207 // diffusive energy flux
208 flux[contiEnergyEqIdx] += heatFlux;
209 flux[contiEnergyEqIdx] *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
210 }
211
212 template <class UpEval, class RateVectorT, class Eval, class FluidState>
213 OPM_HOST_DEVICE static void addPhaseEnthalpyFluxes_(RateVectorT& flux,
214 unsigned phaseIdx,
215 const Eval& volumeFlux,
216 const FluidState& upFs)
217 {
218 flux[contiEnergyEqIdx] +=
219 decay<UpEval>(upFs.enthalpy(phaseIdx)) *
220 decay<UpEval>(upFs.density(phaseIdx)) *
221 volumeFlux;
222 }
223
224 template <class UpstreamEval>
225 OPM_HOST_DEVICE static void addPhaseEnthalpyFlux_(RateVector& flux,
226 unsigned phaseIdx,
227 const ElementContext& elemCtx,
228 unsigned scvfIdx,
229 unsigned timeIdx)
230 {
231 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
232 const unsigned upIdx = extQuants.upstreamIndex(phaseIdx);
233 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
234 const auto& fs = up.fluidState();
235 const auto& volFlux = extQuants.volumeFlux(phaseIdx);
236 addPhaseEnthalpyFluxes_<UpstreamEval>(flux,
237 phaseIdx,
238 volFlux,
239 fs);
240 }
241
242 OPM_HOST_DEVICE static void addToEnthalpyRate(RateVector& flux,
243 const Evaluation& hRate)
244 {
245 flux[contiEnergyEqIdx] += hRate;
246 }
247
251 template <class FluidState>
252 OPM_HOST_DEVICE static void assignPrimaryVars(PrimaryVariables& priVars,
253 const FluidState& fluidState)
254 {
255 priVars[temperatureIdx] = getValue(fluidState.temperature(/*phaseIdx=*/0));
256 }
257
261 OPM_HOST_DEVICE static void updatePrimaryVars(PrimaryVariables& newPv,
262 const PrimaryVariables& oldPv,
263 const EqVector& delta)
264 {
265 // do a plain unchopped Newton update
266 newPv[temperatureIdx] = oldPv[temperatureIdx] - delta[temperatureIdx];
267 }
268
272 OPM_HOST_DEVICE static Scalar computeUpdateError(const PrimaryVariables&,
273 const EqVector&)
274 {
275 // do not consider consider the cange of energy primary variables for
276 // convergence
277 // TODO: maybe this should be changed
278 return static_cast<Scalar>(0.0);
279 }
280
284 OPM_HOST_DEVICE static Scalar computeResidualError(const EqVector& resid)
285 {
286 // do not weight the residual of energy when it comes to convergence
287 return std::abs(scalarValue(resid[contiEnergyEqIdx]));
288 }
289
290 template <class DofEntity>
291 static void serializeEntity(const Model& model, std::ostream& outstream, const DofEntity& dof)
292 {
293 const unsigned dofIdx = model.dofMapper().index(dof);
294 const PrimaryVariables& priVars = model.solution(/*timeIdx=*/0)[dofIdx];
295 outstream << priVars[temperatureIdx];
296 }
297
298 template <class DofEntity>
299 static void deserializeEntity(Model& model, std::istream& instream, const DofEntity& dof)
300 {
301 const unsigned dofIdx = model.dofMapper().index(dof);
302 PrimaryVariables& priVars0 = model.solution(/*timeIdx=*/0)[dofIdx];
303 PrimaryVariables& priVars1 = model.solution(/*timeIdx=*/1)[dofIdx];
304
305 instream >> priVars0[temperatureIdx];
306
307 // set the primary variables for the beginning of the current time step.
308 priVars1 = priVars0[temperatureIdx];
309 }
310};
311
319template <class TypeTag>
320class BlackOilEnergyIntensiveQuantities<TypeTag, EnergyModules::FullyImplicitThermal>
321{
323
333
334 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
335 static constexpr unsigned temperatureIdx = Indices::temperatureIdx;
336
337public:
341 BlackOilEnergyIntensiveQuantities(Evaluation rockInternalEnergy,
342 Evaluation totalThermalConductivity,
343 Scalar rockFraction)
344 : rockInternalEnergy_(rockInternalEnergy)
345 , totalThermalConductivity_(totalThermalConductivity)
346 , rockFraction_(rockFraction)
347 {
348 }
349
350 template <class OtherTypeTag>
353 : rockInternalEnergy_(other.rockInternalEnergy())
354 , totalThermalConductivity_(other.totalThermalConductivity())
355 , rockFraction_(other.rockFraction())
356 {}
357
359
364 OPM_HOST_DEVICE void updateTemperature_(const ElementContext& elemCtx,
365 unsigned dofIdx,
366 unsigned timeIdx)
367 {
368 auto& fs = asImp_().fluidState_;
369 const auto& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
370
371 // set temperature
372 fs.setTemperature(priVars.makeEvaluation(temperatureIdx, timeIdx, elemCtx.linearizationType()));
373 }
374
379 OPM_HOST_DEVICE void updateTemperature_([[maybe_unused]] const Problem& problem,
380 const PrimaryVariables& priVars,
381 [[maybe_unused]] unsigned globalDofIdx,
382 const unsigned timeIdx,
383 const LinearizationType& lintype)
384 {
385 auto& fs = asImp_().fluidState_;
386 fs.setTemperature(priVars.makeEvaluation(temperatureIdx, timeIdx, lintype));
387 }
388
393 OPM_HOST_DEVICE void updateEnergyQuantities_(const ElementContext& elemCtx,
394 unsigned dofIdx,
395 unsigned timeIdx)
396 {
397 updateEnergyQuantities_(elemCtx.problem(), elemCtx.globalSpaceIndex(dofIdx, timeIdx), timeIdx);
398 }
399
400 OPM_HOST_DEVICE void updateEnergyQuantities_(const Problem& problem,
401 const unsigned globalSpaceIdx,
402 const unsigned timeIdx)
403 {
404 auto& fs = asImp_().fluidState_;
405
406 // compute the specific enthalpy of the fluids, the specific enthalpy of the rock
407 // and the thermal conductivity coefficients
408 for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
409 if (!asImp_().getFluidSystem().phaseIsActive(phaseIdx)) {
410 continue;
411 }
412
413 const auto& h = asImp_().getFluidSystem().enthalpy(fs, phaseIdx, problem.pvtRegionIndex(globalSpaceIdx));
414 fs.setEnthalpy(phaseIdx, h);
415 }
416
417 const auto& solidEnergyLawParams = problem.solidEnergyLawParams(globalSpaceIdx, timeIdx);
418 rockInternalEnergy_ = SolidEnergyLaw::solidInternalEnergy(solidEnergyLawParams, fs);
419
420 const auto& thermalConductionLawParams = problem.thermalConductionLawParams(globalSpaceIdx, timeIdx);
421 totalThermalConductivity_ = ThermalConductionLaw::thermalConductivity(thermalConductionLawParams, fs);
422
423 // Retrieve the rock fraction from the problem
424 // Usually 1 - porosity, but if pvmult is used to modify porosity
425 // we will apply the same multiplier to the rock fraction
426 // i.e. pvmult*(1 - porosity) and thus interpret multpv as a volume
427 // multiplier. This is to avoid negative rock volume for pvmult*porosity > 1
428 rockFraction_ = problem.rockFraction(globalSpaceIdx, timeIdx);
429 }
430
431 OPM_HOST_DEVICE const Evaluation& rockInternalEnergy() const
432 { return rockInternalEnergy_; }
433
434 OPM_HOST_DEVICE const Evaluation& totalThermalConductivity() const
435 { return totalThermalConductivity_; }
436
437 OPM_HOST_DEVICE Scalar rockFraction() const
438 { return rockFraction_; }
439
440protected:
441 OPM_HOST_DEVICE Implementation& asImp_()
442 { return *static_cast<Implementation*>(this); }
443
447};
448
449template <class TypeTag>
450class BlackOilEnergyIntensiveQuantities<TypeTag, EnergyModules::ConstantTemperature>
451{
458
460
461public:
462
463 OPM_HOST_DEVICE void updateTemperature_(const ElementContext& elemCtx,
464 unsigned dofIdx,
465 unsigned timeIdx)
466 {
467 updateTemperature_(elemCtx.problem(), elemCtx.globalSpaceIndex(dofIdx, timeIdx), timeIdx);
468 }
469
470 template<class Problem>
471 OPM_HOST_DEVICE void updateTemperature_(const Problem& problem,
472 [[maybe_unused]] const PrimaryVariables& priVars,
473 unsigned globalDofIdx,
474 unsigned timeIdx,
475 [[maybe_unused]] const LinearizationType& lintype)
476 {
477 updateTemperature_(problem, globalDofIdx, timeIdx);
478 }
479
480 OPM_HOST_DEVICE void updateTemperature_(const Problem& problem,
481 unsigned globalDofIdx,
482 unsigned timeIdx)
483 {
484 auto& fs = asImp_().fluidState_;
485 const Scalar T = problem.temperature(globalDofIdx, timeIdx);
486 fs.setTemperature(T);
487 }
488
489 OPM_HOST_DEVICE void updateEnergyQuantities_(const ElementContext&,
490 unsigned,
491 unsigned,
492 const typename FluidSystem::template ParameterCache<Evaluation>&)
493 {}
494
495 OPM_HOST_DEVICE const Evaluation& rockInternalEnergy() const
496 {
497 OPM_THROW(std::logic_error,
498 "Requested the rock internal energy, which is "
499 "unavailable because energy is not conserved");
500 }
501
502 OPM_HOST_DEVICE const Evaluation& totalThermalConductivity() const
503 {
504 OPM_THROW(std::logic_error,
505 "Requested the total thermal conductivity, which is "
506 "unavailable because energy is not conserved");
507 }
508
509protected:
510 OPM_HOST_DEVICE Implementation& asImp_()
511 { return *static_cast<Implementation*>(this); }
512};
513
514template <class TypeTag>
515class BlackOilEnergyIntensiveQuantities<TypeTag, EnergyModules::SequentialImplicitThermal>
516{
527
528public:
529
530 OPM_HOST_DEVICE void updateTemperature_(const Problem& problem,
531 unsigned globalDofIdx,
532 unsigned timeIdx)
533 {
534 // update the temperature for output (without derivatives)
535 auto& fs = asImp_().fluidState_;
536 fs.setTemperature(problem.temperature(globalDofIdx, timeIdx));
537 }
538
539 OPM_HOST_DEVICE void updateTemperature_(const ElementContext& elemCtx,
540 unsigned dofIdx,
541 unsigned timeIdx)
542 {
543 updateTemperature_(elemCtx.problem(), elemCtx.globalSpaceIndex(dofIdx, timeIdx), timeIdx);
544 }
545
546 template<class Problem>
547 OPM_HOST_DEVICE void updateTemperature_(const Problem& problem,
548 [[maybe_unused]] const PrimaryVariables& priVars,
549 unsigned globalDofIdx,
550 unsigned timeIdx,
551 [[maybe_unused]] const LinearizationType& lintype)
552 {
553 updateTemperature_(problem, globalDofIdx, timeIdx);
554 }
555
560 OPM_HOST_DEVICE void updateEnergyQuantities_([[maybe_unused]] const ElementContext& elemCtx,
561 [[maybe_unused]] unsigned dofIdx,
562 [[maybe_unused]] unsigned timeIdx)
563 {
564 }
565
566 OPM_HOST_DEVICE void updateEnergyQuantities_([[maybe_unused]] const Problem& problem,
567 [[maybe_unused]] const unsigned globalSpaceIdx,
568 [[maybe_unused]] const unsigned timeIdx)
569 {
570 }
571
572 OPM_HOST_DEVICE const Evaluation& rockInternalEnergy() const
573 {
574 OPM_THROW(std::logic_error,
575 "Requested the rock internal energy, which is "
576 "unavailable because energy is not conserved");
577 }
578
579 OPM_HOST_DEVICE const Evaluation& totalThermalConductivity() const
580 {
581 OPM_THROW(std::logic_error,
582 "Requested the total thermal conductivity, which is "
583 "unavailable because energy is not conserved");
584 }
585
586protected:
587 OPM_HOST_DEVICE Implementation& asImp_()
588 { return *static_cast<Implementation*>(this); }
589
590};
591
599template <class TypeTag>
600class BlackOilEnergyExtensiveQuantities<TypeTag, EnergyModules::FullyImplicitThermal>
601{
603
607
608public:
609 template<class Evaluation, class FluidState, class IntensiveQuantities>
610 OPM_HOST_DEVICE static void updateEnergy(Evaluation& energyFlux,
611 const unsigned& focusDofIndex,
612 const unsigned& inIdx,
613 const unsigned& exIdx,
614 const IntensiveQuantities& inIq,
615 const IntensiveQuantities& exIq,
616 const FluidState& inFs,
617 const FluidState& exFs,
618 const Scalar& inAlpha,
619 const Scalar& outAlpha,
620 const Scalar& faceArea)
621 {
622 Evaluation deltaT;
623 if (focusDofIndex == inIdx) {
624 deltaT = decay<Scalar>(exFs.temperature(/*phaseIdx=*/0)) -
625 inFs.temperature(/*phaseIdx=*/0);
626 }
627 else if (focusDofIndex == exIdx) {
628 deltaT = exFs.temperature(/*phaseIdx=*/0) -
629 decay<Scalar>(inFs.temperature(/*phaseIdx=*/0));
630 }
631 else {
632 deltaT = decay<Scalar>(exFs.temperature(/*phaseIdx=*/0)) -
633 decay<Scalar>(inFs.temperature(/*phaseIdx=*/0));
634 }
635
636 Evaluation inLambda;
637 if (focusDofIndex == inIdx) {
638 inLambda = inIq.totalThermalConductivity();
639 }
640 else {
641 inLambda = decay<Scalar>(inIq.totalThermalConductivity());
642 }
643
644 Evaluation exLambda;
645 if (focusDofIndex == exIdx) {
646 exLambda = exIq.totalThermalConductivity();
647 }
648 else {
649 exLambda = decay<Scalar>(exIq.totalThermalConductivity());
650 }
651
652 Evaluation H;
653 const Evaluation& inH = inLambda*inAlpha;
654 const Evaluation& exH = exLambda*outAlpha;
655 if (inH > 0 && exH > 0) {
656 // compute the "thermal transmissibility". In contrast to the normal
657 // transmissibility this cannot be done as a preprocessing step because the
658 // average thermal conductivity is analogous to the permeability but
659 // depends on the solution.
660 H = 1.0 / (1.0 / inH + 1.0 / exH);
661 }
662 else {
663 H = 0.0;
664 }
665
666 energyFlux = deltaT * (-H / faceArea);
667 }
668
669 void updateEnergy(const ElementContext& elemCtx,
670 unsigned scvfIdx,
671 unsigned timeIdx)
672 {
673 const auto& stencil = elemCtx.stencil(timeIdx);
674 const auto& scvf = stencil.interiorFace(scvfIdx);
675
676 const Scalar faceArea = scvf.area();
677 const unsigned inIdx = scvf.interiorIndex();
678 const unsigned exIdx = scvf.exteriorIndex();
679 const auto& inIq = elemCtx.intensiveQuantities(inIdx, timeIdx);
680 const auto& exIq = elemCtx.intensiveQuantities(exIdx, timeIdx);
681 const auto& inFs = inIq.fluidState();
682 const auto& exFs = exIq.fluidState();
683 const Scalar inAlpha = elemCtx.problem().thermalHalfTransmissibilityIn(elemCtx, scvfIdx, timeIdx);
684 const Scalar outAlpha = elemCtx.problem().thermalHalfTransmissibilityOut(elemCtx, scvfIdx, timeIdx);
685 updateEnergy(energyFlux_,
686 elemCtx.focusDofIndex(),
687 inIdx,
688 exIdx,
689 inIq,
690 exIq,
691 inFs,
692 exFs,
693 inAlpha,
694 outAlpha,
695 faceArea);
696 }
697
698 template <class Context, class BoundaryFluidState>
699 void updateEnergyBoundary(const Context& ctx,
700 unsigned scvfIdx,
701 unsigned timeIdx,
702 const BoundaryFluidState& boundaryFs)
703 {
704 const auto& stencil = ctx.stencil(timeIdx);
705 const auto& scvf = stencil.boundaryFace(scvfIdx);
706
707 const unsigned inIdx = scvf.interiorIndex();
708 const auto& inIq = ctx.intensiveQuantities(inIdx, timeIdx);
709 const auto& focusDofIdx = ctx.focusDofIndex();
710 const Scalar alpha = ctx.problem().thermalHalfTransmissibilityBoundary(ctx, scvfIdx);
711 updateEnergyBoundary(energyFlux_, inIq, focusDofIdx, inIdx, alpha, boundaryFs);
712 }
713
714 template <class Evaluation, class BoundaryFluidState, class IntensiveQuantities>
715 OPM_HOST_DEVICE static void updateEnergyBoundary(Evaluation& energyFlux,
716 const IntensiveQuantities& inIq,
717 unsigned focusDofIndex,
718 unsigned inIdx,
719 Scalar alpha,
720 const BoundaryFluidState& boundaryFs)
721 {
722 const auto& inFs = inIq.fluidState();
723 Evaluation deltaT;
724 if (focusDofIndex == inIdx) {
725 deltaT = boundaryFs.temperature(/*phaseIdx=*/0) -
726 inFs.temperature(/*phaseIdx=*/0);
727 }
728 else {
729 deltaT = decay<Scalar>(boundaryFs.temperature(/*phaseIdx=*/0)) -
730 decay<Scalar>(inFs.temperature(/*phaseIdx=*/0));
731 }
732
733 Evaluation lambda;
734 if (focusDofIndex == inIdx) {
735 lambda = inIq.totalThermalConductivity();
736 }
737 else {
738 lambda = decay<Scalar>(inIq.totalThermalConductivity());
739 }
740
741 if (lambda > 0.0) {
742 // compute the "thermal transmissibility". In contrast to the normal
743 // transmissibility this cannot be done as a preprocessing step because the
744 // average thermal conductivity is analogous to the permeability but depends
745 // on the solution.
746 energyFlux = deltaT * lambda * -alpha;
747 }
748 else {
749 energyFlux = 0.0;
750 }
751 }
752
753 const Evaluation& energyFlux() const
754 { return energyFlux_; }
755
756private:
757 Implementation& asImp_()
758 { return *static_cast<Implementation*>(this); }
759
760 Evaluation energyFlux_;
761};
762
763template <class TypeTag>
764class BlackOilEnergyExtensiveQuantities<TypeTag, EnergyModules::SequentialImplicitThermal>
765{
769
770public:
771 template<class Evaluation, class FluidState, class IntensiveQuantities>
772 static void updateEnergy(Evaluation& energyFlux,
773 const unsigned& focusDofIndex,
774 const unsigned& inIdx,
775 const unsigned& exIdx,
776 const IntensiveQuantities& inIq,
777 const IntensiveQuantities& exIq,
778 const FluidState& inFs,
779 const FluidState& exFs,
780 const Scalar& inAlpha,
781 const Scalar& outAlpha,
782 const Scalar& faceArea)
783 {
784 // Uses the same caculations as the FullyImplicitThermal approach
786 focusDofIndex,
787 inIdx,
788 exIdx,
789 inIq,
790 exIq,
791 inFs,
792 exFs,
793 inAlpha,
794 outAlpha,
795 faceArea);
796 }
797
798 void updateEnergy(const ElementContext&,
799 unsigned,
800 unsigned)
801 { } // Old interface still used output code for fluxes. But energy flux is not used. i.e. do nothing
802
803 template <class Context, class BoundaryFluidState>
804 void updateEnergyBoundary(const Context&,
805 unsigned,
806 unsigned,
807 const BoundaryFluidState&)
808 { }
809
810 template <class Evaluation, class BoundaryFluidState, class IntensiveQuantities>
811 static void updateEnergyBoundary(Evaluation& /*heatFlux*/,
812 const IntensiveQuantities& /*inIq*/,
813 unsigned /*focusDofIndex*/,
814 unsigned /*inIdx*/,
815 unsigned /*timeIdx*/,
816 Scalar /*alpha*/,
817 const BoundaryFluidState& /*boundaryFs*/)
818 { }
819
820 OPM_HOST_DEVICE const Evaluation& energyFlux() const
821 { OPM_THROW(std::logic_error, "Requested the energy flux, but energy is not conserved"); }
822};
823
824} // namespace Opm
825
826#endif
Contains classes extending the black-oil model. \detail This file holds dummy definitions,...
Declares the properties required by the black oil model.
static OPM_HOST_DEVICE void updateEnergy(Evaluation &energyFlux, const unsigned &focusDofIndex, const unsigned &inIdx, const unsigned &exIdx, const IntensiveQuantities &inIq, const IntensiveQuantities &exIq, const FluidState &inFs, const FluidState &exFs, const Scalar &inAlpha, const Scalar &outAlpha, const Scalar &faceArea)
Definition: blackoilenergymodules.hh:610
const Evaluation & energyFlux() const
Definition: blackoilenergymodules.hh:753
void updateEnergyBoundary(const Context &ctx, unsigned scvfIdx, unsigned timeIdx, const BoundaryFluidState &boundaryFs)
Definition: blackoilenergymodules.hh:699
void updateEnergy(const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilenergymodules.hh:669
static OPM_HOST_DEVICE void updateEnergyBoundary(Evaluation &energyFlux, const IntensiveQuantities &inIq, unsigned focusDofIndex, unsigned inIdx, Scalar alpha, const BoundaryFluidState &boundaryFs)
Definition: blackoilenergymodules.hh:715
static void updateEnergyBoundary(Evaluation &, const IntensiveQuantities &, unsigned, unsigned, unsigned, Scalar, const BoundaryFluidState &)
Definition: blackoilenergymodules.hh:811
static void updateEnergy(Evaluation &energyFlux, const unsigned &focusDofIndex, const unsigned &inIdx, const unsigned &exIdx, const IntensiveQuantities &inIq, const IntensiveQuantities &exIq, const FluidState &inFs, const FluidState &exFs, const Scalar &inAlpha, const Scalar &outAlpha, const Scalar &faceArea)
Definition: blackoilenergymodules.hh:772
void updateEnergy(const ElementContext &, unsigned, unsigned)
Definition: blackoilenergymodules.hh:798
OPM_HOST_DEVICE const Evaluation & energyFlux() const
Definition: blackoilenergymodules.hh:820
void updateEnergyBoundary(const Context &, unsigned, unsigned, const BoundaryFluidState &)
Definition: blackoilenergymodules.hh:804
Provides the energy specific extensive quantities to the generic black-oil module's extensive quantit...
Definition: blackoilmodules.hpp:73
OPM_HOST_DEVICE const Evaluation & totalThermalConductivity() const
Definition: blackoilenergymodules.hh:502
OPM_HOST_DEVICE Implementation & asImp_()
Definition: blackoilenergymodules.hh:510
OPM_HOST_DEVICE const Evaluation & rockInternalEnergy() const
Definition: blackoilenergymodules.hh:495
OPM_HOST_DEVICE void updateEnergyQuantities_(const ElementContext &, unsigned, unsigned, const typename FluidSystem::template ParameterCache< Evaluation > &)
Definition: blackoilenergymodules.hh:489
OPM_HOST_DEVICE void updateTemperature_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Definition: blackoilenergymodules.hh:463
OPM_HOST_DEVICE void updateTemperature_(const Problem &problem, const PrimaryVariables &priVars, unsigned globalDofIdx, unsigned timeIdx, const LinearizationType &lintype)
Definition: blackoilenergymodules.hh:471
OPM_HOST_DEVICE void updateTemperature_(const Problem &problem, unsigned globalDofIdx, unsigned timeIdx)
Definition: blackoilenergymodules.hh:480
OPM_HOST_DEVICE void updateEnergyQuantities_(const Problem &problem, const unsigned globalSpaceIdx, const unsigned timeIdx)
Definition: blackoilenergymodules.hh:400
BlackOilEnergyIntensiveQuantities(const BlackOilEnergyIntensiveQuantities< OtherTypeTag, EnergyModules::FullyImplicitThermal > &other)
Definition: blackoilenergymodules.hh:351
OPM_HOST_DEVICE Scalar rockFraction() const
Definition: blackoilenergymodules.hh:437
OPM_HOST_DEVICE const Evaluation & totalThermalConductivity() const
Definition: blackoilenergymodules.hh:434
OPM_HOST_DEVICE Implementation & asImp_()
Definition: blackoilenergymodules.hh:441
OPM_HOST_DEVICE void updateTemperature_(const Problem &problem, const PrimaryVariables &priVars, unsigned globalDofIdx, const unsigned timeIdx, const LinearizationType &lintype)
Update the temperature of the intensive quantity's fluid state.
Definition: blackoilenergymodules.hh:379
OPM_HOST_DEVICE void updateEnergyQuantities_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Compute the intensive quantities needed to handle energy conservation.
Definition: blackoilenergymodules.hh:393
Evaluation totalThermalConductivity_
Definition: blackoilenergymodules.hh:445
BlackOilEnergyIntensiveQuantities(Evaluation rockInternalEnergy, Evaluation totalThermalConductivity, Scalar rockFraction)
Construct the energy intensive quantities for the fully implicit thermal module.
Definition: blackoilenergymodules.hh:341
OPM_HOST_DEVICE void updateTemperature_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Update the temperature of the intensive quantity's fluid state.
Definition: blackoilenergymodules.hh:364
OPM_HOST_DEVICE const Evaluation & rockInternalEnergy() const
Definition: blackoilenergymodules.hh:431
OPM_HOST_DEVICE void updateTemperature_(const Problem &problem, const PrimaryVariables &priVars, unsigned globalDofIdx, unsigned timeIdx, const LinearizationType &lintype)
Definition: blackoilenergymodules.hh:547
OPM_HOST_DEVICE const Evaluation & totalThermalConductivity() const
Definition: blackoilenergymodules.hh:579
OPM_HOST_DEVICE void updateEnergyQuantities_(const Problem &problem, const unsigned globalSpaceIdx, const unsigned timeIdx)
Definition: blackoilenergymodules.hh:566
OPM_HOST_DEVICE const Evaluation & rockInternalEnergy() const
Definition: blackoilenergymodules.hh:572
OPM_HOST_DEVICE void updateTemperature_(const Problem &problem, unsigned globalDofIdx, unsigned timeIdx)
Definition: blackoilenergymodules.hh:530
OPM_HOST_DEVICE Implementation & asImp_()
Definition: blackoilenergymodules.hh:587
OPM_HOST_DEVICE void updateTemperature_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Definition: blackoilenergymodules.hh:539
OPM_HOST_DEVICE void updateEnergyQuantities_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Compute the intensive quantities needed to handle energy conservation.
Definition: blackoilenergymodules.hh:560
Provides the volumetric quantities required for the equations needed by the energys extension of the ...
Definition: blackoilmodules.hpp:68
static Scalar primaryVarWeight(unsigned pvIdx)
Definition: blackoilenergymodules.hh:117
static OPM_HOST_DEVICE bool primaryVarApplies(unsigned pvIdx)
Definition: blackoilenergymodules.hh:105
static OPM_HOST_DEVICE Scalar computeResidualError(const EqVector &resid)
Return how much a residual is considered an error.
Definition: blackoilenergymodules.hh:284
static OPM_HOST_DEVICE void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilenergymodules.hh:175
static OPM_HOST_DEVICE void addPhaseEnthalpyFluxes_(RateVectorT &flux, unsigned phaseIdx, const Eval &volumeFlux, const FluidState &upFs)
Definition: blackoilenergymodules.hh:213
static OPM_HOST_DEVICE void addPhaseEnthalpyFlux_(RateVector &flux, unsigned phaseIdx, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilenergymodules.hh:225
static std::string primaryVarName(unsigned pvIdx)
Definition: blackoilenergymodules.hh:110
GetPropType< TypeTag, Properties::ExtensiveQuantities > ExtensiveQuantities
Definition: blackoilenergymodules.hh:86
static Scalar eqWeight(unsigned eqIdx)
Definition: blackoilenergymodules.hh:137
static void registerOutputModules(Model &model, Simulator &simulator)
Register all energy specific VTK and ECL output modules.
Definition: blackoilenergymodules.hh:99
static OPM_HOST_DEVICE void addStorage(StorageType &storage, const IntensiveQuantities &intQuants)
Definition: blackoilenergymodules.hh:146
static OPM_HOST_DEVICE void updatePrimaryVars(PrimaryVariables &newPv, const PrimaryVariables &oldPv, const EqVector &delta)
Do a Newton-Raphson update the primary variables of the energys.
Definition: blackoilenergymodules.hh:261
static OPM_HOST_DEVICE void addToEnthalpyRate(RateVector &flux, const Evaluation &hRate)
Definition: blackoilenergymodules.hh:242
static OPM_HOST_DEVICE void addHeatFlux(RateVectorT &flux, const Evaluation &heatFlux)
Definition: blackoilenergymodules.hh:204
static OPM_HOST_DEVICE Scalar computeUpdateError(const PrimaryVariables &, const EqVector &)
Return how much a Newton-Raphson update is considered an error.
Definition: blackoilenergymodules.hh:272
static void deserializeEntity(Model &model, std::istream &instream, const DofEntity &dof)
Definition: blackoilenergymodules.hh:299
static OPM_HOST_DEVICE void assignPrimaryVars(PrimaryVariables &priVars, const FluidState &fluidState)
Assign the energy specific primary variables to a PrimaryVariables object.
Definition: blackoilenergymodules.hh:252
static void serializeEntity(const Model &model, std::ostream &outstream, const DofEntity &dof)
Definition: blackoilenergymodules.hh:291
static void registerParameters()
Register all run-time parameters for the black-oil energy module.
Definition: blackoilenergymodules.hh:91
static OPM_HOST_DEVICE bool eqApplies(unsigned eqIdx)
Definition: blackoilenergymodules.hh:125
static std::string eqName(unsigned eqIdx)
Definition: blackoilenergymodules.hh:130
Definition: blackoilmodules.hpp:63
VTK output module for the black oil model's energy related quantities.
Definition: vtkblackoilenergymodule.hpp:54
static void registerParameters()
Register all run-time parameters for the multi-phase VTK output module.
Definition: vtkblackoilenergymodule.hpp:84
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
This method contains all callback classes for quantities that are required by some extensive quantiti...
Definition: linearizationtype.hh:34