28#ifndef OPM_TRACER_MODEL_HPP
29#define OPM_TRACER_MODEL_HPP
31#include <opm/common/OpmLog/OpmLog.hpp>
32#include <opm/common/TimingMacros.hpp>
34#include <opm/input/eclipse/EclipseState/Aquifer/AquiferConfig.hpp>
35#include <opm/input/eclipse/Schedule/BCState.hpp>
36#include <opm/input/eclipse/Schedule/Schedule.hpp>
37#include <opm/input/eclipse/Schedule/Well/Well.hpp>
38#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
40#include <opm/grid/utility/ElementChunks.hpp>
56#include <unordered_map>
60#include <fmt/format.h>
64template<
class TypeTag,
class MyTypeTag>
78template <
class TypeTag>
80 GetPropType<TypeTag, Properties::GridView>,
81 GetPropType<TypeTag, Properties::DofMapper>,
82 GetPropType<TypeTag, Properties::Stencil>,
83 GetPropType<TypeTag, Properties::FluidSystem>,
84 GetPropType<TypeTag, Properties::Scalar>>
102 using TracerEvaluation = DenseAd::Evaluation<Scalar,1>;
108 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
109 enum { numPhases = FluidSystem::numPhases };
110 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
111 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
112 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
116 :
BaseType(simulator.vanguard().gridView(),
117 simulator.vanguard().eclState(),
118 simulator.vanguard().cartesianIndexMapper(),
119 simulator.model().dofMapper(),
120 simulator.vanguard().cellCentroids())
122 ,
tbatch({waterPhaseIdx, oilPhaseIdx, gasPhaseIdx})
151 gasPhaseIdx, oilPhaseIdx, waterPhaseIdx);
158 for (std::size_t tracerIdx = 0; tracerIdx < this->
tracerPhaseIdx_.size(); ++tracerIdx) {
160 if (! FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)){
161 throw std::runtime_error(
"Water tracer specified for non-water fluid system: " +
162 this->
name(tracerIdx));
167 else if (this->
tracerPhaseIdx_[tracerIdx] == FluidSystem::oilPhaseIdx) {
168 if (! FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)){
169 throw std::runtime_error(
"Oil tracer specified for non-oil fluid system: " +
170 this->
name(tracerIdx));
175 else if (this->
tracerPhaseIdx_[tracerIdx] == FluidSystem::gasPhaseIdx) {
176 if (! FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)){
177 throw std::runtime_error(
"Gas tracer specified for non-gas fluid system: " +
178 this->
name(tracerIdx));
197 for (
auto& tr : this->
tbatch) {
198 if (tr.numTracer() != 0) {
203 tr.mat = std::make_unique<TracerMatrix>(*base);
211 const auto& comm =
simulator_.vanguard().grid().comm();
213 if (comm.rank() == 0) {
214 global_logger.logMessages();
224 OPM_TIMEBLOCK(tracerUpdateCache);
237 OPM_TIMEBLOCK(tracerAdvance);
245 template <
class Restarter>
255 template <
class Restarter>
259 template<
class Serializer>
262 serializer(
static_cast<BaseType&
>(*
this));
272 template<TracerTypeIdx Index>
274 const unsigned globalDofIdx,
275 const unsigned timeIdx)
const
277 const auto& intQuants =
simulator_.model().intensiveQuantities(globalDofIdx, timeIdx);
278 const auto& fs = intQuants.fluidState();
279 constexpr Scalar min_volume = 1e-10;
282 return std::max(decay<Scalar>(fs.saturation(tracerPhaseIdx)) *
283 decay<Scalar>(fs.invB(tracerPhaseIdx)) *
284 decay<Scalar>(intQuants.porosity()),
288 if (tracerPhaseIdx == FluidSystem::oilPhaseIdx && FluidSystem::enableVaporizedOil()) {
289 return std::max(decay<Scalar>(fs.saturation(FluidSystem::gasPhaseIdx)) *
290 decay<Scalar>(fs.invB(FluidSystem::gasPhaseIdx)) *
291 decay<Scalar>(fs.Rv()) *
292 decay<Scalar>(intQuants.porosity()),
297 else if (tracerPhaseIdx == FluidSystem::gasPhaseIdx && FluidSystem::enableDissolvedGas()) {
298 return std::max(decay<Scalar>(fs.saturation(FluidSystem::oilPhaseIdx)) *
299 decay<Scalar>(fs.invB(FluidSystem::oilPhaseIdx)) *
300 decay<Scalar>(fs.Rs()) *
301 decay<Scalar>(intQuants.porosity()),
309 template<TracerTypeIdx Index>
310 std::pair<TracerEvaluation, bool>
312 const ElementContext& elemCtx,
313 const unsigned scvfIdx,
314 const unsigned timeIdx)
const
316 const auto& stencil = elemCtx.stencil(timeIdx);
317 const auto& scvf = stencil.interiorFace(scvfIdx);
319 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
320 const unsigned inIdx = extQuants.interiorIndex();
326 upIdx = extQuants.upstreamIndex(tracerPhaseIdx);
327 const auto& intQuants = elemCtx.intensiveQuantities(upIdx, timeIdx);
328 const auto& fs = intQuants.fluidState();
329 v = decay<Scalar>(extQuants.volumeFlux(tracerPhaseIdx)) *
330 decay<Scalar>(fs.invB(tracerPhaseIdx));
332 if (tracerPhaseIdx == FluidSystem::oilPhaseIdx && FluidSystem::enableVaporizedOil()) {
333 upIdx = extQuants.upstreamIndex(FluidSystem::gasPhaseIdx);
335 const auto& intQuants = elemCtx.intensiveQuantities(upIdx, timeIdx);
336 const auto& fs = intQuants.fluidState();
337 v = decay<Scalar>(fs.invB(FluidSystem::gasPhaseIdx)) *
338 decay<Scalar>(extQuants.volumeFlux(FluidSystem::gasPhaseIdx)) *
339 decay<Scalar>(fs.Rv());
342 else if (tracerPhaseIdx == FluidSystem::gasPhaseIdx && FluidSystem::enableDissolvedGas()) {
343 upIdx = extQuants.upstreamIndex(FluidSystem::oilPhaseIdx);
345 const auto& intQuants = elemCtx.intensiveQuantities(upIdx, timeIdx);
346 const auto& fs = intQuants.fluidState();
347 v = decay<Scalar>(fs.invB(FluidSystem::oilPhaseIdx)) *
348 decay<Scalar>(extQuants.volumeFlux(FluidSystem::oilPhaseIdx)) *
349 decay<Scalar>(fs.Rs());
357 const Scalar A = scvf.area();
358 return inIdx == upIdx
359 ? std::pair{A * v * variable<TracerEvaluation>(1.0, 0),
true}
360 : std::pair{A * v,
false};
363 template<TracerTypeIdx Index,
class TrRe>
371 return tr.storageOfTimeIndex1_[tIdx][I][
Index];
373 return computeVolume_<Index>(tr.phaseIdx_, I1, 1) *
374 tr.concentration_[tIdx][I1][
Index];
380 const ElementContext& elemCtx,
381 const Scalar scvVolume,
387 if (tr.numTracer() == 0) {
391 const TracerEvaluation fVol = computeVolume_<Free>(tr.phaseIdx_, I, 0) * variable<TracerEvaluation>(1.0, 0);
392 const TracerEvaluation sVol = computeVolume_<Solution>(tr.phaseIdx_, I, 0) * variable<TracerEvaluation>(1.0, 0);
393 dVol_[
Solution][tr.phaseIdx_][I] += sVol.value() * scvVolume -
vol1_[1][tr.phaseIdx_][I];
394 dVol_[
Free][tr.phaseIdx_][I] += fVol.value() * scvVolume -
vol1_[0][tr.phaseIdx_][I];
395 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
397 const Scalar fStorageOfTimeIndex0 = fVol.value() * tr.concentration_[tIdx][I][
Free];
398 const Scalar fLocalStorage = (fStorageOfTimeIndex0 - storage1_<Free>(tr, tIdx, I, I1,
399 elemCtx.enableStorageCache())) * scvVolume / dt;
400 tr.residual_[tIdx][I][
Free] += fLocalStorage;
403 const Scalar sStorageOfTimeIndex0 = sVol.value() * tr.concentration_[tIdx][I][
Solution];
404 const Scalar sLocalStorage = (sStorageOfTimeIndex0 - storage1_<Solution>(tr, tIdx, I, I1,
405 elemCtx.enableStorageCache())) * scvVolume / dt;
406 tr.residual_[tIdx][I][
Solution] += sLocalStorage;
410 (*tr.mat)[I][I][
Free][
Free] += fVol.derivative(0) * scvVolume/dt;
416 const ElementContext& elemCtx,
422 if (tr.numTracer() == 0) {
426 const auto& [fFlux, isUpF] = computeFlux_<Free>(tr.phaseIdx_, elemCtx, scvfIdx, 0);
427 const auto& [sFlux, isUpS] = computeFlux_<Solution>(tr.phaseIdx_, elemCtx, scvfIdx, 0);
429 dVol_[
Free][tr.phaseIdx_][I] += fFlux.value() * dt;
430 const int fGlobalUpIdx = isUpF ? I : J;
431 const int sGlobalUpIdx = isUpS ? I : J;
432 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
434 tr.residual_[tIdx][I][
Free] += fFlux.value()*tr.concentration_[tIdx][fGlobalUpIdx][
Free];
435 tr.residual_[tIdx][I][
Solution] += sFlux.value()*tr.concentration_[tIdx][sGlobalUpIdx][
Solution];
440 (*tr.mat)[J][I][
Free][
Free] = -fFlux.derivative(0);
441 (*tr.mat)[I][I][
Free][
Free] += fFlux.derivative(0);
449 template<
class TrRe,
class Well>
453 if (tr.numTracer() == 0) {
457 const auto& eclWell = well.wellEcl();
463 auto* mswTracerRate = eclWell.isMultiSegment()
466 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
467 tracerRate[tr.idx_[tIdx]] = {this->
name(tr.idx_[tIdx]), 0.0};
468 freeTracerRate[tr.idx_[tIdx]] = {this->
wellfname(tr.idx_[tIdx]), 0.0};
469 solTracerRate[tr.idx_[tIdx]] = {this->
wellsname(tr.idx_[tIdx]), 0.0};
470 if (eclWell.isMultiSegment()) {
471 auto& wtr = mswTracerRate->at(tr.idx_[tIdx]) = {this->
name(tr.idx_[tIdx])};;
472 wtr.rate.reserve(eclWell.getConnections().size());
473 for (std::size_t i = 0; i < eclWell.getConnections().size(); ++i) {
474 wtr.rate.emplace(eclWell.getConnections().get(i).segment(), 0.0);
479 std::vector<Scalar> wtracer(tr.numTracer());
480 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
482 simulator_.problem().wellModel().summaryState());
486 const auto& ws =
simulator_.problem().wellModel().wellState().well(well.name());
487 const auto well_eff = well.wellEfficiencyFactor();
488 for (std::size_t i = 0; i < ws.perf_data.size(); ++i) {
489 const auto I = ws.perf_data.cell_index[i];
490 const Scalar rate = well.volumetricSurfaceRateForConnection(I, tr.phaseIdx_);
493 if (tr.phaseIdx_ == FluidSystem::oilPhaseIdx && FluidSystem::enableVaporizedOil()) {
494 rate_s = ws.perf_data.phase_mixing_rates[i][ws.vaporized_oil] * well_eff;
496 else if (tr.phaseIdx_ == FluidSystem::gasPhaseIdx && FluidSystem::enableDissolvedGas()) {
497 rate_s = ws.perf_data.phase_mixing_rates[i][ws.dissolved_gas] * well_eff;
503 const Scalar rate_f = rate - rate_s;
505 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
506 const Scalar delta = rate_f * wtracer[tIdx];
508 tr.residual_[tIdx][I][
Free] -= delta;
512 tracerRate[tr.idx_[tIdx]].rate += delta;
513 freeTracerRate[tr.idx_[tIdx]].rate += delta;
514 if (eclWell.isMultiSegment()) {
515 (*mswTracerRate)[tr.idx_[tIdx]].rate[eclWell.getConnections().get(i).segment()] += delta;
518 dVol_[
Free][tr.phaseIdx_][I] -= rate_f * dt;
520 else if (rate_f < 0) {
521 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
522 const Scalar delta = rate_f * wtracer[tIdx];
525 tracerRate[tr.idx_[tIdx]].rate += delta;
526 freeTracerRate[tr.idx_[tIdx]].rate += delta;
529 tr.residual_[tIdx][I][
Free] -= rate_f * tr.concentration_[tIdx][I][
Free];
531 dVol_[
Free][tr.phaseIdx_][I] -= rate_f * dt;
534 (*tr.mat)[I][I][
Free][
Free] -= rate_f * variable<TracerEvaluation>(1.0, 0).derivative(0);
537 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
539 tr.residual_[tIdx][I][
Solution] -= rate_s * tr.concentration_[tIdx][I][
Solution];
544 (*tr.mat)[I][I][
Solution][
Solution] -= rate_s * variable<TracerEvaluation>(1.0, 0).derivative(0);
565 const ElementContext& elemCtx,
569 if (tr.numTracer() == 0) {
574 if (!problem.nonTrivialBoundaryConditions()) {
578 if (!elemCtx.onBoundary()) {
586 BoundaryContext boundaryCtx(elemCtx);
587 if (boundaryCtx.intersection(0).neighbor()) {
589 boundaryCtx.increment();
592 const auto& stencil = elemCtx.stencil(0);
593 const auto& bcstate =
simulator_.vanguard().schedule()[problem.episodeIndex()].bcstate;
594 const unsigned numBoundaryFaces = boundaryCtx.numBoundaryFaces(0);
595 for (
unsigned bfIdx = 0; bfIdx < numBoundaryFaces; ++bfIdx, boundaryCtx.increment()) {
596 const auto& bf = stencil.boundaryFace(bfIdx);
597 const int dirId = bf.dirId();
602 const int bcIndex = problem.boundaryConditionIndex(I, dirId);
607 const BCType type = problem.boundaryCondition(I, dirId).first;
608 if (type != BCType::RATE && type != BCType::FREE && type != BCType::DIRICHLET) {
612 BoundaryRateVector bdyFlux;
613 problem.boundary(bdyFlux, boundaryCtx, bfIdx, 0);
614 const unsigned pvtRegionIdx = problem.pvtRegionIndex(I);
615 const Scalar boundaryArea = bf.area() * decay<Scalar>(elemCtx.intensiveQuantities(0, 0).extrusionFactor());
621 const auto phaseFlux = [&](
const int phaseIdx)
623 const int compIdx = phaseIdx == FluidSystem::waterPhaseIdx ? FluidSystem::waterCompIdx
624 : phaseIdx == FluidSystem::oilPhaseIdx ? FluidSystem::oilCompIdx
625 : FluidSystem::gasCompIdx;
626 Scalar flux = decay<Scalar>(bdyFlux[FluidSystem::canonicalToActiveCompIdx(compIdx)]) * boundaryArea;
627 if constexpr (!getPropValue<TypeTag, Properties::BlackoilConserveSurfaceVolume>()) {
628 flux /= FluidSystem::referenceDensity(phaseIdx, pvtRegionIdx);
632 const Scalar rateOut = phaseFlux(tr.phaseIdx_);
633 if (rateOut == Scalar{0}) {
641 Scalar rateFree = rateOut;
642 Scalar rateSol = 0.0;
643 const bool oilSolution = tr.phaseIdx_ == FluidSystem::oilPhaseIdx && FluidSystem::enableVaporizedOil();
644 const bool gasSolution = tr.phaseIdx_ == FluidSystem::gasPhaseIdx && FluidSystem::enableDissolvedGas();
645 if (rateOut > 0 && (oilSolution || gasSolution)) {
647 const auto& intQuants =
simulator_.model().intensiveQuantities(I, 0);
648 const auto& fs = intQuants.fluidState();
649 const Scalar Rs = FluidSystem::enableDissolvedGas() ? decay<Scalar>(fs.Rs()) : Scalar{0};
650 const Scalar Rv = FluidSystem::enableVaporizedOil() ? decay<Scalar>(fs.Rv()) : Scalar{0};
651 const Scalar Qo = phaseFlux(FluidSystem::oilPhaseIdx);
652 const Scalar Qg = phaseFlux(FluidSystem::gasPhaseIdx);
653 const Scalar det = 1.0 - Rs * Rv;
654 const Scalar Fo = (Qo - Rv * Qg) / det;
655 const Scalar Fg = (Qg - Rs * Qo) / det;
666 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
669 const auto bcConc = bcstate.tracerConcentration(bcIndex,
670 this->
name(tr.idx_[tIdx]));
671 tr.residual_[tIdx][I][
Free] += rateOut * bcConc.value_or(0.0);
675 tr.residual_[tIdx][I][
Free] += rateFree * tr.concentration_[tIdx][I][
Free];
676 tr.residual_[tIdx][I][
Solution] += rateSol * tr.concentration_[tIdx][I][
Solution];
679 dVol_[
Free][tr.phaseIdx_][I] += rateFree * dt;
684 (*tr.mat)[I][I][
Free][
Free] += rateFree * variable<TracerEvaluation>(1.0, 0).derivative(0);
685 (*tr.mat)[I][I][
Solution][
Solution] += rateSol * variable<TracerEvaluation>(1.0, 0).derivative(0);
695 if (tr.numTracer() == 0) {
700 if (tr.phaseIdx_ == FluidSystem::waterPhaseIdx ||
701 (tr.phaseIdx_ == FluidSystem::gasPhaseIdx && !FluidSystem::enableDissolvedGas()) ||
702 (tr.phaseIdx_ == FluidSystem::oilPhaseIdx && !FluidSystem::enableVaporizedOil()))
708 const Scalar& dfVol =
dVol_[
Free][tr.phaseIdx_][I];
711 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
713 const auto delta = (dfVol / dt) * tr.concentration_[tIdx][I][
Free];
714 tr.residual_[tIdx][I][
Free] -= delta;
715 tr.residual_[tIdx][I][
Solution] += delta;
718 const auto delta = (dsVol / dt) * tr.concentration_[tIdx][I][
Solution];
719 tr.residual_[tIdx][I][
Free] += delta;
720 tr.residual_[tIdx][I][
Solution] -= delta;
726 const auto delta = (dfVol / dt) * variable<TracerEvaluation>(1.0, 0).derivative(0);
727 (*tr.mat)[I][I][
Free][
Free] -= delta;
731 const auto delta = (dsVol / dt) * variable<TracerEvaluation>(1.0, 0).derivative(0);
748 OPM_TIMEBLOCK(tracerAssemble);
750 if (tr.numTracer() != 0) {
752 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
753 tr.residual_[tIdx] = 0.0;
767 const auto& wellPtrs =
simulator_.problem().wellModel().localNonshutWells();
772 for (
const auto& wellPtr : wellPtrs) {
774 const auto& eclWell = wellPtr->wellEcl();
778 auto* mswTracerRate = eclWell.isMultiSegment()
795 #pragma omp parallel for
799 const Scalar dt = elemCtx.simulator().timeStepSize();
801 for (
const auto& elem : chunk) {
802 elemCtx.updateStencil(elem);
803 const std::size_t I = elemCtx.globalSpaceIndex( 0, 0);
805 if (elem.partitionType() != Dune::InteriorEntity) {
809 for (
const auto& tr :
tbatch) {
810 if (tr.numTracer() != 0) {
811 (*tr.mat)[I][I][0][0] = 1.;
812 (*tr.mat)[I][I][1][1] = 1.;
817 elemCtx.updateAllIntensiveQuantities();
818 elemCtx.updateAllExtensiveQuantities();
820 const Scalar extrusionFactor =
821 elemCtx.intensiveQuantities( 0, 0).extrusionFactor();
822 Valgrind::CheckDefined(extrusionFactor);
823 assert(isfinite(extrusionFactor));
824 assert(extrusionFactor > 0.0);
825 const Scalar scvVolume =
826 elemCtx.stencil(0).subControlVolume( 0).volume() * extrusionFactor;
827 const std::size_t I1 = elemCtx.globalSpaceIndex( 0, 1);
832 if (tr.numTracer() == 0) {
838 const std::size_t numInteriorFaces = elemCtx.numInteriorFaces(0);
839 for (
unsigned scvfIdx = 0; scvfIdx < numInteriorFaces; scvfIdx++) {
840 const auto& face = elemCtx.stencil(0).interiorFace(scvfIdx);
841 const unsigned j = face.exteriorIndex();
842 const unsigned J = elemCtx.globalSpaceIndex( j, 0);
844 if (tr.numTracer() == 0) {
858 if (tr.numTracer() == 0) {
867 "assembleTracerEquations() failed: ",
872 if (tr.numTracer() == 0) {
877 simulator_.gridView().communicate(handle, Dune::InteriorBorder_All_Interface,
878 Dune::ForwardCommunication);
882 template<TracerTypeIdx Index,
class TrRe>
884 const Scalar scvVolume,
885 const unsigned globalDofIdx)
887 const Scalar vol1 = computeVolume_<Index>(tr.phaseIdx_, globalDofIdx, 0);
888 vol1_[
Index][tr.phaseIdx_][globalDofIdx] = vol1 * scvVolume;
889 dVol_[
Index][tr.phaseIdx_][globalDofIdx] = 0.0;
890 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
891 tr.storageOfTimeIndex1_[tIdx][globalDofIdx][
Index] =
892 vol1 * tr.concentrationInitial_[tIdx][globalDofIdx][
Index];
899 if (tr.numTracer() != 0) {
900 tr.concentrationInitial_ = tr.concentration_;
906 #pragma omp parallel for
911 for (
const auto& elem : chunk) {
912 elemCtx.updatePrimaryStencil(elem);
913 elemCtx.updatePrimaryIntensiveQuantities(0);
914 const Scalar extrusionFactor = elemCtx.intensiveQuantities( 0, 0).extrusionFactor();
915 const Scalar scvVolume = elemCtx.stencil(0).subControlVolume( 0).volume() * extrusionFactor;
916 const unsigned globalDofIdx = elemCtx.globalSpaceIndex(0, 0);
919 if (tr.numTracer() == 0) {
924 updateElem<Free>(tr, scvVolume, globalDofIdx);
925 updateElem<Solution>(tr, scvVolume, globalDofIdx);
931 template<TracerTypeIdx Index,
class TrRe>
933 const std::vector<TracerVector>& dx,
936 const unsigned globalDofIdx,
937 std::vector<TracerVectorSingle>& sc)
939 constexpr Scalar tol_gas_sat = 1e-6;
940 tr.concentration_[tIdx][globalDofIdx][
Index] -= dx[tIdx][globalDofIdx][
Index];
941 if (tr.concentration_[tIdx][globalDofIdx][
Index] < 0.0 || S < tol_gas_sat) {
942 tr.concentration_[tIdx][globalDofIdx][
Index] = 0.0;
944 sc[tr.idx_[tIdx]][globalDofIdx] = tr.concentration_[tIdx][globalDofIdx][
Index];
947 template<TracerTypeIdx Index,
class TrRe>
958 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
960 const Scalar delta = rate * tr.concentration_[tIdx][I][
Index];
961 tracerRate[tr.idx_[tIdx]].rate += delta;
962 splitRate[tr.idx_[tIdx]].rate += delta;
963 if (eclWell.isMultiSegment()) {
964 (*mswTracerRate)[tr.idx_[tIdx]].rate[eclWell.getConnections().get(i).segment()] += delta;
971 const auto& wellPtrs =
simulator_.problem().wellModel().localNonshutWells();
972 for (
const auto& wellPtr : wellPtrs) {
973 const auto& eclWell = wellPtr->wellEcl();
974 const auto well_seq_index = eclWell.seqIndex();
975 const auto inv_well_eff_factor = 1.0 / std::max(Scalar{1.0e-10}, wellPtr->wellEfficiencyFactor());
978 wtr.
rate *= inv_well_eff_factor;
981 wtr.
rate *= inv_well_eff_factor;
984 wtr.
rate *= inv_well_eff_factor;
986 if (eclWell.isMultiSegment()) {
988 std::ranges::for_each(wtr.
rate, [&](
auto& item) {
989 item.second *= inv_well_eff_factor;
1010 std::unordered_map<std::string, int> tracer_name_to_idx;
1011 for (
int tracerIdx = 0; tracerIdx < this->
numTracers(); ++tracerIdx) {
1012 tracer_name_to_idx.emplace(this->
name(tracerIdx), tracerIdx);
1015 const bool logging =
simulator_.vanguard().grid().comm().rank() == 0;
1016 const auto& schedule =
simulator_.vanguard().schedule();
1017 std::set<std::pair<int, std::string>> warned;
1018 std::set<int> flowIndices;
1019 std::set<int> tracerIndices;
1020 for (std::size_t step = 0; step < schedule.size(); ++step) {
1021 for (
const auto& face : schedule[step].bcstate) {
1022 if (face.bctype == BCType::RATE || face.bctype == BCType::FREE ||
1023 face.bctype == BCType::DIRICHLET) {
1024 flowIndices.insert(face.index);
1027 for (
const auto& tracerbc : face.tracerbcvalues) {
1028 tracerIndices.insert(face.index);
1029 const auto pos = tracer_name_to_idx.find(tracerbc.tracer);
1030 if (pos == tracer_name_to_idx.end()) {
1031 throw std::runtime_error(fmt::format(
"BCTRACER: tracer {} (INDEX {}) is not declared in TRACER",
1032 tracerbc.tracer, face.index));
1036 const bool samePhase =
1037 (face.component == BCComponent::WATER && phaseIdx == FluidSystem::waterPhaseIdx) ||
1038 (face.component == BCComponent::OIL && phaseIdx == FluidSystem::oilPhaseIdx) ||
1039 (face.component == BCComponent::GAS && phaseIdx == FluidSystem::gasPhaseIdx);
1041 const bool isPhaseComponent = face.component == BCComponent::WATER ||
1042 face.component == BCComponent::OIL ||
1043 face.component == BCComponent::GAS;
1044 if (isPhaseComponent && !samePhase &&
1045 warned.emplace(face.index, tracerbc.tracer).second && logging)
1047 deferredLogger.
warning(fmt::format(
"BCTRACER: the BCPROP component of INDEX {} is not the phase "
1048 "of tracer {}, so the tracer will not enter through this "
1049 "boundary", face.index, tracerbc.tracer));
1055 for (
const int index : tracerIndices) {
1056 if (!flowIndices.contains(index) && logging) {
1057 deferredLogger.
warning(fmt::format(
"BCTRACER: INDEX {} has no BCPROP of type RATE, FREE or DIRICHLET. "
1058 "BCTRACER is only used for boundaries with a flow and is ignored.",
1068 const auto& aquifer_cfg = this->
eclState_.aquifer();
1069 if (!aquifer_cfg.active()) {
1073 const auto& specs = aquifer_cfg.aquiferTracers();
1074 if (specs.empty()) {
1078 std::unordered_map<std::string, int> tracer_name_to_idx;
1079 for (
int tracerIdx = 0; tracerIdx < this->
numTracers(); ++tracerIdx) {
1080 tracer_name_to_idx.emplace(this->
name(tracerIdx), tracerIdx);
1083 const auto& vanguard =
simulator_.vanguard();
1084 for (
const auto& spec : specs) {
1085 if (!aquifer_cfg.hasAnalyticalAquifer(spec.aquifer_id)) {
1089 const auto tracer_pos = tracer_name_to_idx.find(spec.tracer_name);
1090 if (tracer_pos == tracer_name_to_idx.end()) {
1091 if (
simulator_.vanguard().grid().comm().rank() == 0) {
1092 deferredLogger.
warning(fmt::format(
"AQANTRC tracer '{}' is not declared in TRACER",
1098 if (!aquifer_cfg.connections().hasAquiferConnections(spec.aquifer_id)) {
1102 const int tracerIdx = tracer_pos->second;
1105 for (
const auto& conn : aquifer_cfg.connections().getConnections(spec.aquifer_id)) {
1106 const int cellIdx = vanguard.compressedIndex(conn.global_index);
1117 template<
class TrRe>
1124 const auto& aquiferModel =
simulator_.problem().aquiferModel();
1130 const Scalar rate = aquiferModel.cachedConnectionInfluxRate(cellIdx);
1131 if (rate == Scalar{0}) {
1135 const unsigned I = cellIdx;
1136 const Scalar rate_f = rate;
1138 for (
const auto& spec : specs) {
1139 if (spec.phaseIdx != tr.phaseIdx_) {
1144 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
1145 if (tr.idx_[tIdx] == spec.tracerIdx) {
1150 if (localTIdx < 0) {
1155 const Scalar delta = rate_f * spec.concentration;
1156 tr.residual_[localTIdx][I][
Free] -= delta;
1157 dVol_[
Free][tr.phaseIdx_][I] -= rate_f * dt;
1159 else if (rate_f < 0) {
1160 tr.residual_[localTIdx][I][
Free] -= rate_f * tr.concentration_[localTIdx][I][
Free];
1161 dVol_[
Free][tr.phaseIdx_][I] -= rate_f * dt;
1162 (*tr.mat)[I][I][
Free][
Free] -= rate_f * variable<TracerEvaluation>(1.0, 0).derivative(0);
1172 for (
auto& tr :
tbatch) {
1173 if (tr.numTracer() == 0) {
1179 std::vector<TracerVector> dx(tr.concentration_);
1180 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
1186 OpmLog::warning(
"### Tracer model: Linear solver did not converge. ###");
1189 OPM_TIMEBLOCK(tracerPost);
1191 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
1192 for (std::size_t globalDofIdx = 0; globalDofIdx < tr.concentration_[tIdx].size(); ++globalDofIdx) {
1195 const auto& intQuants =
simulator_.model().intensiveQuantities(globalDofIdx, 0);
1196 const auto& fs = intQuants.fluidState();
1197 const Scalar Sf = decay<Scalar>(fs.saturation(tr.phaseIdx_));
1200 if (tr.phaseIdx_ == FluidSystem::gasPhaseIdx && FluidSystem::enableDissolvedGas()) {
1201 Ss = decay<Scalar>(fs.saturation(FluidSystem::oilPhaseIdx));
1203 else if (tr.phaseIdx_ == FluidSystem::oilPhaseIdx && FluidSystem::enableVaporizedOil()) {
1204 Ss = decay<Scalar>(fs.saturation(FluidSystem::gasPhaseIdx));
1213 const auto& wellPtrs =
simulator_.problem().wellModel().localNonshutWells();
1214 for (
const auto& wellPtr : wellPtrs) {
1215 const auto& eclWell = wellPtr->wellEcl();
1218 if (!eclWell.isProducer()) {
1222 Scalar rateWellPos = 0.0;
1223 Scalar rateWellNeg = 0.0;
1224 const std::size_t well_index =
simulator_.problem().wellModel().wellState().index(eclWell.name()).value();
1225 const auto& ws =
simulator_.problem().wellModel().wellState().well(well_index);
1229 auto* mswTracerRate = eclWell.isMultiSegment() ? &this->
mSwTracerRate_[eclWell.seqIndex()] :
nullptr;
1230 const auto well_eff = wellPtr->wellEfficiencyFactor();
1231 for (std::size_t i = 0; i < ws.perf_data.size(); ++i) {
1232 const auto I = ws.perf_data.cell_index[i];
1233 const Scalar rate = wellPtr->volumetricSurfaceRateForConnection(I, tr.phaseIdx_);
1236 if (tr.phaseIdx_ == FluidSystem::oilPhaseIdx && FluidSystem::enableVaporizedOil()) {
1237 rate_s = ws.perf_data.phase_mixing_rates[i][ws.vaporized_oil]*well_eff;
1239 else if (tr.phaseIdx_ == FluidSystem::gasPhaseIdx && FluidSystem::enableDissolvedGas()) {
1240 rate_s = ws.perf_data.phase_mixing_rates[i][ws.dissolved_gas]*well_eff;
1246 const Scalar rate_f = rate - rate_s;
1247 assignRates<Free>(tr, eclWell, i, I, rate_f,
1248 tracerRate, mswTracerRate, freeTracerRate);
1249 assignRates<Solution>(tr, eclWell, i, I, rate_s,
1250 tracerRate, mswTracerRate, solTracerRate);
1253 rateWellNeg += rate;
1256 rateWellPos += rate;
1265 const Scalar official_well_rate_total =
1266 simulator_.problem().wellModel().wellState().well(well_index).surface_rates[tr.phaseIdx_];
1268 const Scalar rateWellTotal = official_well_rate_total;
1270 if (rateWellTotal > rateWellNeg) {
1271 constexpr Scalar bucketPrDay = 10.0 / (1000. * 3600. * 24.);
1272 const Scalar factor = (rateWellTotal < -bucketPrDay) ? rateWellTotal / rateWellNeg : 0.0;
1273 for (
int tIdx = 0; tIdx < tr.numTracer(); ++tIdx) {
1274 tracerRate[tIdx].rate *= factor;
1292 template <
typename TV>
1301 std::unique_ptr<TracerMatrix>
mat;
1312 result.
idx_ = {1,2,3};
1321 template<
class Serializer>
1331 {
return idx_.size(); }
1335 const int numGridDof = concentration.size();
1336 idx_.emplace_back(idx);
1344 std::array<TracerBatch<TracerVector>,numPhases>
tbatch;
1348 std::array<std::array<std::vector<Scalar>,numPhases>,2>
vol1_;
1349 std::array<std::array<std::vector<Scalar>,numPhases>,2>
dVol_;
#define OPM_END_PARALLEL_TRY_CATCH_LOG(obptc_logger, obptc_prefix, obptc_output, comm)
Catch exception, log, and throw in a parallel try-catch clause.
Definition: DeferredLoggingErrorHelpers.hpp:207
#define OPM_BEGIN_PARALLEL_TRY_CATCH()
Macro to setup the try of a parallel try-catch.
Definition: DeferredLoggingErrorHelpers.hpp:160
A datahandle sending data located in multiple vectors.
Definition: DeferredLogger.hpp:57
void warning(const std::string &tag, const std::string &message)
Definition: GenericTracerModel.hpp:56
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::numTracers int numTracers() const
Return the number of tracers considered by the tracerModel.
Definition: GenericTracerModel_impl.hpp:162
Opm::GenericTracerModel< 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(bool rst, std::size_t numGridDof, std::size_t gasPhaseIdx, std::size_t oilPhaseIdx, std::size_t waterPhaseIdx)
Initialize all internal data structures needed by the tracer module.
Definition: GenericTracerModel_impl.hpp:227
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::tracerConcentration_ std::vector< TracerVector > tracerConcentration_
Definition: GenericTracerModel.hpp:158
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::tracerPhaseIdx_ std::vector< int > tracerPhaseIdx_
Definition: GenericTracerModel.hpp:156
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::wellFreeTracerRate_ std::unordered_map< int, std::vector< WellTracerRate< GetPropType< TypeTag, Properties::Scalar > > > > wellFreeTracerRate_
Definition: GenericTracerModel.hpp:165
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::wellTracerRate_ std::unordered_map< int, std::vector< WellTracerRate< GetPropType< TypeTag, Properties::Scalar > > > > wellTracerRate_
Definition: GenericTracerModel.hpp:164
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::mSwTracerRate_ std::unordered_map< int, std::vector< MSWellTracerRate< GetPropType< TypeTag, Properties::Scalar > > > > mSwTracerRate_
Definition: GenericTracerModel.hpp:168
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::eclState_ const EclipseState & eclState_
Definition: GenericTracerModel.hpp:152
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::wellfname std::string wellfname(int tracerIdx) const
Definition: GenericTracerModel_impl.hpp:183
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::name const std::string & name(int tracerIdx) const
Return the tracer name.
Definition: GenericTracerModel_impl.hpp:220
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::wellsname std::string wellsname(int tracerIdx) const
Definition: GenericTracerModel_impl.hpp:190
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::freeTracerConcentration_ std::vector< TracerVectorSingle > freeTracerConcentration_
Definition: GenericTracerModel.hpp:160
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::TracerVector Dune::BlockVector< Dune::FieldVector< GetPropType< TypeTag, Properties::Scalar >, 2 > > TracerVector
Definition: GenericTracerModel.hpp:60
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::TracerTypeIdx TracerTypeIdx
Tracer type index.
Definition: GenericTracerModel.hpp:146
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::Free @ Free
Definition: GenericTracerModel.hpp:147
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::Solution @ Solution
Definition: GenericTracerModel.hpp:148
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::linearSolveBatchwise_ bool linearSolveBatchwise_(const TracerMatrix &M, std::vector< TracerVector > &x, std::vector< TracerVector > &b)
Definition: GenericTracerModel_impl.hpp:444
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::TracerMatrix Dune::BCRSMatrix< Opm::MatrixBlock< GetPropType< TypeTag, Properties::Scalar >, 2, 2 > > TracerMatrix
Definition: GenericTracerModel.hpp:59
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::solTracerConcentration_ std::vector< TracerVectorSingle > solTracerConcentration_
Definition: GenericTracerModel.hpp:161
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::currentConcentration_ GetPropType< TypeTag, Properties::Scalar > currentConcentration_(const Well &eclWell, const std::string &trName, const SummaryState &summaryState) const
Definition: GenericTracerModel_impl.hpp:211
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::TracerVectorSingle Dune::BlockVector< Dune::FieldVector< GetPropType< TypeTag, Properties::Scalar >, 1 > > TracerVectorSingle
Definition: GenericTracerModel.hpp:58
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::tracerMatrix_ std::unique_ptr< TracerMatrix > tracerMatrix_
Definition: GenericTracerModel.hpp:159
Opm::GenericTracerModel< GetPropType< TypeTag, Properties::Grid >, GetPropType< TypeTag, Properties::GridView >, GetPropType< TypeTag, Properties::DofMapper >, GetPropType< TypeTag, Properties::Stencil >, GetPropType< TypeTag, Properties::FluidSystem >, GetPropType< TypeTag, Properties::Scalar > >::wellSolTracerRate_ std::unordered_map< int, std::vector< WellTracerRate< GetPropType< TypeTag, Properties::Scalar > > > > wellSolTracerRate_
Definition: GenericTracerModel.hpp:166
static unsigned maxThreads()
Return the maximum number of threads of the current process.
Definition: threadmanager.hpp:66
A class which handles tracers as specified in by ECL.
Definition: TracerModel.hpp:85
void updateStorageCache()
Definition: TracerModel.hpp:896
std::array< std::array< std::vector< Scalar >, numPhases >, 2 > vol1_
Definition: TracerModel.hpp:1348
void convertEffectiveRatesToRawRates()
Definition: TracerModel.hpp:970
TracerBatch< TracerVector > & oil_
Definition: TracerModel.hpp:1346
void assembleTracerEquationBoundary(TrRe &tr, const ElementContext &elemCtx, const unsigned I, const Scalar dt)
Boundary conditions for the tracer equations.
Definition: TracerModel.hpp:564
void advanceTracerFields()
Definition: TracerModel.hpp:1168
void init(bool rst)
Definition: TracerModel.hpp:148
void checkBoundaryTracers_(DeferredLogger &deferredLogger) const
Cross-reference the boundary conditions of the schedule with the tracers.
Definition: TracerModel.hpp:1008
void assembleTracerEquationSource(TrRe &tr, const Scalar dt, unsigned I)
Definition: TracerModel.hpp:691
TracerModel(Simulator &simulator)
Definition: TracerModel.hpp:115
void assignRates(const TrRe &tr, const Well &eclWell, const std::size_t i, const std::size_t I, const Scalar rate, std::vector< WellTracerRate< Scalar > > &tracerRate, std::vector< MSWellTracerRate< Scalar > > *mswTracerRate, std::vector< WellTracerRate< Scalar > > &splitRate)
Definition: TracerModel.hpp:948
void copyForOutput(TrRe &tr, const std::vector< TracerVector > &dx, const Scalar S, const unsigned tIdx, const unsigned globalDofIdx, std::vector< TracerVectorSingle > &sc)
Definition: TracerModel.hpp:932
void assembleTracerEquationFlux(TrRe &tr, const ElementContext &elemCtx, unsigned scvfIdx, unsigned I, unsigned J, const Scalar dt)
Definition: TracerModel.hpp:415
void assembleTracerEquationWell(TrRe &tr, const Well &well)
Definition: TracerModel.hpp:450
void updateElem(TrRe &tr, const Scalar scvVolume, const unsigned globalDofIdx)
Definition: TracerModel.hpp:883
Scalar computeVolume_(const int tracerPhaseIdx, const unsigned globalDofIdx, const unsigned timeIdx) const
Definition: TracerModel.hpp:273
void assembleTracerEquationAquifer_(TrRe &tr)
Definition: TracerModel.hpp:1118
typename BaseType::TracerTypeIdx TracerTypeIdx
Definition: TracerModel.hpp:267
void assembleTracerEquationVolume(TrRe &tr, const ElementContext &elemCtx, const Scalar scvVolume, const Scalar dt, unsigned I, unsigned I1)
Definition: TracerModel.hpp:379
Scalar storage1_(const TrRe &tr, const unsigned tIdx, const unsigned I, const unsigned I1, const bool cache)
Definition: TracerModel.hpp:364
void serialize(Restarter &)
This method writes the complete state of all tracer to the hard disk.
Definition: TracerModel.hpp:246
TracerBatch< TracerVector > & gas_
Definition: TracerModel.hpp:1347
void assembleTracerEquations_()
Definition: TracerModel.hpp:737
std::array< TracerBatch< TracerVector >, numPhases > tbatch
Definition: TracerModel.hpp:1344
void buildAquiferTracerConnections_(DeferredLogger &deferredLogger)
Definition: TracerModel.hpp:1064
std::pair< TracerEvaluation, bool > computeFlux_(const int tracerPhaseIdx, const ElementContext &elemCtx, const unsigned scvfIdx, const unsigned timeIdx) const
Definition: TracerModel.hpp:311
void beginTimeStep()
Definition: TracerModel.hpp:218
void serializeOp(Serializer &serializer)
Definition: TracerModel.hpp:260
void prepareTracerBatches()
Definition: TracerModel.hpp:154
std::unordered_map< unsigned, std::vector< AquiferTracerCellSpec > > aquifer_tracer_cells_
Definition: TracerModel.hpp:1358
std::array< std::array< std::vector< Scalar >, numPhases >, 2 > dVol_
Definition: TracerModel.hpp:1349
ElementChunks< GridView, Dune::Partitions::All > element_chunks_
Definition: TracerModel.hpp:1350
TracerBatch< TracerVector > & wat_
Definition: TracerModel.hpp:1345
void endTimeStep()
Informs the tracer model that a time step has just been finished.
Definition: TracerModel.hpp:231
Simulator & simulator_
Definition: TracerModel.hpp:1282
void deserialize(Restarter &)
This method restores the complete state of the tracer from disk.
Definition: TracerModel.hpp:256
A data handle sending multiple data store in vectors attached to cells.
Definition: VectorVectorDataHandle.hpp:50
int Index
The type of an index of a degree of freedom.
Definition: overlaptypes.hh:44
Definition: blackoilmodel.hh:74
Definition: blackoilbioeffectsmodules.hh:45
Opm::DeferredLogger gatherDeferredLogger(const Opm::DeferredLogger &local_deferredlogger, Parallel::Communication communicator)
Create a global log combining local logs.
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: WellTracerRate.hpp:60
std::unordered_map< int, Scalar > rate
Definition: WellTracerRate.hpp:62
Definition: TracerModel.hpp:65
a tag to mark properties as undefined
Definition: propertysystem.hh:38
Definition: TracerModel.hpp:1352
int phaseIdx
Definition: TracerModel.hpp:1354
Scalar concentration
Definition: TracerModel.hpp:1355
int tracerIdx
Definition: TracerModel.hpp:1353
Definition: TracerModel.hpp:1294
const int phaseIdx_
Definition: TracerModel.hpp:1296
void addTracer(const int idx, const TV &concentration)
Definition: TracerModel.hpp:1333
bool operator==(const TracerBatch &rhs) const
Definition: TracerModel.hpp:1303
static TracerBatch serializationTestObject()
Definition: TracerModel.hpp:1309
std::vector< TV > concentrationInitial_
Definition: TracerModel.hpp:1297
void serializeOp(Serializer &serializer)
Definition: TracerModel.hpp:1322
TracerBatch(int phaseIdx=0)
Definition: TracerModel.hpp:1328
int numTracer() const
Definition: TracerModel.hpp:1330
std::vector< int > idx_
Definition: TracerModel.hpp:1295
std::unique_ptr< TracerMatrix > mat
Definition: TracerModel.hpp:1301
std::vector< TV > storageOfTimeIndex1_
Definition: TracerModel.hpp:1299
std::vector< TV > residual_
Definition: TracerModel.hpp:1300
std::vector< TV > concentration_
Definition: TracerModel.hpp:1298
Definition: WellTracerRate.hpp:33
Scalar rate
Definition: WellTracerRate.hpp:35