OGS
VolumeFractionAverage.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
8
10{
12{
13 // get the corresponding property's name
14 name_ = std::move(name);
15
17}
18
20{
21 if (!std::holds_alternative<Medium*>(scale_))
22 {
24 "The property 'VolumeFractionAverage' is "
25 "implemented on the 'medium' scale only.");
26 }
27}
28
30 std::vector<std::unique_ptr<Phase>> const& phases)
31{
32 // run over phases, identify them and get properties
33 for (auto const& phase : phases)
34 {
35 if (phase == nullptr)
36 {
38 "One of the required phases (AqueousLiquid/FrozenLiquid/Solid) "
39 "does not exist!");
40 }
41
42 if (!phase->hasProperty(prop_type_))
43 {
45 "The phase '{}' does not have the required property '{}'!",
46 toString(phase->phaseName),
48 }
49 auto const& property = phase->property(prop_type_);
50 if (phase->phaseName == PhaseName::AqueousLiquid)
51 {
52 properties_.liquid = &property;
53 }
54 else if (phase->phaseName == PhaseName::FrozenLiquid)
55 {
56 properties_.frozen = &property;
57 }
58 else if (phase->phaseName == PhaseName::Solid)
59 {
60 properties_.porous = &property;
61 }
62 }
63
64 // Consistency check performed once at setup (scale_ is already set to the
65 // medium by setScale() before setProperties() runs), instead of on every
66 // value()/dValue() call: a FrozenLiquid phase providing this property and
67 // the medium's frozen_liquid_saturation property must either both be
68 // present or both be absent.
69 auto const& medium = *std::get<Medium*>(scale_);
70 if ((properties_.frozen != nullptr) !=
72 {
74 "In the 'VolumeFractionAverage' property '{}', a FrozenLiquid "
75 "phase "
76 "and the medium's 'frozen_liquid_saturation' property must be "
77 "provided together. Found FrozenLiquid phase property: {}, medium "
78 "frozen_liquid_saturation property: {}.",
79 name_, properties_.frozen != nullptr,
80 medium.hasProperty(PropertyType::frozen_liquid_saturation));
81 }
82}
83
85 VariableArray const& variable_array,
86 ParameterLib::SpatialPosition const& pos, double const t,
87 double const dt) const
88{
89 auto const& medium = *std::get<Medium*>(scale_);
90 auto const& porosity = medium[PropertyType::porosity];
91
92 auto const phi =
93 std::get<double>(porosity.value(variable_array, pos, t, dt));
94
95 double S_fr = 0;
96 double prop_value_frozen = 0;
97
98 // get frozen liquid (ice) saturation, i.e. the fraction of the pore space
99 // occupied by ice (the frozen-phase/saturation consistency is enforced once
100 // in setProperties())
101 if (medium.hasProperty(PropertyType::frozen_liquid_saturation))
102 {
104 S_fr = std::get<double>(saturation.value(variable_array, pos, t, dt));
105 prop_value_frozen = std::get<double>(
106 properties_.frozen->value(variable_array, pos, t, dt));
107 }
108 auto const prop_value_liquid =
109 std::get<double>(properties_.liquid->value(variable_array, pos, t, dt));
110 auto const prop_value_porous =
111 std::get<double>(properties_.porous->value(variable_array, pos, t, dt));
112
113 return phi * (1.0 - S_fr) * prop_value_liquid +
114 phi * S_fr * prop_value_frozen + (1 - phi) * prop_value_porous;
115}
116
118 VariableArray const& variable_array, Variable const variable,
119 ParameterLib::SpatialPosition const& pos, double const t,
120 double const dt) const
121{
122 if (variable != Variable::temperature)
123 {
124 OGS_FATAL(
125 "VolumeFractionAverage::dValue is implemented for derivatives with "
126 "respect to temperature only.");
127 }
128
129 auto const& medium = *std::get<Medium*>(scale_);
130 auto const& porosity = medium[PropertyType::porosity];
131 auto const phi =
132 std::get<double>(porosity.value(variable_array, pos, t, dt));
133
134 double dS_fr_dT = 0;
135 double prop_value_frozen = 0;
136
137 if (medium.hasProperty(PropertyType::frozen_liquid_saturation))
138 {
140 dS_fr_dT = std::get<double>(saturation.dValue(
141 variable_array, Variable::temperature, pos, t, dt));
142 prop_value_frozen = std::get<double>(
143 properties_.frozen->value(variable_array, pos, t, dt));
144 }
145
146 double prop_value_liquid =
147 std::get<double>(properties_.liquid->value(variable_array, pos, t, dt));
148
149 // Only the frozen liquid saturation S_fr is treated as temperature
150 // dependent here; the porosity and the phase properties are assumed to be
151 // temperature independent, so their temperature derivatives are omitted.
152 return phi * (prop_value_frozen - prop_value_liquid) * dS_fr_dT;
153}
154} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:10
virtual PropertyDataType value() const
std::variant< Medium *, Phase *, Component * > scale_
void setProperties(std::vector< std::unique_ptr< Phase > > const &phases) override
Default implementation:
PropertyDataType dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
PropertyType convertStringToProperty(std::string const &string)
static const std::array< std::string, PropertyType::number_of_properties > property_enum_to_string
std::string_view toString(PhaseName phase_name)
Convert phase enum to its string representation.
Definition Phase.cpp:13
std::variant< double, Eigen::Matrix< double, 2, 1 >, Eigen::Matrix< double, 3, 1 >, Eigen::Matrix< double, 2, 2 >, Eigen::Matrix< double, 3, 3 >, Eigen::Matrix< double, 4, 1 >, Eigen::Matrix< double, 6, 1 >, Eigen::MatrixXd > PropertyDataType