OGS
MathLib::VectorizedTensor Namespace Reference

Detailed Description

Namespace for vectorized second-order tensor types and operations on those. The tensors are for example, deformation gradients.

Typedefs

template<int DisplacementDim>
using Type = Eigen::Matrix<double, size(DisplacementDim), 1, Eigen::ColMajor>

Functions

bool isTensorConvertibleTo1d (Eigen::Matrix3d const &tensor)
 Only a diagonal tensor can be converted to a 1d vectorized tensor.
bool isTensorConvertibleTo2d (Eigen::Matrix3d const &tensor)
constexpr int size (int const displacement_dim)
 Vectorized tensor size for given displacement dimension.
template<typename VectorizedTensor>
constexpr int dimension ()
 Displacement dimension of a vectorized tensor.
template<int DisplacementDim>
constexpr auto identity ()
template<typename Derived>
double determinant (Eigen::MatrixBase< Derived > const &tensor)
 Computes determinant of a vectorized tensor.
template<int DisplacementDim, typename Derived>
Type< DisplacementDim > toVector (Eigen::MatrixBase< Derived > const &tensor)
template<int DisplacementDim>
Eigen::Matrix3d toTensor (Type< DisplacementDim > const &tensor)
 Converts a vectorized tensor to a 3x3 matrix.

Typedef Documentation

◆ Type

template<int DisplacementDim>
using MathLib::VectorizedTensor::Type = Eigen::Matrix<double, size(DisplacementDim), 1, Eigen::ColMajor>

Vectorized tensor type for given displacement dimension.

Note
The Eigen vector is always a fixed size vector in contrast to a shape matrix policy types like GMatrixPolicyType::GradientVectorType.

Definition at line 66 of file VectorizedTensor.h.

Function Documentation

◆ determinant()

template<typename Derived>
double MathLib::VectorizedTensor::determinant ( Eigen::MatrixBase< Derived > const & tensor)

Computes determinant of a vectorized tensor.

Definition at line 105 of file VectorizedTensor.h.

106{
107 constexpr int displacement_dim = dimension<Derived>();
108 static_assert(0 < displacement_dim && displacement_dim <= 3,
109 "Vectorized tensor determinant is implemented only for "
110 "displacement dimension 1, 2, or 3.");
111
112 if constexpr (displacement_dim == 1)
113 {
114 return tensor[0] * tensor[1] * tensor[2];
115 }
116 if constexpr (displacement_dim == 2)
117 {
118 Eigen::Map<Eigen::Matrix2d const> const top_left{
119 tensor.derived().data()};
120
121 return top_left.determinant() * tensor[4];
122 }
123 if constexpr (displacement_dim == 3)
124 {
125 return Eigen::Map<Eigen::Matrix3d const>(tensor.derived().data())
126 .determinant();
127 }
128}
constexpr int dimension()
Displacement dimension of a vectorized tensor.

References dimension().

Referenced by ProcessLib::NonLinearFbar::computeFBarInitialVariablesAverage(), ProcessLib::NonLinearFbar::computeFBarInitialVariablesElementCenter(), and ProcessLib::LargeDeformation::LargeDeformationLocalAssembler< ShapeFunction, DisplacementDim >::computeOutputStrainData().

◆ dimension()

template<typename VectorizedTensor>
int MathLib::VectorizedTensor::dimension ( )
constexpr

Displacement dimension of a vectorized tensor.

Definition at line 40 of file VectorizedTensor.h.

41{
42 static_assert(VectorizedTensor::ColsAtCompileTime == 1);
43 constexpr int rows = VectorizedTensor::RowsAtCompileTime;
44 if (rows == 3)
45 {
46 return 1;
47 }
48 if (rows == 5)
49 {
50 return 2;
51 }
52 if (rows == 9)
53 {
54 return 3;
55 }
57 "Cannot convert vectorized tensor of size {} to displacement "
58 "dimension.",
59 rows);
60}
#define OGS_FATAL(...)
Definition Error.h:19

References OGS_FATAL.

Referenced by determinant().

◆ identity()

template<int DisplacementDim>
auto MathLib::VectorizedTensor::identity ( )
constexpr

Vectorized identity tensor expression. Corresponds to 3x3 identity matrix in all dimensions.

Definition at line 71 of file VectorizedTensor.h.

72{
73 static_assert(
74 0 < DisplacementDim && DisplacementDim <= 3,
75 "Identity is implemented only for displacement dimension 1, 2, or 3.");
77 size(DisplacementDim), 1,
78 [](Eigen::Index const row, [[maybe_unused]] Eigen::Index const col)
79 {
80 assert(col == 0);
81 if constexpr (DisplacementDim == 1)
82 { // All entries are diagonal entries.
83 return 1;
84 }
85 if constexpr (DisplacementDim == 2)
86 {
87 if (row == 0 || row == 3 || row == 4)
88 {
89 return 1;
90 }
91 }
92 if constexpr (DisplacementDim == 3)
93 {
94 if (row == 0 || row == 4 || row == 8)
95 {
96 return 1;
97 }
98 }
99 return 0;
100 });
101}
constexpr int size(int const displacement_dim)
Vectorized tensor size for given displacement dimension.
Eigen::Matrix< double, size(DisplacementDim), 1, Eigen::ColMajor > Type

References size().

Referenced by ProcessLib::NonLinearFbar::computeFBarInitialVariablesAverage(), ProcessLib::NonLinearFbar::computeFBarInitialVariablesElementCenter(), ProcessLib::LargeDeformation::LargeDeformationLocalAssembler< ShapeFunction, DisplacementDim >::computeOutputStrainData(), and ProcessLib::LargeDeformation::LargeDeformationLocalAssembler< ShapeFunction, DisplacementDim >::updateConstitutiveRelations().

◆ isTensorConvertibleTo1d()

bool MathLib::VectorizedTensor::isTensorConvertibleTo1d ( Eigen::Matrix3d const & tensor)

Only a diagonal tensor can be converted to a 1d vectorized tensor.

Definition at line 9 of file VectorizedTensor.cpp.

10{
11 return (tensor(0, 1) == 0. && tensor(1, 0) == 0. && //
12 tensor(0, 2) == 0. && tensor(2, 0) == 0. && //
13 tensor(1, 2) == 0. && tensor(2, 1) == 0.);
14}

Referenced by toVector().

◆ isTensorConvertibleTo2d()

bool MathLib::VectorizedTensor::isTensorConvertibleTo2d ( Eigen::Matrix3d const & tensor)

Only a tensor of form \( \left( \begin{array}{ccc} a & b & 0 \\% c & d & 0 \\% 0 & 0 & e \\% \end{array} \right)\) can be converted to a 2d vectorized tensor.

Definition at line 16 of file VectorizedTensor.cpp.

17{
18 return (tensor(0, 2) == 0. && tensor(1, 2) == 0. && //
19 tensor(2, 0) == 0. && tensor(2, 1) == 0.);
20}

Referenced by toVector().

◆ size()

int MathLib::VectorizedTensor::size ( int const displacement_dim)
constexpr

Vectorized tensor size for given displacement dimension.

Definition at line 19 of file VectorizedTensor.h.

20{
21 if (displacement_dim == 1)
22 {
23 return 3;
24 }
25 if (displacement_dim == 2)
26 {
27 return 5;
28 }
29 if (displacement_dim == 3)
30 {
31 return 9;
32 }
34 "Cannot convert displacement dimension {} to vectorized tensor size.",
35 displacement_dim);
36}

References OGS_FATAL.

Referenced by MaterialPropertyLib::Function::Implementation< D >::createSymbolTable(), and identity().

◆ toTensor()

template<int DisplacementDim>
Eigen::Matrix3d MathLib::VectorizedTensor::toTensor ( Type< DisplacementDim > const & tensor)

Converts a vectorized tensor to a 3x3 matrix.

Definition at line 198 of file VectorizedTensor.h.

199{
200 static_assert(
201 DisplacementDim == 1 || DisplacementDim == 2 || DisplacementDim == 3,
202 "Conversion from displacement dimension other than 1, 2, or 3 "
203 "is not valid.");
204
205 using Matrix = Eigen::Matrix3d;
206 if constexpr (DisplacementDim == 1)
207 {
208 return tensor.asDiagonal();
209 }
210 if constexpr (DisplacementDim == 2)
211 {
212 Matrix m = Matrix::Zero();
213 m.template block<2, 2>(0, 0) =
214 Eigen::Map<Eigen::Matrix<double, 2, 2> const>(tensor.data());
215 m(2, 2) = tensor(4);
216 return m;
217 }
218 if constexpr (DisplacementDim == 3)
219 {
220 return Eigen::Map<Matrix const>(tensor.data());
221 }
222}

Referenced by ProcessLib::NonLinearFbar::computeFBarInitialVariablesAverage(), and ProcessLib::NonLinearFbar::computeQVector().

◆ toVector()

template<int DisplacementDim, typename Derived>
Type< DisplacementDim > MathLib::VectorizedTensor::toVector ( Eigen::MatrixBase< Derived > const & tensor)

Converts a 3x3 matrix expression to a vectorized tensor if the conversion for that dimension is possible; see isTensorConvertibleTo1d() and isTensorConvertibleTo2d() functions.

Definition at line 146 of file VectorizedTensor.h.

147{
148 static_assert(0 < DisplacementDim && DisplacementDim <= 3,
149 "Conversion to displacement dimension other than 1, 2, or 3 "
150 "is not valid.");
151
152 constexpr int rows = Derived::RowsAtCompileTime;
153 constexpr int cols = Derived::ColsAtCompileTime;
154 static_assert(rows == 3 || rows == Eigen::Dynamic);
155 static_assert(cols == 3 || cols == Eigen::Dynamic);
156 if (tensor.rows() != 3 || tensor.cols() != 3)
157 {
158 OGS_FATAL(
159 "Incorrect tensor size, must be 3x3, but tensor is {:d}x{:d}.",
160 tensor.rows(), tensor.cols());
161 }
162
163 if constexpr (DisplacementDim == 1)
164 {
165 if (!isTensorConvertibleTo1d(tensor))
166 {
167 OGS_FATAL(
168 "Cannot convert a tensor with non-zero off-diagonal elements "
169 "to a 1d vectorized tensor representation.");
170 }
171 return tensor.diagonal();
172 }
173 if constexpr (DisplacementDim == 2)
174 {
175 if (!isTensorConvertibleTo2d(tensor))
176 {
177 OGS_FATAL(
178 "Cannot convert a tensor with non-zero elements at (0, 2), (1, "
179 "2), (2, 0), and (2, 1) positions to a 2d vectorized tensor "
180 "representation.");
181 }
182 Type<2> result;
183 result.template head<4>() =
184 tensor.template block<2, 2>(0, 0).reshaped();
185 result(4) = tensor(2, 2);
186 return result;
187 }
188 if constexpr (DisplacementDim == 3)
189 {
190 return tensor.reshaped();
191 }
192 OGS_FATAL(
193 "Not all cases handled in the VectorizedTensor::toVector() function.");
194}
bool isTensorConvertibleTo2d(Eigen::Matrix3d const &tensor)
bool isTensorConvertibleTo1d(Eigen::Matrix3d const &tensor)
Only a diagonal tensor can be converted to a 1d vectorized tensor.

References isTensorConvertibleTo1d(), isTensorConvertibleTo2d(), and OGS_FATAL.