ryujin 2.5.0 revision c64172211cf21344cb9b9b0f3a1266aa6400d392
Loading...
Searching...
No Matches
state_vector.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// Copyright (C) 2024 - 2026 by the ryujin authors
4//
5
6#pragma once
7
8#include <ryujin/base/compile_time_options.h>
11
12#include <algorithm>
13#include <concepts>
14#include <limits>
15#include <vector>
16
17namespace ryujin
18{
19#ifndef DOXYGEN
20 /* Forward declaration */
21 template <int dim, typename Number>
22 class OfflineData;
23#endif
24
32 template <typename Number>
33 using ScalarHostVector = dealii::LinearAlgebra::distributed::Vector<Number>;
34
35
42 template <typename Number>
44
45
61 template <typename Number>
62 struct StateVector {
65 std::vector<ScalarVector<Number>> dynamic_state;
66 std::vector<ScalarVector<Number>> dynamic_precomputed;
67 };
68
69
82
83
90 template <typename MemorySpace,
91 typename Number,
92 std::same_as<StateVectorPart>... Parts>
94 [[maybe_unused]],
95 Parts... parts [[maybe_unused]])
96 {
97 static_assert(sizeof...(Parts) > 0, "No state vector part selected");
98
99 if constexpr (have_separate_memory_spaces) {
100 ComputingTimer::Scope scope("time step [X] _ - memory space transfers");
101
102 const auto &[U, Q, U_dynamic, Q_dynamic] = state_vector;
103
104 const auto copy = [&](const StateVectorPart part) {
105 switch (part) {
107 U.template copy_to_memory_space<MemorySpace>();
108 break;
110 Q.template copy_to_memory_space<MemorySpace>();
111 break;
113 for (const auto &U_k : U_dynamic)
114 U_k.template copy_to_memory_space<MemorySpace>();
115 break;
117 for (const auto &Q_k : Q_dynamic)
118 Q_k.template copy_to_memory_space<MemorySpace>();
119 break;
120 }
121 };
122
123 (copy(parts), ...);
124 }
125 }
126
127
135 template <typename MemorySpace, typename Number>
137 [[maybe_unused]])
138 {
139 if constexpr (have_separate_memory_spaces) {
140 ComputingTimer::Scope scope("time step [X] _ - memory space transfers");
141 vector.template copy_to_memory_space<MemorySpace>();
142 }
143 }
144
145
152 template <typename MemorySpace,
153 typename Number,
154 std::same_as<StateVectorPart>... Parts>
155 void move_to_memory_space(StateVector<Number> &state_vector [[maybe_unused]],
156 Parts... parts [[maybe_unused]])
157 {
158 static_assert(sizeof...(Parts) > 0, "No state vector part selected");
159
160 if constexpr (have_separate_memory_spaces) {
161 ComputingTimer::Scope scope("time step [X] _ - memory space transfers");
162
163 auto &[U, Q, U_dynamic, Q_dynamic] = state_vector;
164
165 const auto move = [&](const StateVectorPart part) {
166 switch (part) {
168 U.template move_to_memory_space<MemorySpace>();
169 break;
171 Q.template move_to_memory_space<MemorySpace>();
172 break;
174 for (auto &U_k : U_dynamic)
175 U_k.template move_to_memory_space<MemorySpace>();
176 break;
178 for (auto &Q_k : Q_dynamic)
179 Q_k.template move_to_memory_space<MemorySpace>();
180 break;
181 }
182 };
183
184 (move(parts), ...);
185 }
186 }
187
188
196 template <typename MemorySpace, typename Number>
198 [[maybe_unused]])
199 {
200 if constexpr (have_separate_memory_spaces) {
201 ComputingTimer::Scope scope("time step [X] _ - memory space transfers");
202 vector.template move_to_memory_space<MemorySpace>();
203 }
204 }
205
206
215 template <typename MemorySpace, typename Number>
217 const Number s,
218 const Number b,
219 const StateVector<Number> &src)
220 {
221 copy_to_memory_space<MemorySpace>(
223 move_to_memory_space<MemorySpace>(
225
226 auto &[dst_U, dst_Q, dst_U_dynamic, dst_Q_dynamic] = dst;
227 const auto &[src_U, src_Q, src_U_dynamic, src_Q_dynamic] = src;
228
229 auto &dst_U_vector = dst_U.template deal_ii_vector<MemorySpace>();
230 dst_U_vector.zero_out_ghost_values();
231 dst_U_vector.sadd(s, b, src_U.template deal_ii_vector<MemorySpace>());
232
233 AssertDimension(dst_U_dynamic.size(), src_U_dynamic.size());
234
235 for (std::size_t k = 0; k < dst_U_dynamic.size(); ++k) {
236 auto &dst_k = dst_U_dynamic[k].template deal_ii_vector<MemorySpace>();
237 const auto &src_k =
238 src_U_dynamic[k].template deal_ii_vector<MemorySpace>();
239 dst_k.zero_out_ghost_values();
240 dst_k.sadd(s, b, src_k);
241 }
242 }
243
244
255 template <typename Number, typename OfflineData>
257 [[maybe_unused]],
258 const OfflineData &offline_data
259 [[maybe_unused]])
260 {
261#ifdef DEBUG
262
263 move_to_memory_space<dealii::MemorySpace::Host>(
265
266 auto &[U, Q, U_dynamic, Q_dynamic] = state_vector;
267
268 constexpr auto nan = std::numeric_limits<Number>::signaling_NaN();
269
270 const unsigned int n_owned = offline_data.n_locally_owned();
271 const unsigned int n_relevant = offline_data.n_locally_relevant();
272 const auto &partitioner = offline_data.scalar_partitioner();
273
274 /*
275 * The number of components is a run time property: work on the
276 * underlying deal.II vectors with n_comp() as stride.
277 */
278 const unsigned int prob_dim = U.n_comp();
279 const unsigned int prec_dim = Q.n_comp();
280 Number *const U_data = U.deal_ii_vector().begin();
281 Number *const prec_data = Q.deal_ii_vector().begin();
282
283 for (unsigned int i = 0; i < n_owned; ++i) {
284 std::fill_n(prec_data + i * prec_dim, prec_dim, nan);
285
286 if (!offline_data.affine_constraints().is_constrained(
287 partitioner->local_to_global(i)))
288 continue;
289 std::fill_n(U_data + i * prob_dim, prob_dim, nan);
290 }
291
292 for (unsigned int i = n_owned; i < n_relevant; ++i) {
293 std::fill_n(prec_data + i * prec_dim, prec_dim, nan);
294
295 std::fill_n(U_data + i * prob_dim, prob_dim, nan);
296 }
297#endif
298 }
299} // namespace ryujin
constexpr bool have_separate_memory_spaces
Definition gpu.h:29
dealii::LinearAlgebra::distributed::Vector< Number > ScalarHostVector
void sadd(StateVector< Number > &dst, const Number s, const Number b, const StateVector< Number > &src)
void copy_to_memory_space(const StateVector< Number > &state_vector, Parts... parts)
void debug_poison_invalid_values(StateVector< Number > &state_vector, const OfflineData &offline_data)
void move_to_memory_space(StateVector< Number > &state_vector, Parts... parts)
std::vector< ScalarVector< Number > > dynamic_state
MultiComponentVector< Number > state
std::vector< ScalarVector< Number > > dynamic_precomputed
MultiComponentVector< Number > precomputed