OGS
FormEigenTensor.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 <type_traits>
8#include <variant>
9
12
13namespace MaterialPropertyLib
14{
15template <int GlobalDim>
17{
18 constexpr Eigen::Matrix<double, GlobalDim, GlobalDim> operator()(
19 double const& value) const
20 {
21 return Eigen::Matrix<double, GlobalDim, GlobalDim>::Identity() * value;
22 }
23
24 // Constexpr version for GlobalDim == 2 (valid case)
25 template <int Dim = GlobalDim>
26 constexpr std::enable_if_t<Dim == 2, Eigen::Matrix<double, 2, 2>>
27 operator()(Eigen::Vector2d const& values) const
28 {
29 return values.asDiagonal();
30 }
31
32 // Non-constexpr version for invalid GlobalDim values
33 template <int Dim = GlobalDim>
34 constexpr std::enable_if_t<Dim != 2,
35 Eigen::Matrix<double, GlobalDim, GlobalDim>>
36 operator()(Eigen::Vector2d const& values) const
37 {
39 "Cannot convert 2d vector with values [{}] to {:d}x{:d} diagonal "
40 "matrix.",
41 values, GlobalDim, GlobalDim);
42 }
43
44 // Constexpr version for GlobalDim == 3 (valid case)
45 template <int Dim = GlobalDim>
46 constexpr std::enable_if_t<Dim == 3, Eigen::Matrix<double, 3, 3>>
47 operator()(Eigen::Vector3d const& values) const
48 {
49 return values.asDiagonal();
50 }
51
52 // Non-constexpr version for invalid GlobalDim values
53 template <int Dim = GlobalDim>
54 constexpr std::enable_if_t<Dim != 3,
55 Eigen::Matrix<double, GlobalDim, GlobalDim>>
56 operator()(Eigen::Vector3d const& values) const
57 {
59 "Cannot convert 3d vector with values [{}] to {:d}x{:d} diagonal "
60 "matrix.",
61 values, GlobalDim, GlobalDim);
62 }
63
64 // Constexpr version for GlobalDim == 2 (valid case)
65 template <int Dim = GlobalDim>
66 constexpr std::enable_if_t<Dim == 2, Eigen::Matrix<double, 2, 2>>
67 operator()(Eigen::Matrix<double, 2, 2> const& values) const
68 {
69 return values;
70 }
71
72 // Non-constexpr version for invalid GlobalDim values
73 template <int Dim = GlobalDim>
74 constexpr std::enable_if_t<Dim != 2,
75 Eigen::Matrix<double, GlobalDim, GlobalDim>>
76 operator()(Eigen::Matrix<double, 2, 2> const& values) const
77 {
79 "Cannot convert a 2d tensor with values [{}] to {:d}x{:d} matrix",
80 values, GlobalDim, GlobalDim);
81 }
82
83 // Constexpr version for GlobalDim == 3 (valid case)
84 template <int Dim = GlobalDim>
85 constexpr std::enable_if_t<Dim == 3, Eigen::Matrix<double, 3, 3>>
86 operator()(Eigen::Matrix<double, 3, 3> const& values) const
87 {
88 return values;
89 }
90
91 // Non-constexpr version for invalid GlobalDim values
92 template <int Dim = GlobalDim>
93 constexpr std::enable_if_t<Dim != 3,
94 Eigen::Matrix<double, GlobalDim, GlobalDim>>
95 operator()(Eigen::Matrix<double, 3, 3> const& values) const
96 {
98 "Cannot convert a 3d tensor with values [{}] to {:d}x{:d} matrix",
99 values, GlobalDim, GlobalDim);
100 }
101
102 constexpr Eigen::Matrix<double, GlobalDim, GlobalDim> operator()(
103 Eigen::Matrix<double, 4, 1> const& values) const
104 {
105 if constexpr (GlobalDim == 2)
106 { // skip the z-direction in this case
107 Eigen::Matrix<double, GlobalDim, GlobalDim> result;
108 result << values[0], values[3], values[3], values[1];
109 return result;
110 }
111 else if constexpr (GlobalDim == 3)
112 {
113 Eigen::Matrix<double, GlobalDim, GlobalDim> result;
114 result << values[0], values[3], 0, values[3], values[1], 0, 0, 0,
115 values[2];
116 return result;
117 }
118 // For other dimensions, we need to provide a fallback to avoid missing
119 // return warning
120 OGS_FATAL("Cannot convert 4d vector to {:d}x{:d} matrix", GlobalDim,
121 GlobalDim);
122 }
123
124 // Constexpr version for GlobalDim == 3 (valid case)
125 template <int Dim = GlobalDim>
126 constexpr std::enable_if_t<Dim == 3, Eigen::Matrix<double, 3, 3>>
127 operator()(Eigen::Matrix<double, 6, 1> const& values) const
128 {
129 Eigen::Matrix<double, 3, 3> result;
130 result << values[0], values[3], values[5], values[3], values[1],
131 values[4], values[5], values[4], values[2];
132 return result;
133 }
134
135 // Non-constexpr version for invalid GlobalDim values
136 template <int Dim = GlobalDim>
137 constexpr std::enable_if_t<Dim != 3,
138 Eigen::Matrix<double, GlobalDim, GlobalDim>>
139 operator()(Eigen::Matrix<double, 6, 1> const& values) const
140 {
141 OGS_FATAL(
142 "Cannot convert a symmetric 3d tensor with values [{}] to a {}x{} "
143 "matrix",
144 values, GlobalDim, GlobalDim);
145 }
146
147 Eigen::Matrix<double, GlobalDim, GlobalDim> operator()(
148 Eigen::MatrixXd const& values) const
149 {
150 if (GlobalDim == values.rows() && GlobalDim == values.cols())
151 {
152 return values;
153 }
154
155 OGS_FATAL(
156 "Cannot convert a dynamic {}x{} matrix with values [{}] to a {}x{} "
157 "matrix",
158 values.rows(), values.cols(), values, GlobalDim, GlobalDim);
159 }
160};
161
162template <int GlobalDim>
163constexpr Eigen::Matrix<double, GlobalDim, GlobalDim> formEigenTensor(
165{
166 return std::visit(FormEigenTensor<GlobalDim>(), values);
167}
168
169} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:19
constexpr Eigen::Matrix< double, GlobalDim, GlobalDim > formEigenTensor(MaterialPropertyLib::PropertyDataType 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
constexpr std::enable_if_t< Dim==2, Eigen::Matrix< double, 2, 2 > > operator()(Eigen::Matrix< double, 2, 2 > const &values) const
constexpr Eigen::Matrix< double, GlobalDim, GlobalDim > operator()(Eigen::Matrix< double, 4, 1 > const &values) const
constexpr std::enable_if_t< Dim !=3, Eigen::Matrix< double, GlobalDim, GlobalDim > > operator()(Eigen::Vector3d const &values) const
Eigen::Matrix< double, GlobalDim, GlobalDim > operator()(Eigen::MatrixXd const &values) const
constexpr Eigen::Matrix< double, GlobalDim, GlobalDim > operator()(double const &value) const
constexpr std::enable_if_t< Dim !=3, Eigen::Matrix< double, GlobalDim, GlobalDim > > operator()(Eigen::Matrix< double, 3, 3 > const &values) const
constexpr std::enable_if_t< Dim==2, Eigen::Matrix< double, 2, 2 > > operator()(Eigen::Vector2d const &values) const
constexpr std::enable_if_t< Dim !=2, Eigen::Matrix< double, GlobalDim, GlobalDim > > operator()(Eigen::Matrix< double, 2, 2 > const &values) const
constexpr std::enable_if_t< Dim==3, Eigen::Matrix< double, 3, 3 > > operator()(Eigen::Vector3d const &values) const
constexpr std::enable_if_t< Dim !=2, Eigen::Matrix< double, GlobalDim, GlobalDim > > operator()(Eigen::Vector2d const &values) const
constexpr std::enable_if_t< Dim==3, Eigen::Matrix< double, 3, 3 > > operator()(Eigen::Matrix< double, 3, 3 > const &values) const
constexpr std::enable_if_t< Dim !=3, Eigen::Matrix< double, GlobalDim, GlobalDim > > operator()(Eigen::Matrix< double, 6, 1 > const &values) const
constexpr std::enable_if_t< Dim==3, Eigen::Matrix< double, 3, 3 > > operator()(Eigen::Matrix< double, 6, 1 > const &values) const