7#include <Eigen/Geometry>
18static double const tolerance = std::numeric_limits<double>::epsilon();
22 Eigen::Matrix<double, Dim, Dim, Eigen::ColMajor, Dim, Dim>
const& t)
24 if (std::abs(t.determinant() - 1) >
tolerance)
27 "The determinant of the coordinate system transformation matrix is "
28 "'{:g}', which is not sufficiently close to unity with the "
29 "tolerance of '{:g}'. Please adjust the accuracy of the local "
33 if (((t * t.transpose() - Eigen::Matrix<double, Dim, Dim>::Identity())
38 "The transformation is not orthogonal because the difference "
39 "A*A^T - I is:\n{}\nand at least one component deviates from zero "
40 "by more then '{:g}'.",
41 (t * t.transpose() - Eigen::Matrix<double, Dim, Dim>::Identity())
47template <
typename Derived>
49 std::string_view
const parmeter_name)
51 if (std::abs(vec.squaredNorm() - 1.0) >
tolerance)
54 "The direction vector given by parameter {:s} for the "
55 "local_coordinate_system is not normalized to unit length. Vector "
56 "norm is {:g} and |v|^2-1 = {:g}.",
57 parmeter_name, vec.norm(), vec.squaredNorm() - 1.0);
64 if (
_base[2]->isTimeDependent())
67 "The unit_normal parameter named {} must not be time dependent.",
79 "The parameter types for the basis must be equal but they are "
84 if (
_base[0]->isTimeDependent() ||
_base[1]->isTimeDependent())
86 OGS_FATAL(
"The parameters for the basis must not be time dependent.");
88 if (
_base[0]->getNumberOfGlobalComponents() != 2 ||
89 _base[1]->getNumberOfGlobalComponents() != 2)
91 OGS_FATAL(
"The parameters for the 2D basis must have two components.");
105 "The parameter types for the basis must be equal but they are "
106 "'{:s}', '{:s}', and '{:s}'.",
111 if (
_base[0]->isTimeDependent() ||
_base[1]->isTimeDependent(),
112 _base[2]->isTimeDependent())
114 OGS_FATAL(
"The parameters for the basis must not be time dependent.");
116 if (
_base[0]->getNumberOfGlobalComponents() != 3 ||
117 _base[1]->getNumberOfGlobalComponents() != 3 ||
118 _base[2]->getNumberOfGlobalComponents() != 3)
121 "The parameters for the 3D basis must have three components.");
128 auto const& normal = unit_direction(0 , pos);
130 unit_direction.
name);
132 Eigen::Matrix<double, 2, 2> t;
135 t << normal[1], normal[0], -normal[0], normal[1];
150 if (
_base[2] !=
nullptr)
153 "The coordinate system is 3D but a transformation for 2D case is "
157 Eigen::Matrix<double, 2, 2> t;
158 t.col(0) = Eigen::Map<Eigen::Vector2d>(
159 (*
_base[0])(0 , pos).data());
160 t.col(1) = Eigen::Map<Eigen::Vector2d>(
161 (*
_base[1])(0 , pos).data());
170 auto const& normal = unit_direction(0 , pos);
172 Eigen::Matrix<double, 3, 3> t;
174 e2 = Eigen::Map<Eigen::Vector3d const>(normal.data());
179 e2.cwiseAbs().maxCoeff(&
id);
182 const auto id_a = (
id + 1) % 3;
183 const auto id_b = (
id + 2) % 3;
187 e1 = Eigen::Vector3d::Zero();
200 e1[id_b] = -e2[id_a] / e2[id_b];
208 t.col(0) = e1.cross(e2);
224 if (
_base[2] ==
nullptr)
227 "The coordinate system is 2D but a transformation for 3D case is "
231 Eigen::Matrix<double, 3, 3> t;
232 t.col(0) = Eigen::Map<Eigen::Vector3d>(
233 (*
_base[0])(0 , pos).data());
234 t.col(1) = Eigen::Map<Eigen::Vector3d>(
235 (*
_base[1])(0 , pos).data());
236 t.col(2) = Eigen::Map<Eigen::Vector3d>(
237 (*
_base[2])(0 , pos).data());
247 if ((*
_base[2])(0 , pos).size() == 3)
253 Eigen::Matrix<double, 3, 3> t = Eigen::Matrix<double, 3, 3>::Identity();
267 if (
_base[2] !=
nullptr)
272 auto e0 = (*
_base[0])(0 , pos);
273 auto e1 = (*
_base[1])(0 , pos);
274 Eigen::Matrix<double, 3, 3> t = Eigen::Matrix<double, 3, 3>::Identity();
275 t.template topLeftCorner<2, 2>() << e0[0], e1[0], e0[1], e1[1];
281template <
int Dimension>
285 assert(values.size() == Dimension * Dimension ||
286 "Input vector has wrong dimension; expected 4 or 9 entries.");
288 Eigen::Map<Eigen::Matrix<double, Dimension, Dimension>
const>(
289 values.data(), Dimension, Dimension);
293template <
int Dimension>
294Eigen::Matrix<double, Dimension, Dimension>
298 assert(values.size() == Dimension ||
299 "Input vector has wrong dimension; expected 2 or 3 entries.");
300 auto const tensor = Eigen::Map<Eigen::Matrix<double, Dimension, 1>
const>(
301 values.data(), Dimension, 1);
303 return R * tensor.asDiagonal() * R.transpose();
std::string typeToString()
Eigen::Matrix< double, 2, 2 > getTransformationFromSingleBase2D(Parameter< double > const &unit_direction, SpatialPosition const &pos)
static double const tolerance
static void checkNormalization(Eigen::MatrixBase< Derived > const &vec, std::string_view const parmeter_name)
static void checkTransformationIsSON(Eigen::Matrix< double, Dim, Dim, Eigen::ColMajor, Dim, Dim > const &t)
Eigen::Matrix< double, 3, 3 > getTransformationFromSingleBase3D(Parameter< double > const &unit_direction, SpatialPosition const &pos)
std::array< Parameter< double > const *, 3 > _base
Eigen::Matrix< double, Dimension, Dimension > transformation(SpatialPosition const &pos) const
Eigen::Matrix< double, 3, 3 > transformationFromSingleBase_3d(SpatialPosition const &pos) const
Eigen::Matrix< double, 3, 3 > transformation_3d(SpatialPosition const &pos) const
Eigen::Matrix< double, Dimension, Dimension > rotateTensor(std::vector< double > const &values, SpatialPosition const &pos) const
Eigen::Matrix< double, Dimension, Dimension > rotateDiagonalTensor(std::vector< double > const &values, SpatialPosition const &pos) const
CoordinateSystem(Parameter< double > const &unit_direction)