OGS
HydrodynamicDispersion.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <Eigen/Core>
7
9
10namespace NumLib
11{
12namespace detail
13{
14
15inline Eigen::MatrixXd getHydrodynamicDispersion(
16 Eigen::MatrixXd const& pore_diffusion_coefficient,
17 Eigen::VectorXd const& velocity,
18 double const porosity,
19 double const solute_dispersivity_transverse,
20 double const solute_dispersivity_longitudinal)
21{
22 double const velocity_magnitude = velocity.norm();
23 if (velocity_magnitude == 0.0)
24 {
25 return porosity * pore_diffusion_coefficient;
26 }
27
28 auto const dim = velocity.size();
29 Eigen::MatrixXd const& I(Eigen::MatrixXd::Identity(dim, dim));
30 return porosity * pore_diffusion_coefficient +
31 solute_dispersivity_transverse * velocity_magnitude * I +
32 (solute_dispersivity_longitudinal - solute_dispersivity_transverse) /
33 velocity_magnitude * velocity * velocity.transpose();
34}
35
37 IsotropicDiffusionStabilization const& stabilizer,
38 std::size_t const element_id,
39 Eigen::MatrixXd const& pore_diffusion_coefficient,
40 Eigen::VectorXd const& velocity,
41 double const porosity,
42 double const solute_dispersivity_transverse,
43 double const solute_dispersivity_longitudinal)
44{
45 double const velocity_magnitude = velocity.norm();
46 if (velocity_magnitude == 0.0)
47 {
48 return porosity * pore_diffusion_coefficient;
49 }
50
51 double const artificial_diffusion =
52 stabilizer.computeArtificialDiffusion(element_id, velocity_magnitude);
53
54 auto const dim = velocity.size();
55 Eigen::MatrixXd const& I(Eigen::MatrixXd::Identity(dim, dim));
56 return porosity * pore_diffusion_coefficient +
57 (solute_dispersivity_transverse * velocity_magnitude +
58 artificial_diffusion) *
59 I +
60 (solute_dispersivity_longitudinal - solute_dispersivity_transverse) /
61 velocity_magnitude * velocity * velocity.transpose();
62}
63} // namespace detail
64
65inline Eigen::MatrixXd computeHydrodynamicDispersion(
66 NumericalStabilization const& stabilizer,
67 std::size_t const element_id,
68 Eigen::MatrixXd const& pore_diffusion_coefficient,
69 Eigen::VectorXd const& velocity,
70 double const porosity,
71 double const solute_dispersivity_transverse,
72 double const solute_dispersivity_longitudinal)
73{
74 return std::visit(
75 [&](auto&& stabilizer)
76 {
77 using Stabilizer = std::decay_t<decltype(stabilizer)>;
78 if constexpr (std::is_same_v<Stabilizer,
80 {
82 stabilizer,
83 element_id,
84 pore_diffusion_coefficient,
85 velocity,
86 porosity,
87 solute_dispersivity_transverse,
88 solute_dispersivity_longitudinal);
89 }
90
92 pore_diffusion_coefficient,
93 velocity,
94 porosity,
95 solute_dispersivity_transverse,
96 solute_dispersivity_longitudinal);
97 },
98 stabilizer);
99}
100
101} // namespace NumLib
double computeArtificialDiffusion(std::size_t const element_id, double const velocity_norm) const
Eigen::MatrixXd getHydrodynamicDispersion(Eigen::MatrixXd const &pore_diffusion_coefficient, Eigen::VectorXd const &velocity, double const porosity, double const solute_dispersivity_transverse, double const solute_dispersivity_longitudinal)
Eigen::MatrixXd getHydrodynamicDispersionWithArtificialDiffusion(IsotropicDiffusionStabilization const &stabilizer, std::size_t const element_id, Eigen::MatrixXd const &pore_diffusion_coefficient, Eigen::VectorXd const &velocity, double const porosity, double const solute_dispersivity_transverse, double const solute_dispersivity_longitudinal)
std::variant< NoStabilization, IsotropicDiffusionStabilization, FullUpwind, FluxCorrectedTransport > NumericalStabilization
Eigen::MatrixXd computeHydrodynamicDispersion(NumericalStabilization const &stabilizer, std::size_t const element_id, Eigen::MatrixXd const &pore_diffusion_coefficient, Eigen::VectorXd const &velocity, double const porosity, double const solute_dispersivity_transverse, double const solute_dispersivity_longitudinal)