Skip to content

Commit 4fe0953

Browse files
author
Matthew Emmett
committed
imex: Support virtual nodes (0 and 1).
1 parent 36182aa commit 4fe0953

File tree

1 file changed

+57
-10
lines changed

1 file changed

+57
-10
lines changed

include/pfasst/encap/imex_sweeper.hpp

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ namespace pfasst
8686
*/
8787
matrix<time> s_mat;
8888

89+
/**
90+
* quadrature matrix containing weights for 0-to-last node integration
91+
*/
92+
matrix<time> b_mat;
93+
8994
/**
9095
* quadrature matrix containing weights for node-to-node integration of explicit part
9196
*
@@ -101,6 +106,24 @@ namespace pfasst
101106
matrix<time> s_mat_impl;
102107
//! @}
103108

109+
110+
/**
111+
* Set end state to \\( U_0 + \\int F_{expl} + F_{expl} \\).
112+
*/
113+
void integrate_end_state(time dt)
114+
{
115+
vector<shared_ptr<Encapsulation<time>>> dst = { this->u_state.back() };
116+
dst[0]->copy(this->u_state.front());
117+
dst[0]->mat_apply(dst, dt, this->b_mat, this->fs_expl, false);
118+
dst[0]->mat_apply(dst, dt, this->b_mat, this->fs_impl, false);
119+
}
120+
121+
inline bool last_node_is_virtual()
122+
{
123+
return !this->get_is_proper().back();
124+
}
125+
126+
104127
public:
105128
//! @{
106129
virtual ~IMEXSweeper()
@@ -178,6 +201,12 @@ namespace pfasst
178201

179202
this->s_mat = compute_quadrature(nodes, nodes, is_proper, 's');
180203

204+
auto q_mat = compute_quadrature(nodes, nodes, is_proper, 'q');
205+
this->b_mat = matrix<time>(1, nodes.size());
206+
for (size_t m = 0; m < nodes.size(); m++) {
207+
this->b_mat(0,m) = q_mat(nodes.size()-2, m);
208+
}
209+
181210
this->s_mat_expl = this->s_mat;
182211
this->s_mat_impl = this->s_mat;
183212
for (size_t m = 0; m < nodes.size() - 1; m++) {
@@ -191,7 +220,12 @@ namespace pfasst
191220
if (coarse) {
192221
this->previous_u_state.push_back(this->get_factory()->create(pfasst::encap::solution));
193222
}
194-
this->fs_expl.push_back(this->get_factory()->create(pfasst::encap::function));
223+
// XXX: can prolly save some f's here...
224+
// if ((m == 0) || this->get_is_proper()[m]) {
225+
this->fs_expl.push_back(this->get_factory()->create(pfasst::encap::function));
226+
// } else {
227+
// this->fs_expl.push_back(nullptr);
228+
// }
195229
this->fs_impl.push_back(this->get_factory()->create(pfasst::encap::function));
196230
}
197231

@@ -212,14 +246,11 @@ namespace pfasst
212246
time dt = this->get_controller()->get_time_step();
213247
time t = this->get_controller()->get_time();
214248

215-
if (initial) {
216-
this->f_expl_eval(this->fs_expl[0], this->u_state[0], t);
217-
this->f_impl_eval(this->fs_impl[0], this->u_state[0], t);
218-
}
249+
if (initial) { this->evaluate(0); }
219250

220251
shared_ptr<Encapsulation<time>> rhs = this->get_factory()->create(pfasst::encap::solution);
221252

222-
for (size_t m = 0; m < nnodes - 1; m++) {
253+
for (size_t m = 0; m < nnodes - (this->last_node_is_virtual() ? 2 : 1); m++) {
223254
time ds = dt * (nodes[m + 1] - nodes[m]);
224255
rhs->copy(this->u_state[m]);
225256
rhs->saxpy(ds, this->fs_expl[m]);
@@ -228,6 +259,8 @@ namespace pfasst
228259

229260
t += ds;
230261
}
262+
263+
if (this->last_node_is_virtual()) { this->integrate_end_state(dt); }
231264
}
232265

233266
virtual void sweep()
@@ -251,7 +284,7 @@ namespace pfasst
251284
// sweep
252285
shared_ptr<Encapsulation<time>> rhs = this->get_factory()->create(pfasst::encap::solution);
253286

254-
for (size_t m = 0; m < nnodes - 1; m++) {
287+
for (size_t m = 0; m < nnodes - (this->last_node_is_virtual() ? 2 : 1); m++) {
255288
time ds = dt * (nodes[m + 1] - nodes[m]);
256289

257290
rhs->copy(this->u_state[m]);
@@ -262,6 +295,8 @@ namespace pfasst
262295

263296
t += ds;
264297
}
298+
299+
if (this->last_node_is_virtual()) { this->integrate_end_state(dt); }
265300
}
266301

267302
virtual void advance() override
@@ -282,11 +317,23 @@ namespace pfasst
282317
}
283318
}
284319

320+
/**
321+
* @copybrief EncapSweeper::evaluate()
322+
*
323+
* If the node `m` is virtual (not proper), we can save some
324+
* implicit/explicit evaluations.
325+
*/
285326
virtual void evaluate(size_t m) override
286327
{
287-
time t = this->get_nodes()[m]; // XXX
288-
this->f_expl_eval(this->fs_expl[m], this->u_state[m], t);
289-
this->f_impl_eval(this->fs_impl[m], this->u_state[m], t);
328+
time t0 = this->get_controller()->get_time();
329+
time dt = this->get_controller()->get_time_step();
330+
time t = t0 + dt * this->get_nodes()[m];
331+
if ((m == 0) || this->get_is_proper()[m]) {
332+
this->f_expl_eval(this->fs_expl[m], this->u_state[m], t);
333+
}
334+
if (this->get_is_proper()[m]) {
335+
this->f_impl_eval(this->fs_impl[m], this->u_state[m], t);
336+
}
290337
}
291338

292339
/**

0 commit comments

Comments
 (0)