-
Notifications
You must be signed in to change notification settings - Fork 5
/
microphysicalprocess.hpp
268 lines (246 loc) · 9.73 KB
/
microphysicalprocess.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/*
* Copyright (c) 2024 MPI-M, Clara Bayley
*
* ----- CLEO -----
* File: microphysicalprocess.hpp
* Project: superdrops
* Created Date: Friday 13th October 2023
* Author: Clara Bayley (CB)
* Additional Contributors: Tobias Kölling (TK)
* -----
* Last Modified: Saturday 25th May 2024
* Modified By: CB
* -----
* License: BSD 3-Clause "New" or "Revised" License
* https://opensource.org/licenses/BSD-3-Clause
* -----
* File Description:
* Concept of a Microphysical Process as well as helpers structs and functions for creating
* structs that obeys the concept to model microphysics in SDM (eg. condensation or
* collision-coalescence using the ConstTstepMicrophysics struct).
*/
#ifndef LIBS_SUPERDROPS_MICROPHYSICALPROCESS_HPP_
#define LIBS_SUPERDROPS_MICROPHYSICALPROCESS_HPP_
#include <Kokkos_Core.hpp>
#include <Kokkos_Random.hpp>
#include <concepts>
#include "../cleoconstants.hpp"
#include "./kokkosaliases_sd.hpp"
#include "./sdmmonitor.hpp"
#include "./state.hpp"
#include "./superdrop.hpp"
/**
* @brief Concept of a microphysical process.
*
* The MicrophysicalProcess concept represents all types that meet the requirements (constraints)
* of two time-stepping functions ("next_step" and "on_step"), as well as the constraints on the
* "run_step" function.
*
* Note: NullSDMMonitor used here as placeholder for templated run_step function that can take any
* type satisfying the SDMMonitor concept.
*
* @tparam P The type that satisfies the MicrophysicalProcess concept.
*/
template <typename P>
concept MicrophysicalProcess =
requires(P p, const TeamMember &tm, const unsigned int t, subviewd_supers supers, State &state,
const NullSDMMonitor mo) {
{ p.next_step(t) } -> std::convertible_to<unsigned int>;
{ p.on_step(t) } -> std::same_as<bool>;
{ p.run_step(tm, t, supers, state, mo) } -> std::convertible_to<subviewd_supers>;
};
/**
* @brief Combined microphysical process struct.
*
* The CombinedMicrophysicalProcess struct combines two microphysical processes into one.
* It implements the MicrophysicalProcess concept by delegating calls to the individual processes.
* Structure enacts associative addition operation that defines the set for the
* microphysical process Monoid.
*
* @tparam Microphys1 The type of the first microphysical process.
* @tparam Microphys2 The type of the second microphysical process.
*/
template <MicrophysicalProcess Microphys1, MicrophysicalProcess Microphys2>
struct CombinedMicrophysicalProcess {
private:
Microphys1 a; /**< The first instance of type of MicrophysicalProcess. */
Microphys2 b; /**< The second instance of type of MicrophysicalProcess. */
public:
/**
* @brief Constructs a CombinedMicrophysicalProcess object.
*
* @param a The first microphysical process.
* @param b The second microphysical process.
*/
CombinedMicrophysicalProcess(const Microphys1 a, const Microphys2 b) : a(a), b(b) {}
/**
* @brief Returns the next time step for the combined microphysical process.
*
* @param subt The current time step.
* @return The smaller of the next time steps from the two individual processes.
*/
KOKKOS_INLINE_FUNCTION
unsigned int next_step(const unsigned int subt) const {
const auto t_a = a.next_step(subt);
const auto t_b = b.next_step(subt);
return !(t_a < t_b) ? t_b : t_a; // smaller of two unsigned ints (see std::min)
}
/**
* @brief Checks if the combined microphysical process should perform an on-step action.
*
* @param subt The current time step.
* @return True if either individual process indicates an on-step action.
*/
KOKKOS_INLINE_FUNCTION
bool on_step(const unsigned int subt) const { return a.on_step(subt) || b.on_step(subt); }
/**
* @brief Runs the combined microphysical process.
*
* @param team_member The Kokkos team member executing the process.
* @param subt The current time step.
* @param supers The view of super-droplets.
* @param state The state of the system / volume.
* @param mo Monitor of SDM processes.
* @return The updated view of super-droplets after the process.
*/
KOKKOS_INLINE_FUNCTION subviewd_supers run_step(const TeamMember &team_member,
const unsigned int subt, subviewd_supers supers,
State &state, const SDMMonitor auto mo) const {
supers = a.run_step(team_member, subt, supers, state, mo);
supers = b.run_step(team_member, subt, supers, state, mo);
return supers;
}
};
/**
* @brief Operator for combining two microphysical processes.
*
* This operator combines two microphysical processes into one using the
* CombinedMicrophysicalProcess struct.
*
* @param a The first microphysical process.
* @param b The second microphysical process.
* @return The combined microphysical process.
*/
auto operator>>(const MicrophysicalProcess auto a, const MicrophysicalProcess auto b) {
return CombinedMicrophysicalProcess(a, b);
}
/**
* @brief Null microphysical process struct.
*
* The NullMicrophysicalProcess struct represents a microphysical process that does nothing.
* It is defined to satisfy null member of the Monoid set.
*/
struct NullMicrophysicalProcess {
/**
* @brief Returns the next time step for the null microphysical process.
*
* @param subt The current time step.
* @return The maximum unsigned integer value, indicating no further time step will require
* action of null microphyisical process.
*/
KOKKOS_INLINE_FUNCTION
unsigned int next_step(const unsigned int subt) const { return LIMITVALUES::uintmax; }
/**
* @brief Checks if the null microphysical process should perform an on-step action.
*
* @param subt The current time step.
* @return Always returns false, indicating no action is ever performed.
*/
KOKKOS_INLINE_FUNCTION
bool on_step(const unsigned int subt) const { return false; }
/**
* @brief Runs the null microphysical process.
*
* Is null, i.e. does nothing and returns unchanged super-droplet view.
*
* @param team_member The team member executing the process.
* @param subt The current time step.
* @param supers The view of super-droplets.
* @param state The state of the system.
* @param mo Monitor of SDM processes.
* @return The unchanged view of super-droplets.
*/
KOKKOS_INLINE_FUNCTION subviewd_supers run_step(const TeamMember &team_member,
const unsigned int subt, subviewd_supers supers,
State &state, const SDMMonitor auto mo) const {
return supers;
}
};
/**
* @brief Concept for a microphysics function.
*
* The MicrophysicsFunc concept represents all function-like types that can be called by the
* "run_step" function in ConstTstepMicrophysics.
*
* Note: NullSDMMonitor used here as placeholder for templated run_step function that can take any
* type satisfying the SDMMonitor concept.
*
* @tparam F The type that satisfies the MicrophysicsFunc concept.
*/
template <typename F>
concept MicrophysicsFunc = requires(F f, const TeamMember &tm, const unsigned int subt,
subviewd_supers supers, State &state, const NullSDMMonitor mo) {
{ f(tm, subt, supers, state, mo) } -> std::convertible_to<subviewd_supers>;
};
/**
* @brief Struct representing microphysics with constant time step.
*
* The ConstTstepMicrophysics struct is a type that satisfies the concept of microphysical process
* and has a constant time step interval. It can be used to create microphysical processes with
* constant time steps between action of microphysics determined by the MicrophysicsFunc type 'F'.
*
* @tparam F The type of the microphysics function.
*/
template <MicrophysicsFunc F>
struct ConstTstepMicrophysics {
private:
unsigned int interval; /**< The constant time step between calls to microphysics. */
F do_microphysics; /**< Function-like microphysics is type of MicrophysicsFunc*/
public:
/**
* @brief Constructs a ConstTstepMicrophysics object.
*
* @param interval The constant time step between calls to microphysics.
* @param f The microphysics function.
*/
ConstTstepMicrophysics(const unsigned int interval, const F f)
: interval(interval), do_microphysics(f) {}
/**
* @brief Returns the next time when the microphysics should be called given its constant
* interval.
*
* @param subt The current time step.
* @return The next time step based on the interval.
*/
KOKKOS_INLINE_FUNCTION
unsigned int next_step(const unsigned int subt) const {
return ((subt / interval) + 1) * interval;
}
/**
* @brief Checks if the constant time step microphysics should perform an on-step action.
*
* @param subt The current time step.
* @return True if the current time step is a multiple of the interval.
*/
KOKKOS_INLINE_FUNCTION
bool on_step(const unsigned int subt) const { return subt % interval == 0; }
/**
* @brief Runs microphysics with the constant time step.
*
* @param team_member The team member executing the process.
* @param subt The current time step.
* @param supers The view of super-droplets.
* @param state The state of the system / volume.
* @param mo Monitor of SDM processes.
* @return The updated view of super-droplets after the process.
*/
KOKKOS_INLINE_FUNCTION subviewd_supers run_step(const TeamMember &team_member,
const unsigned int subt, subviewd_supers supers,
State &state, const SDMMonitor auto mo) const {
if (on_step(subt)) {
supers = do_microphysics(team_member, subt, supers, state, mo);
}
return supers;
}
};
#endif // LIBS_SUPERDROPS_MICROPHYSICALPROCESS_HPP_