Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_RungeKutta.H
Go to the documentation of this file.
1#ifndef AMREX_RUNGE_KUTTA_H_
2#define AMREX_RUNGE_KUTTA_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_FabArray.H>
6
50
52 template <typename MF>
53 std::enable_if_t<IsFabArray<MF>::value> operator() (int, MF&) const {}
54};
55
57namespace detail {
59template <typename MF>
60void rk_update (MF& Unew, MF const& Uold, MF const& dUdt, Real dt)
61{
62 auto const& snew = Unew.arrays();
63 auto const& sold = Uold.const_arrays();
64 auto const& sdot = dUdt.const_arrays();
65 amrex::ParallelFor(Unew, IntVect(0), Unew.nComp(), [=] AMREX_GPU_DEVICE
66 (int bi, int i, int j, int k, int n) noexcept
67 {
68 snew[bi](i,j,k,n) = sold[bi](i,j,k,n) + dt*sdot[bi](i,j,k,n);
69 });
70 if (!Gpu::inNoSyncRegion()) {
71 Gpu::streamSynchronize();
72 }
73}
74
76template <typename MF>
77void rk_update (MF& Unew, MF const& Uold, MF const& dUdt1, MF const& dUdt2, Real dt)
78{
79 auto const& snew = Unew.arrays();
80 auto const& sold = Uold.const_arrays();
81 auto const& sdot1 = dUdt1.const_arrays();
82 auto const& sdot2 = dUdt2.const_arrays();
83 amrex::ParallelFor(Unew, IntVect(0), Unew.nComp(), [=] AMREX_GPU_DEVICE
84 (int bi, int i, int j, int k, int n) noexcept
85 {
86 snew[bi](i,j,k,n) = sold[bi](i,j,k,n) + dt*(sdot1[bi](i,j,k,n) +
87 sdot2[bi](i,j,k,n));
88 });
89 if (!Gpu::inNoSyncRegion()) {
90 Gpu::streamSynchronize();
91 }
92}
93
95template <typename MF>
96void rk2_update_2 (MF& Unew, MF const& Uold, MF const& dUdt, Real dt)
97{
98 auto const& snew = Unew.arrays();
99 auto const& sold = Uold.const_arrays();
100 auto const& sdot = dUdt.const_arrays();
101 amrex::ParallelFor(Unew, IntVect(0), Unew.nComp(), [=] AMREX_GPU_DEVICE
102 (int bi, int i, int j, int k, int n) noexcept
103 {
104 snew[bi](i,j,k,n) = Real(0.5)*(snew[bi](i,j,k,n) +
105 sold[bi](i,j,k,n) +
106 sdot[bi](i,j,k,n) * dt);
107 });
108 if (!Gpu::inNoSyncRegion()) {
109 Gpu::streamSynchronize();
110 }
111}
112
114template <typename MF>
115void rk3_update_3 (MF& Unew, MF const& Uold, Array<MF,3> const& rkk, Real dt6)
116{
117 auto const& snew = Unew.arrays();
118 auto const& sold = Uold.const_arrays();
119 auto const& k1 = rkk[0].const_arrays();
120 auto const& k2 = rkk[1].const_arrays();
121 auto const& k3 = rkk[2].const_arrays();
122 amrex::ParallelFor(Unew, IntVect(0), Unew.nComp(), [=] AMREX_GPU_DEVICE
123 (int bi, int i, int j, int k, int n) noexcept
124 {
125 snew[bi](i,j,k,n) = sold[bi](i,j,k,n)
126 + dt6 * (k1[bi](i,j,k,n) + k2[bi](i,j,k,n)
127 + Real(4.) * k3[bi](i,j,k,n));
128 });
129 if (!Gpu::inNoSyncRegion()) {
130 Gpu::streamSynchronize();
131 }
132}
133
135template <typename MF>
136void rk4_update_4 (MF& Unew, MF const& Uold, Array<MF,4> const& rkk, Real dt6)
137{
138 auto const& snew = Unew.arrays();
139 auto const& sold = Uold.const_arrays();
140 auto const& k1 = rkk[0].const_arrays();
141 auto const& k2 = rkk[1].const_arrays();
142 auto const& k3 = rkk[2].const_arrays();
143 auto const& k4 = rkk[3].const_arrays();
144 amrex::ParallelFor(Unew, IntVect(0), Unew.nComp(), [=] AMREX_GPU_DEVICE
145 (int bi, int i, int j, int k, int n) noexcept
146 {
147 snew[bi](i,j,k,n) = sold[bi](i,j,k,n)
148 + dt6 * ( k1[bi](i,j,k,n) + k4[bi](i,j,k,n)
149 + Real(2.)*(k2[bi](i,j,k,n) + k3[bi](i,j,k,n)));
150 });
151 if (!Gpu::inNoSyncRegion()) {
152 Gpu::streamSynchronize();
153 }
154}
155}
157
169template <typename MF, typename F, typename FB, typename P = PostStageNoOp>
170void RK2 (MF& Uold, MF& Unew, Real time, Real dt, F const& frhs, FB const& fillbndry,
171 P const& post_stage = PostStageNoOp())
172{
173 BL_PROFILE("RungeKutta2");
174
175 MF dUdt(Unew.boxArray(), Unew.DistributionMap(), Unew.nComp(), 0,
176 MFInfo().SetArena(The_Async_Arena()), Unew.Factory());
177
178 // RK2 stage 1
179 fillbndry(1, Uold, time);
180 frhs(1, dUdt, Uold, time, Real(0.5)*dt);
181 // Unew = Uold + dt * dUdt
182 detail::rk_update(Unew, Uold, dUdt, dt);
183 post_stage(1, Unew);
184
185 // RK2 stage 2
186 fillbndry(2, Unew, time+dt);
187 frhs(2, dUdt, Unew, time, Real(0.5)*dt);
188 // Unew = (Uold+Unew)/2 + dUdt_2 * dt/2,
189 // which is Unew = Uold + dt/2 * (dUdt_1 + dUdt_2)
190 detail::rk2_update_2(Unew, Uold, dUdt, dt);
191 post_stage(2, Unew);
192}
193
206template <typename MF, typename F, typename FB, typename R,
207 typename P = PostStageNoOp>
208void RK3 (MF& Uold, MF& Unew, Real time, Real dt, F const& frhs, FB const& fillbndry,
209 R const& store_crse_data, P const& post_stage = PostStageNoOp())
210{
211 BL_PROFILE("RungeKutta3");
212
213 Array<MF,3> rkk;
214 for (auto& mf : rkk) {
215 mf.define(Unew.boxArray(), Unew.DistributionMap(), Unew.nComp(), 0,
216 MFInfo().SetArena(The_Async_Arena()), Unew.Factory());
217 }
218
219 // RK3 stage 1
220 fillbndry(1, Uold, time);
221 frhs(1, rkk[0], Uold, time, dt/Real(6.));
222 // Unew = Uold + k1 * dt
223 detail::rk_update(Unew, Uold, rkk[0], dt);
224 post_stage(1, Unew);
225
226 // RK3 stage 2
227 fillbndry(2, Unew, time+dt);
228 frhs(2, rkk[1], Unew, time+dt, dt/Real(6.));
229 // Unew = Uold + (k1+k2) * dt/4
230 detail::rk_update(Unew, Uold, rkk[0], rkk[1], Real(0.25)*dt);
231 post_stage(2, Unew);
232
233 // RK3 stage 3
234 Real t_half = time + Real(0.5)*dt;
235 fillbndry(3, Unew, t_half);
236 frhs(3, rkk[2], Unew, t_half, dt*Real(2./3.));
237 // Unew = Uold + (k1/6 + k2/6 + k3*(2/3)) * dt
238 detail::rk3_update_3(Unew, Uold, rkk, Real(1./6.)*dt);
239 post_stage(3, Unew);
240
241 store_crse_data(rkk);
242}
243
256template <typename MF, typename F, typename FB, typename R,
257 typename P = PostStageNoOp>
258void RK4 (MF& Uold, MF& Unew, Real time, Real dt, F const& frhs, FB const& fillbndry,
259 R const& store_crse_data, P const& post_stage = PostStageNoOp())
260{
261 BL_PROFILE("RungeKutta4");
262
263 Array<MF,4> rkk;
264 for (auto& mf : rkk) {
265 mf.define(Unew.boxArray(), Unew.DistributionMap(), Unew.nComp(), 0,
266 MFInfo().SetArena(The_Async_Arena()), Unew.Factory());
267 }
268
269 // RK4 stage 1
270 fillbndry(1, Uold, time);
271 frhs(1, rkk[0], Uold, time, dt/Real(6.));
272 // Unew = Uold + k1 * dt/2
273 detail::rk_update(Unew, Uold, rkk[0], Real(0.5)*dt);
274 post_stage(1, Unew);
275
276 // RK4 stage 2
277 Real t_half = time + Real(0.5)*dt;
278 fillbndry(2, Unew, t_half);
279 frhs(2, rkk[1], Unew, t_half, dt/Real(3.));
280 // Unew = Uold + k2 * dt/2
281 detail::rk_update(Unew, Uold, rkk[1], Real(0.5)*dt);
282 post_stage(2, Unew);
283
284 // RK4 stage 3
285 fillbndry(3, Unew, t_half);
286 frhs(3, rkk[2], Unew, t_half, dt/Real(3.));
287 // Unew = Uold + k3 * dt;
288 detail::rk_update(Unew, Uold, rkk[2], dt);
289 post_stage(3, Unew);
290
291 // RK4 stage 4
292 fillbndry(4, Unew, time+dt);
293 frhs(4, rkk[3], Unew, time+dt, dt/Real(6.));
294 // Unew = Uold + (k1/6 + k2/3 + k3/3 + k4/6) * dt
295 detail::rk4_update_4(Unew, Uold, rkk, Real(1./6.)*dt);
296 post_stage(4, Unew);
297
298 store_crse_data(rkk);
299}
300
301}
302
303#endif
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:79
std::array< T, N > Array
Definition AMReX_Array.H:26
Arena * The_Async_Arena()
Definition AMReX_Arena.cpp:815
Functions for Runge-Kutta methods.
Definition AMReX_RungeKutta.H:49
void RK2(MF &Uold, MF &Unew, Real time, Real dt, F const &frhs, FB const &fillbndry, P const &post_stage=PostStageNoOp())
Time stepping with RK2.
Definition AMReX_RungeKutta.H:170
void RK3(MF &Uold, MF &Unew, Real time, Real dt, F const &frhs, FB const &fillbndry, R const &store_crse_data, P const &post_stage=PostStageNoOp())
Time stepping with RK3.
Definition AMReX_RungeKutta.H:208
std::enable_if_t< std::is_integral_v< T > > ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:193
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:33
FabArray memory allocation information.
Definition AMReX_FabArray.H:66
MFInfo & SetArena(Arena *ar) noexcept
Definition AMReX_FabArray.H:77
Definition AMReX_RungeKutta.H:51
std::enable_if_t< IsFabArray< MF >::value > operator()(int, MF &) const
Definition AMReX_RungeKutta.H:53