OGS
MaterialLib/MPL/Property.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#include <array>
8#include <string>
9#include <typeinfo>
10#include <variant>
11
13#include "BaseLib/Error.h"
15#include "PropertyType.h"
16#include "VariableType.h"
17
18namespace MaterialPropertyLib
19{
20class Medium;
21class Phase;
22class Component;
23
25 std::variant<double, Eigen::Matrix<double, 2, 1>,
26 Eigen::Matrix<double, 3, 1>, Eigen::Matrix<double, 2, 2>,
27 Eigen::Matrix<double, 3, 3>, Eigen::Matrix<double, 4, 1>,
28 Eigen::Matrix<double, 6, 1>, Eigen::MatrixXd>;
29
38PropertyDataType fromVector(std::vector<double> const& values);
39
48template <std::size_t N>
49PropertyDataType fromArray(std::array<double, N> const& values)
50{
51 if constexpr (N == 1)
52 {
53 return values[0];
54 }
55 else if constexpr (N == 2)
56 {
57 return Eigen::Vector2d{values[0], values[1]};
58 }
59 else if constexpr (N == 3)
60 {
61 return Eigen::Vector3d{values[0], values[1], values[2]};
62 }
63 else if constexpr (N == 4)
64 {
65 using M = Eigen::Matrix2d;
66 using MRM = Eigen::Matrix<double, 2, 2, Eigen::RowMajor>;
67 return M{Eigen::Map<MRM const>{values.data(), 2, 2}};
68 }
69 else if constexpr (N == 6)
70 {
71 using M = Eigen::Matrix<double, 6, 1>;
72 return M{Eigen::Map<M const>{values.data(), 6}};
73 }
74 else if constexpr (N == 9)
75 {
76 using M = Eigen::Matrix3d;
77 using MRM = Eigen::Matrix<double, 3, 3, Eigen::RowMajor>;
78 return M{Eigen::Map<MRM const>{values.data(), 3, 3}};
79 }
80 else
81 {
82 static_assert(false, "Unsupported array size for fromArray.");
83 }
84}
85
90{
91public:
92#ifndef NDEBUG
93 virtual ~Property()
94 {
95 if (property_used)
96 {
97 DBUG("Property is used: '{:s}'", description());
98 }
99 else
100 {
101 WARN("Property is not used: '{:s}'", description());
102 }
103 }
104#else
105 virtual ~Property() = default;
106#endif
107
111 ParameterLib::SpatialPosition const& pos, double const t) const;
112
115 virtual PropertyDataType value() const;
119 virtual PropertyDataType value(VariableArray const& variable_array,
120 VariableArray const& variable_array_prev,
122 double const t, double const dt) const;
126 virtual PropertyDataType value(VariableArray const& variable_array,
128 double const t, double const dt) const;
132 virtual PropertyDataType dValue(VariableArray const& variable_array,
133 VariableArray const& variable_array_prev,
134 Variable const variable,
136 double const t, double const dt) const;
140 virtual PropertyDataType dValue(VariableArray const& variable_array,
141 Variable const variable,
143 double const t, double const dt) const;
146 virtual PropertyDataType d2Value(VariableArray const& variable_array,
147 Variable const variable1,
148 Variable const variable2,
150 double const t, double const dt) const;
151
154 virtual void setProperties(
155 std::vector<std::unique_ptr<Phase>> const& phases);
156
157 void setScale(std::variant<Medium*, Phase*, Component*> scale)
158 {
159 scale_ = scale;
160 checkScale();
161 };
162
163 template <typename T>
165 double const t) const
166 {
167 try
168 {
169 return std::get<T>(initialValue(pos, t));
170 }
171 catch (std::bad_variant_access const&)
172 {
173 OGS_FATAL(
174 "The initial value of {:s} does not hold requested type '{:s}' "
175 "but a {:s}.",
176 description(),
178 property_data_type_names_[initialValue(pos, t).index()]);
179 }
180 }
181
182 template <typename T>
183 T value() const
184 {
185 try
186 {
187#ifndef NDEBUG
188 property_used = true;
189#endif
190 return std::get<T>(value());
191 }
192 catch (std::bad_variant_access const&)
193 {
194 OGS_FATAL(
195 "The value of {:s} does not hold requested type '{:s}' but a "
196 "{:s}.",
197 description(),
200 }
201 }
202
203 template <typename T>
204 T value(VariableArray const& variable_array,
205 VariableArray const& variable_array_prev,
206 ParameterLib::SpatialPosition const& pos, double const t,
207 double const dt) const
208 {
209 try
210 {
211#ifndef NDEBUG
212 property_used = true;
213#endif
214 return std::get<T>(
215 value(variable_array, variable_array_prev, pos, t, dt));
216 }
217 catch (std::bad_variant_access const&)
218 {
219 OGS_FATAL(
220 "The value of {:s} is not of the requested type '{:s}' but a "
221 "{:s}.",
222 description(),
224 property_data_type_names_[value(variable_array,
225 variable_array_prev, pos, t, dt)
226 .index()]);
227 }
228 }
229 template <typename T>
230 T value(VariableArray const& variable_array,
231 ParameterLib::SpatialPosition const& pos, double const t,
232 double const dt) const
233 {
234 try
235 {
236#ifndef NDEBUG
237 property_used = true;
238#endif
239 return std::get<T>(value(variable_array, pos, t, dt));
240 }
241 catch (std::bad_variant_access const&)
242 {
243 OGS_FATAL(
244 "The value of {:s} is not of the requested type '{:s}' but a "
245 "{:s}.",
246 description(),
248 property_data_type_names_[value(variable_array, pos, t, dt)
249 .index()]);
250 }
251 }
252
253 template <typename T>
254 T dValue(VariableArray const& variable_array,
255 VariableArray const& variable_array_prev, Variable const variable,
256 ParameterLib::SpatialPosition const& pos, double const t,
257 double const dt) const
258 {
259 try
260 {
261#ifndef NDEBUG
262 property_used = true;
263#endif
264 return std::get<T>(dValue(variable_array, variable_array_prev,
265 variable, pos, t, dt));
266 }
267 catch (std::bad_variant_access const&)
268 {
269 OGS_FATAL(
270 "The first derivative value of {:s} is not of the requested "
271 "type '{:s}' but a {:s}.",
272 description(),
275 [dValue(variable_array, variable, pos, t, dt).index()]);
276 }
277 }
278 template <typename T>
279 T dValue(VariableArray const& variable_array, Variable const variable,
280 ParameterLib::SpatialPosition const& pos, double const t,
281 double const dt) const
282 {
283 try
284 {
285#ifndef NDEBUG
286 property_used = true;
287#endif
288 return std::get<T>(dValue(variable_array, variable, pos, t, dt));
289 }
290 catch (std::bad_variant_access const&)
291 {
292 OGS_FATAL(
293 "The first derivative value of {:s} is not of the requested "
294 "type '{:s}' but a {:s}.",
295 description(),
298 [dValue(variable_array, variable, pos, t, dt).index()]);
299 }
300 }
301 template <typename T>
302 T d2Value(VariableArray const& variable_array, Variable const& variable1,
303 Variable const& variable2,
304 ParameterLib::SpatialPosition const& pos, double const t,
305 double const dt) const
306 {
307 try
308 {
309#ifndef NDEBUG
310 property_used = true;
311#endif
312 return std::get<T>(
313 d2Value(variable_array, variable1, variable2, pos, t, dt));
314 }
315 catch (std::bad_variant_access const&)
316 {
317 OGS_FATAL(
318 "The second derivative value of {:s} is not of the requested "
319 "type '{:s}' but a {:s}.",
320 description(),
322 property_data_type_names_[d2Value(variable_array, variable1,
323 variable2, pos, t, dt)
324 .index()]);
325 }
326 }
327
328protected:
329 std::string name_;
336 std::variant<Medium*, Phase*, Component*> scale_;
337
338private:
339 virtual void checkScale() const
340 {
341 // Empty check for properties which can be defined on every scale,
342 // medium, phase or component
343 }
344 std::string description() const;
345#ifndef NDEBUG
346 mutable bool property_used = false;
347#endif
348
349private:
351 static constexpr std::array property_data_type_names_ = {
352 "scalar", "2-vector", "3-vector",
353 "2x2-matrix", "3x3-matrix", "2D-Kelvin vector",
354 "3D-Kelvin vector", "dynamic matrix type"};
355 static_assert(property_data_type_names_.size() ==
356 std::variant_size_v<PropertyDataType>,
357 "The array of property data type names has different size "
358 "than the PropertyDataType variant type.");
359};
360
362 PropertyArray& properties,
363 PropertyArray& new_properties,
364 std::variant<Medium*, Phase*, Component*>
365 scale_pointer)
366{
367 for (std::size_t i = 0; i < properties.size(); ++i)
368 {
369 if (new_properties[i] != nullptr)
370 {
371 properties[i] = std::move(new_properties[i]);
372 properties[i]->setScale(scale_pointer);
373 }
374 }
375}
376
378 PropertyArray& properties,
379 std::vector<std::unique_ptr<Phase>> const& phases)
380{
381 for (auto& p : properties)
382 {
383 if (p != nullptr)
384 {
385 p->setProperties(phases);
386 }
387 }
388}
389
390} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:10
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
This class defines components (substances).
Definition Component.h:18
virtual void setProperties(std::vector< std::unique_ptr< Phase > > const &phases)
Default implementation:
virtual PropertyDataType d2Value(VariableArray const &variable_array, Variable const variable1, Variable const variable2, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const
Default implementation: 2nd derivative of any constant property is zero.
static constexpr std::array property_data_type_names_
Corresponds to the PropertyDataType.
T dValue(VariableArray const &variable_array, VariableArray const &variable_array_prev, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const
T value(VariableArray const &variable_array, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const
T d2Value(VariableArray const &variable_array, Variable const &variable1, Variable const &variable2, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const
PropertyDataType value_
The single value of a property.
T dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const
T initialValue(ParameterLib::SpatialPosition const &pos, double const t) const
virtual PropertyDataType value() const
void setScale(std::variant< Medium *, Phase *, Component * > scale)
T value(VariableArray const &variable_array, VariableArray const &variable_array_prev, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const
std::variant< Medium *, Phase *, Component * > scale_
virtual PropertyDataType initialValue(ParameterLib::SpatialPosition const &pos, double const t) const
virtual PropertyDataType dValue(VariableArray const &variable_array, VariableArray const &variable_array_prev, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const
std::string typeToString()
void overwriteExistingProperties(PropertyArray &properties, PropertyArray &new_properties, std::variant< Medium *, Phase *, Component * > scale_pointer)
PropertyDataType fromVector(std::vector< double > const &values)
std::array< std::unique_ptr< Property >, PropertyType::number_of_properties > PropertyArray
void updatePropertiesForAllPhases(PropertyArray &properties, std::vector< std::unique_ptr< Phase > > const &phases)
PropertyDataType fromArray(std::array< double, N > const &values)
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