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