OGS
TangentOperatorBlocksView.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 <MGIS/Behaviour/Variable.hxx>
7#include <boost/mp11.hpp>
8#include <range/v3/view/enumerate.hpp>
9#include <range/v3/view/filter.hpp>
10#include <range/v3/view/map.hpp>
11#include <range/v3/view/zip.hpp>
12
13#include "BaseLib/cpp23.h"
16
18{
19namespace detail
20{
24static constexpr std::array<double, 3 * 3 * 3 * 3>
26} // namespace detail
27
30{
31 std::vector<double> data;
32};
33
56template <typename Gradients, typename TDynForces, typename ExtStateVars>
58{
59 static_assert(boost::mp11::mp_is_set<Gradients>::value);
60 static_assert(boost::mp11::mp_is_set<TDynForces>::value);
61 static_assert(boost::mp11::mp_is_set<ExtStateVars>::value);
62
64 boost::mp11::mp_append<Gradients, ExtStateVars>;
65
66 static_assert(boost::mp11::mp_is_set<GradientsAndExtStateVars>::value);
67
68 using type = boost::mp11::
69 mp_product<boost::mp11::mp_list, TDynForces, GradientsAndExtStateVars>;
70};
71
85template <int DisplacementDim, typename ForcesGradsCombinations>
87{
88 static_assert(boost::mp11::mp_is_set<ForcesGradsCombinations>::value);
89
92 static constexpr std::size_t invalid_offset_ = -1;
93
94public:
98 std::vector<std::pair<mgis::behaviour::Variable,
99 mgis::behaviour::Variable>> const& to_blocks)
100 {
102
103 std::vector<bool> used_blocks(
104 to_blocks.size(), false); // checked after creation of all offsets.
105
106 boost::mp11::mp_for_each<ForcesGradsCombinations>(
107 [&to_blocks,
108 &used_blocks,
109 this]<typename Force, typename GradOrExtStateVar>(
110 boost::mp11::mp_list<Force, GradOrExtStateVar>)
111 {
112 std::size_t data_offset = 0;
113 for (auto [block, is_used] :
114 ranges::views::zip(to_blocks, used_blocks))
115 {
116 auto const& [force, grad] = block;
117 if (force.name == Force::name &&
118 grad.name == GradOrExtStateVar::name)
119 {
120 auto constexpr block_idx =
122 offsets_[block_idx] = data_offset;
123 is_used = true;
124 return;
125 }
126
127 data_offset += size(force.type) * size(grad.type);
128 }
129 });
130
131 // Indices of unused blocks.
132 auto indices = ranges::views::enumerate(used_blocks) |
133 ranges::views::filter([](auto const& pair)
134 { return !pair.second; }) |
135 ranges::views::keys;
136
137 if (!indices.empty())
138 {
139 ERR("There are unused tangent operator blocks provided by MFront. "
140 "Following blocks are unused:");
141
142 for (auto const i : indices)
143 {
144 auto const& [force, grad] = to_blocks[i];
145 ERR("\t{}/{}", force.name, grad.name);
146 }
147 OGS_FATAL("All tangent operator blocks must be used.");
148 }
149 }
150
157 template <typename Force, typename GradOrExtStateVar>
158 auto block(Force,
159 GradOrExtStateVar,
160 OGSMFrontTangentOperatorData const& data) const
161 {
162 static_assert(
163 boost::mp11::mp_contains<
165 boost::mp11::mp_list<Force, GradOrExtStateVar>>::value,
166 "Requested tangent block was not created in the "
167 "OGSMFrontTangentOperatorBlocksView.");
168
169 constexpr auto index = blockIndex<Force, GradOrExtStateVar>();
170 const auto offset = offsets_[index];
171
172 constexpr auto force_size = Force::template size<DisplacementDim>();
173 constexpr auto grad_size =
174 GradOrExtStateVar::template size<DisplacementDim>();
175
176 if constexpr (grad_size == 1 && force_size == 1)
177 {
178 if (offset == invalid_offset_)
179 {
180 return 0.0;
181 }
182
183 return data.data[offset];
184 }
185 else
186 {
187 constexpr auto order =
188 grad_size == 1 ? Eigen::ColMajor : Eigen::RowMajor;
189
190 using Result = Eigen::Map<
191 const Eigen::Matrix<double, force_size, grad_size, order>>;
192
193 if (offset == invalid_offset_)
194 {
195 return Result{
197 }
198
199 return Result{data.data.data() + offset};
200 }
201 }
202
203private:
204 static constexpr std::size_t size(mgis::behaviour::Variable::Type vt)
205 {
206 using VT = mgis::behaviour::Variable::Type;
207
208 switch (vt)
209 {
210 case VT::SCALAR:
211 return 1;
212 case VT::STENSOR:
214 DisplacementDim);
215 case VT::VECTOR:
216 return DisplacementDim;
217 case VT::TENSOR:
218 return MaterialPropertyLib::tensorSize(DisplacementDim);
219 case VT::VECTOR_1D:
220 case VT::VECTOR_2D:
221 case VT::VECTOR_3D:
222 case VT::STENSOR_1D:
223 case VT::STENSOR_2D:
224 case VT::STENSOR_3D:
225 case VT::TENSOR_1D:
226 case VT::TENSOR_2D:
227 case VT::TENSOR_3D:
228 case VT::HIGHER_ORDER_TENSOR:
229 case VT::ARRAY:
230 break; // Unsupported variable types
231 }
232
233 OGS_FATAL("Unsupported MGIS variable type {}.",
235 }
236
238 template <typename Force, typename GradOrExtStateVar>
239 static constexpr std::size_t blockIndex()
240 {
241 return boost::mp11::mp_find<
243 boost::mp11::mp_list<Force, GradOrExtStateVar>>::value;
244 }
245
250 std::array<std::size_t,
251 boost::mp11::mp_size<ForcesGradsCombinations>::value>
253};
254} // namespace MaterialLib::Solids::MFront
#define OGS_FATAL(...)
Definition Error.h:19
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
OGSMFrontTangentOperatorBlocksView(std::vector< std::pair< mgis::behaviour::Variable, mgis::behaviour::Variable > > const &to_blocks)
static constexpr std::size_t size(mgis::behaviour::Variable::Type vt)
static constexpr std::size_t blockIndex()
Computes the index of a tangent operator block in the offsets_ array.
std::array< std::size_t, boost::mp11::mp_size< ForcesGradsCombinations >::value > offsets_
auto block(Force, GradOrExtStateVar, OGSMFrontTangentOperatorData const &data) const
constexpr auto to_underlying(E e) noexcept
Converts an enumeration to its underlying type.
Definition cpp23.h:22
static constexpr std::array< double, 3 *3 *3 *3 > OGSMFrontTangentOperatorBlocksViewZeroes
constexpr int tensorSize(int dim)
See Tensor type for details.
Definition Tensor.h:13
constexpr int kelvin_vector_dimensions(int const displacement_dim)
Kelvin vector dimensions for given displacement dimension.
boost::mp11:: mp_product< boost::mp11::mp_list, TDynForces, GradientsAndExtStateVars > type
boost::mp11::mp_append< Gradients, ExtStateVars > GradientsAndExtStateVars
Used for disambiguation with MFront's thermodynamic forces data.