hyper.deal
Loading...
Searching...
No Matches
time_integrators.templates.h
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2020 by the hyper.deal authors
4//
5// This file is part of the hyper.deal library.
6//
7// The hyper.deal library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 3.0 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.MD at
12// the top level directory of hyper.deal.
13//
14// ---------------------------------------------------------------------
15
16#include <deal.II/base/exceptions.h>
17
18#include <hyper.deal/base/time_integrators.h>
19
20namespace hyperdeal
21{
22 template <typename Number, typename VectorType>
24 LowStorageRungeKuttaIntegrator(VectorType & vec_Ki,
25 VectorType & vec_Ti,
26 const std::string type,
27 const bool only_Ti_is_ghosted)
28 : vec_Ki(vec_Ki)
29 , vec_Ti(vec_Ti)
30 , only_Ti_is_ghosted(only_Ti_is_ghosted)
31 {
32 // Runge-Kutta coefficients
33 // see: Kennedy, Carpenter, Lewis, 2000
34 if (type == "rk33")
35 {
36 bi = {{0.245170287303492, 0.184896052186740, 0.569933660509768}};
37 ai = {{0.755726351946097, 0.386954477304099}};
38 }
39 else if (type == "rk45")
40 {
41 bi = {{1153189308089. / 22510343858157.,
42 1772645290293. / 4653164025191.,
43 -1672844663538. / 4480602732383.,
44 2114624349019. / 3568978502595.,
45 5198255086312. / 14908931495163.}};
46 ai = {{970286171893. / 4311952581923.,
47 6584761158862. / 12103376702013.,
48 2251764453980. / 15575788980749.,
49 26877169314380. / 34165994151039.}};
50 }
51 else if (type == "rk47")
52 {
53 bi = {{0.0941840925477795334,
54 0.149683694803496998,
55 0.285204742060440058,
56 -0.122201846148053668,
57 0.0605151571191401122,
58 0.345986987898399296,
59 0.186627171718797670}};
60 ai = {{0.241566650129646868 + bi[0],
61 0.0423866513027719953 + bi[1],
62 0.215602732678803776 + bi[2],
63 0.232328007537583987 + bi[3],
64 0.256223412574146438 + bi[4],
65 0.0978694102142697230 + bi[5]}};
66 }
67 else if (type == "rk59")
68 {
69 bi = {{2274579626619. / 23610510767302.,
70 693987741272. / 12394497460941.,
71 -347131529483. / 15096185902911.,
72 1144057200723. / 32081666971178.,
73 1562491064753. / 11797114684756.,
74 13113619727965. / 44346030145118.,
75 393957816125. / 7825732611452.,
76 720647959663. / 6565743875477.,
77 3559252274877. / 14424734981077.}};
78 ai = {{1107026461565. / 5417078080134.,
79 38141181049399. / 41724347789894.,
80 493273079041. / 11940823631197.,
81 1851571280403. / 6147804934346.,
82 11782306865191. / 62590030070788.,
83 9452544825720. / 13648368537481.,
84 4435885630781. / 26285702406235.,
85 2357909744247. / 11371140753790.}};
86 }
87 else
88 AssertThrow(false, dealii::StandardExceptions::ExcNotImplemented());
89 }
90
91 template <typename Number, typename VectorType>
92 void
94 VectorType & solution,
95 const Number &current_time,
96 const Number &time_step,
97 const std::function<void(const VectorType &, VectorType &, const Number)>
98 &op)
99 {
100 const auto &local_elements = solution.locally_owned_elements();
101
102 // definition of a stage
103 auto perform_stage = [&](const Number current_time,
104 const Number factor_solution,
105 const Number factor_ai,
106 const VectorType &current_Ti,
107 VectorType & vec_Ki,
108 VectorType & solution,
109 VectorType & next_Ti) {
110 // call operator
111 op(current_Ti, vec_Ki, current_time);
112
113 const Number ai = factor_ai;
114 const Number bi = factor_solution;
115 if (ai == Number())
116 {
117 for (const auto i : local_elements)
118 {
119 const Number K_i = vec_Ki(i);
120 const Number sol_i = solution(i);
121 solution(i) = sol_i + bi * K_i;
122 }
123 }
124 else
125 {
126 for (const auto i : local_elements)
127 {
128 const Number K_i = vec_Ki(i);
129 const Number sol_i = solution(i);
130 solution(i) = sol_i + bi * K_i;
131 next_Ti(i) = sol_i + ai * K_i;
132 }
133 if constexpr (manual_compress)
134 next_Ti.compress(dealii::VectorOperation::insert);
135 }
136 if constexpr (manual_compress)
137 solution.compress(dealii::VectorOperation::insert);
138 };
139
140
141 // perform first stage
142 if (only_Ti_is_ghosted)
143 {
144 // swap solution and Ti
145 for (const auto i : local_elements)
146 vec_Ti(i) = solution(i);
147 if constexpr (manual_compress)
148 vec_Ti.compress(dealii::VectorOperation::insert);
149
150 perform_stage(current_time,
151 bi[0] * time_step,
152 ai[0] * time_step,
153 vec_Ti,
154 vec_Ki,
155 solution,
156 vec_Ti);
157 }
158 else
159 {
160 perform_stage(current_time,
161 bi[0] * time_step,
162 ai[0] * time_step,
163 solution,
164 vec_Ti,
165 solution,
166 vec_Ti);
167 }
168
169
170 // perform rest stages
171 Number sum_previous_bi = 0;
172 for (unsigned int stage = 1; stage < bi.size(); ++stage)
173 {
174 const Number c_i = sum_previous_bi + ai[stage - 1];
175 perform_stage(current_time + c_i * time_step,
176 bi[stage] * time_step,
177 (stage == bi.size() - 1 ? 0 : ai[stage] * time_step),
178 vec_Ti,
179 vec_Ki,
180 solution,
181 vec_Ti);
182 sum_previous_bi += bi[stage - 1];
183 }
184 }
185
186 template <typename Number, typename VectorType>
187 unsigned int
189 {
190 return bi.size();
191 }
192
193} // namespace hyperdeal
Definition time_integrators.h:49
void perform_time_step(VectorType &solution, const Number &current_time, const Number &time_step, const std::function< void(const VectorType &, VectorType &, const Number)> &op)
Definition time_integrators.templates.h:93
LowStorageRungeKuttaIntegrator(VectorType &vec_Ki, VectorType &vec_Ti, const std::string type, const bool only_Ti_is_ghosted=true)
Definition time_integrators.templates.h:24