OGS
ThermodynamicForcesView.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <Eigen/Core>
14#include <boost/mp11.hpp>
15
17{
20{
21 std::vector<double> data;
22};
23
41template <int DisplacementDim, typename TDynForces>
43{
44 static_assert(boost::mp11::mp_is_set<TDynForces>::value,
45 "The types in the list TDynForces are not unique.");
46
48 template <typename Variable>
49 struct SizeOf
50 : boost::mp11::mp_size_t<Variable::template size<DisplacementDim>()>
51 {
52 };
53
56 template <typename Force>
57 static constexpr std::size_t dataOffset()
58 {
59 using namespace boost::mp11;
60 static_assert(mp_contains<TDynForces, Force>::value,
61 "The type Force is not in the list TDynForces.");
62
63 using ForceIndex = mp_find<TDynForces, Force>;
64
65 using ForcesHead = mp_take<TDynForces, ForceIndex>;
66
67 using Sizes = mp_transform<SizeOf, ForcesHead>;
68
69 return mp_apply<mp_plus, Sizes>::value;
70 }
71
73 template <typename Force, typename DataVector>
74 static constexpr auto asEigenMap(DataVector& data)
75 {
76 static_assert(Force::template size<DisplacementDim>() != 1,
77 "Use asDouble for the single component case.");
78
79 assert(data.size() == data_size_all_forces);
80
81 constexpr std::size_t data_offset = dataOffset<Force>();
82
83 constexpr std::size_t rows = Force::template rows<DisplacementDim>();
84 constexpr std::size_t cols = Force::template cols<DisplacementDim>();
85 constexpr auto order = cols == 1 ? Eigen::ColMajor : Eigen::RowMajor;
86
87 using MatrixType =
88 std::conditional_t<std::is_const_v<DataVector>,
89 const Eigen::Matrix<double, rows, cols, order>,
90 Eigen::Matrix<double, rows, cols, order>>;
91
92 return Eigen::Map<MatrixType>(data.data() + data_offset);
93 }
94
96 template <typename Force, typename DataVector>
97 static constexpr auto& asDouble(DataVector& data)
98 {
99 static_assert(Force::template size<DisplacementDim>() == 1,
100 "Use asEigenMap for the multi component case.");
101
102 assert(data.size() == data_size_all_forces);
103
104 constexpr std::size_t data_offset = dataOffset<Force>();
105
106 return data[data_offset];
107 }
108
109public:
111 template <typename Force>
112 auto block(Force force, OGSMFrontThermodynamicForcesData const& data) const
113 {
114 return block(force, data.data);
115 }
116
118 template <typename Force>
119 auto block(Force, std::vector<double> const& data) const
120 {
121 constexpr std::size_t data_size =
122 Force::template size<DisplacementDim>();
123
124 if constexpr (data_size == 1)
125 {
126 return asDouble<Force>(data);
127 }
128 else
129 {
130 return asEigenMap<Force>(data);
131 }
132 }
133
138 template <typename Force,
139 std::enable_if_t<SizeOf<Force>::value == 1, bool> = true>
140 double& block(Force force, OGSMFrontThermodynamicForcesData& data) const
141 {
142 return block(force, data.data);
143 }
144
146 template <typename Force,
147 std::enable_if_t<SizeOf<Force>::value == 1, bool> = true>
148 double& block(Force, std::vector<double>& data) const
149 {
150 return asDouble<Force>(data);
151 }
152
157 template <typename Force,
158 std::enable_if_t<SizeOf<Force>::value != 1, bool> = true>
159 auto block(Force force, OGSMFrontThermodynamicForcesData& data) const
160 {
161 return block(force, data.data);
162 }
163
165 template <typename Force,
166 std::enable_if_t<SizeOf<Force>::value != 1, bool> = true>
167 auto block(Force, std::vector<double>& data) const
168 {
169 return asEigenMap<Force>(data);
170 }
171
173 static constexpr std::size_t data_size_all_forces = boost::mp11::mp_apply<
174 boost::mp11::mp_plus,
175 boost::mp11::mp_transform<SizeOf, TDynForces>>::value;
176};
177} // 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.