OGS
ThermodynamicForcesView.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 <boost/mp11.hpp>
8
10{
13{
14 std::vector<double> data;
15};
16
34template <int DisplacementDim, typename TDynForces>
36{
37 static_assert(boost::mp11::mp_is_set<TDynForces>::value,
38 "The types in the list TDynForces are not unique.");
39
41 template <typename Variable>
42 struct SizeOf
43 : boost::mp11::mp_size_t<Variable::template size<DisplacementDim>()>
44 {
45 };
46
49 template <typename Force>
50 static constexpr std::size_t dataOffset()
51 {
52 using namespace boost::mp11;
53 static_assert(mp_contains<TDynForces, Force>::value,
54 "The type Force is not in the list TDynForces.");
55
56 using ForceIndex = mp_find<TDynForces, Force>;
57
58 using ForcesHead = mp_take<TDynForces, ForceIndex>;
59
60 using Sizes = mp_transform<SizeOf, ForcesHead>;
61
62 return mp_apply<mp_plus, Sizes>::value;
63 }
64
66 template <typename Force, typename DataVector>
67 static constexpr auto asEigenMap(DataVector& data)
68 {
69 static_assert(Force::template size<DisplacementDim>() != 1,
70 "Use asDouble for the single component case.");
71
72 assert(data.size() == data_size_all_forces);
73
74 constexpr std::size_t data_offset = dataOffset<Force>();
75
76 constexpr std::size_t rows = Force::template rows<DisplacementDim>();
77 constexpr std::size_t cols = Force::template cols<DisplacementDim>();
78 constexpr auto order = cols == 1 ? Eigen::ColMajor : Eigen::RowMajor;
79
80 using MatrixType =
81 std::conditional_t<std::is_const_v<DataVector>,
82 const Eigen::Matrix<double, rows, cols, order>,
83 Eigen::Matrix<double, rows, cols, order>>;
84
85 return Eigen::Map<MatrixType>(data.data() + data_offset);
86 }
87
89 template <typename Force, typename DataVector>
90 static constexpr auto& asDouble(DataVector& data)
91 {
92 static_assert(Force::template size<DisplacementDim>() == 1,
93 "Use asEigenMap for the multi component case.");
94
95 assert(data.size() == data_size_all_forces);
96
97 constexpr std::size_t data_offset = dataOffset<Force>();
98
99 return data[data_offset];
100 }
101
102public:
104 template <typename Force>
105 auto block(Force force, OGSMFrontThermodynamicForcesData const& data) const
106 {
107 return block(force, data.data);
108 }
109
111 template <typename Force>
112 auto block(Force, std::vector<double> const& data) const
113 {
114 constexpr std::size_t data_size =
115 Force::template size<DisplacementDim>();
116
117 if constexpr (data_size == 1)
118 {
119 return asDouble<Force>(data);
120 }
121 else
122 {
123 return asEigenMap<Force>(data);
124 }
125 }
126
131 template <typename Force,
132 std::enable_if_t<SizeOf<Force>::value == 1, bool> = true>
133 double& block(Force force, OGSMFrontThermodynamicForcesData& data) const
134 {
135 return block(force, data.data);
136 }
137
139 template <typename Force,
140 std::enable_if_t<SizeOf<Force>::value == 1, bool> = true>
141 double& block(Force, std::vector<double>& data) const
142 {
143 return asDouble<Force>(data);
144 }
145
150 template <typename Force,
151 std::enable_if_t<SizeOf<Force>::value != 1, bool> = true>
152 auto block(Force force, OGSMFrontThermodynamicForcesData& data) const
153 {
154 return block(force, data.data);
155 }
156
158 template <typename Force,
159 std::enable_if_t<SizeOf<Force>::value != 1, bool> = true>
160 auto block(Force, std::vector<double>& data) const
161 {
162 return asEigenMap<Force>(data);
163 }
164
166 static constexpr std::size_t data_size_all_forces = boost::mp11::mp_apply<
167 boost::mp11::mp_plus,
168 boost::mp11::mp_transform<SizeOf, TDynForces>>::value;
169};
170} // namespace MaterialLib::Solids::MFront
static constexpr std::size_t data_size_all_forces
The passed data to the block() methods must have this size.
auto block(Force, std::vector< double > &data) const
Overload taking a std::vector.
double & block(Force force, OGSMFrontThermodynamicForcesData &data) const
auto block(Force force, OGSMFrontThermodynamicForcesData &data) const
static constexpr auto & asDouble(DataVector &data)
Access a block of the given data as a double value.
double & block(Force, std::vector< double > &data) const
Overload taking a std::vector.
auto block(Force, std::vector< double > const &data) const
Overload taking a std::vector.
static constexpr auto asEigenMap(DataVector &data)
Access a block of the given data as an Eigen::Map.
auto block(Force force, OGSMFrontThermodynamicForcesData const &data) const
Read-only access to the data for the given thermodynamic force Force.
Used for disambiguation with MFront's tangent operator blocks data.
A template metafunction accessing the size of the given Variable.