OGS
ReflectionSetIPData.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <Eigen/Core>
14#include <vector>
15
17#include "ReflectionIPData.h"
18
20{
21namespace detail
22{
23template <int dim, typename IPData, typename Accessor>
24void setIPData(double const* values,
25 std::vector<IPData>& ip_data_vector,
26 Accessor const& accessor)
27{
28 using AccessorResult = std::invoke_result_t<Accessor, IPData&>;
29 using AccessorResultStripped = std::remove_cvref_t<AccessorResult>;
30
31 static_assert(is_raw_data_v<AccessorResultStripped>,
32 "This method only deals with raw data. The given "
33 "AccessorResultStripped is not raw data.");
34
36
37 auto const num_int_pts = ip_data_vector.size();
38
39 if constexpr (num_comp == 1)
40 {
41 // scalar
42 for (unsigned ip = 0; ip < num_int_pts; ++ip)
43 {
44 accessor(ip_data_vector[ip]) = values[ip];
45 }
46 }
47 else
48 {
49 constexpr auto num_rows = NumberOfRows<AccessorResultStripped>::value;
50 constexpr auto num_cols =
52 constexpr auto kv_size =
54
55 auto const values_mat =
56 Eigen::Map<Eigen::Matrix<double, num_comp, Eigen::Dynamic,
57 Eigen::ColMajor> const>(values, num_comp,
58 num_int_pts);
59
60 for (unsigned ip = 0; ip < num_int_pts; ++ip)
61 {
62 if constexpr (num_cols == 1 || num_rows == 1)
63 {
64 // vector
65 if constexpr (num_comp == kv_size)
66 {
67 // Kelvin vector
68 accessor(ip_data_vector[ip]) =
70 values_mat.col(ip));
71 }
72 else
73 {
74 // other vector
75 accessor(ip_data_vector[ip]) = values_mat.col(ip);
76 }
77 }
78 else
79 {
80 // matrix
81 accessor(ip_data_vector[ip]) =
82 values_mat.col(ip).template reshaped<Eigen::RowMajor>(
83 num_rows, num_cols);
84 }
85 }
86 }
87}
88
89// Sets IP data if the passed name equals the one in refl_data.
90// Returns true if IP have been set, false otherwise.
91template <int dim, typename IPData, typename Accessor_CurrentLevelFromIPData,
92 typename Class, typename Accessor>
93bool setIPDataIfNameMatches(std::string_view const name, double const* values,
94 std::vector<IPData>& ip_data_vector,
95 Accessor_CurrentLevelFromIPData const& accessor,
96 ReflectionData<Class, Accessor> const& refl_data)
97{
98 auto const accessor_next_level = refl_data.accessor;
99
100 using MemberRef = std::invoke_result_t<Accessor, Class&>;
101 using Member = std::remove_cvref_t<MemberRef>;
102
103 auto const accessor_field_from_ip_data =
104 [accessor, accessor_next_level](IPData& ip_data) -> Member&
105 { return accessor_next_level(accessor(ip_data)); };
106
107 if constexpr (detail::is_reflectable<Member>)
108 {
109 return reflectSetIPData<dim>(
110 name, values, ip_data_vector, accessor_field_from_ip_data,
111 detail::reflect(std::type_identity<Member>{}));
112 }
113 else
114 {
115 static_assert(detail::is_raw_data_v<Member>,
116 "The current member is not reflectable, so we "
117 "expect it to be raw data.");
118
119 if (refl_data.name != name)
120 {
121 return false;
122 }
123
124 setIPData<dim>(values, ip_data_vector, accessor_field_from_ip_data);
125
126 return true;
127 }
128}
129
130template <int dim, typename IPData, typename Accessor_CurrentLevelFromIPData,
131 typename... Classes, typename... Accessors, std::size_t... Idcs>
133 std::string_view const name, double const* values,
134 std::vector<IPData>& ip_data_vector,
135 Accessor_CurrentLevelFromIPData const& accessor,
136 std::tuple<ReflectionData<Classes, Accessors>...> const& refl_data,
137 std::index_sequence<Idcs...>)
138{
139 // uses short-circuit evaluation of the fold || ... to stop after the first
140 // match
141 return ((setIPDataIfNameMatches<dim>(name, values, ip_data_vector, accessor,
142 std::get<Idcs>(refl_data))) ||
143 ...);
144}
145
146template <int dim, typename IPData, typename Accessor_CurrentLevelFromIPData,
147 typename... Classes, typename... Accessors>
149 std::string_view const name, double const* values,
150 std::vector<IPData>& ip_data_vector,
151 Accessor_CurrentLevelFromIPData const& accessor,
152 std::tuple<ReflectionData<Classes, Accessors>...> const& refl_data)
153{
154 return reflectSetIPData<dim>(
155 name, values, ip_data_vector, accessor, refl_data,
156 std::make_index_sequence<sizeof...(Classes)>{});
157}
158} // namespace detail
159
169template <int dim, typename IPData>
170std::size_t reflectSetIPData(std::string_view const name, double const* values,
171 std::vector<IPData>& ip_data_vector)
172{
173 detail::reflectSetIPData<dim>(
174 name, values, ip_data_vector, std::identity{},
175 detail::reflect(std::type_identity<IPData>{}));
176
177 return ip_data_vector.size();
178}
179
180} // namespace ProcessLib::Reflection
constexpr int kelvin_vector_dimensions(int const displacement_dim)
Kelvin vector dimensions for given displacement dimension.
Eigen::Matrix< double, Eigen::MatrixBase< Derived >::RowsAtCompileTime, 1 > symmetricTensorToKelvinVector(Eigen::MatrixBase< Derived > const &v)
bool setIPDataIfNameMatches(std::string_view const name, double const *values, std::vector< IPData > &ip_data_vector, Accessor_CurrentLevelFromIPData const &accessor, ReflectionData< Class, Accessor > const &refl_data)
bool reflectSetIPData(std::string_view const name, double const *values, std::vector< IPData > &ip_data_vector, Accessor_CurrentLevelFromIPData const &accessor, std::tuple< ReflectionData< Classes, Accessors >... > const &refl_data, std::index_sequence< Idcs... >)
void setIPData(double const *values, std::vector< IPData > &ip_data_vector, Accessor const &accessor)
auto reflect(std::type_identity< std::tuple< Ts... > >)
std::size_t reflectSetIPData(std::string_view const name, double const *values, std::vector< IPData > &ip_data_vector)