Skip to content

Commit 53c60b2

Browse files
committed
state: Add simple range iterations and get_time() etc.
This couples each level to the controller, and lets the controller keep track of, eg, which step and iteration is being operated on. This allows sweepers etc to get at this data consistently, and simplifies various method signatures.
1 parent 244ec25 commit 53c60b2

File tree

6 files changed

+154
-85
lines changed

6 files changed

+154
-85
lines changed

examples/advection_diffusion/advection_diffusion_sweeper.hpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
using namespace std;
2121

2222
template<typename time = pfasst::time_precision>
23-
class AdvectionDiffusionSweeper
23+
class AdvectionDiffusionSweeper
2424
: public pfasst::encap::IMEXSweeper<time>
2525
{
2626
typedef pfasst::encap::Encapsulation<time> Encapsulation;
@@ -89,20 +89,27 @@ class AdvectionDiffusionSweeper
8989
double d = abs(qend->data()[i] - qex->data()[i]);
9090
if (d > max) { max = d; }
9191
}
92-
cout << "err: " << scientific << max
92+
93+
auto n = this->get_controller()->get_step();
94+
auto k = this->get_controller()->get_iteration();
95+
cout << "err: " << n << " " << k << " " << scientific << max
9396
<< " (" << qend->size() << ", " << predict << ")"
9497
<< endl;
9598
}
9699

97-
void predict(time t, time dt, bool initial)
100+
void predict(bool initial)
98101
{
99-
pfasst::encap::IMEXSweeper<time>::predict(t, dt, initial);
102+
pfasst::encap::IMEXSweeper<time>::predict(initial);
103+
time t = this->get_controller()->get_time();
104+
time dt = this->get_controller()->get_time_step();
100105
echo_error(t + dt, true);
101106
}
102107

103-
void sweep(time t, time dt)
108+
void sweep()
104109
{
105-
pfasst::encap::IMEXSweeper<time>::sweep(t, dt);
110+
pfasst::encap::IMEXSweeper<time>::sweep();
111+
time t = this->get_controller()->get_time();
112+
time dt = this->get_controller()->get_time_step();
106113
echo_error(t + dt);
107114
}
108115

@@ -150,7 +157,7 @@ class AdvectionDiffusionSweeper
150157
fft.backward(f);
151158
}
152159

153-
void f2comp(shared_ptr<Encapsulation> f, shared_ptr<Encapsulation> q, time t, time dt,
160+
void f2comp(shared_ptr<Encapsulation> f, shared_ptr<Encapsulation> q, time t, time dt,
154161
shared_ptr<Encapsulation> rhs)
155162
{
156163
shared_ptr<DVectorT> f_cast = dynamic_pointer_cast<DVectorT>(f);
@@ -163,7 +170,7 @@ class AdvectionDiffusionSweeper
163170
this->f2comp(f_cast, q_cast, t, dt, rhs_cast);
164171
}
165172

166-
void f2comp(shared_ptr<DVectorT> f, shared_ptr<DVectorT> q, time t, time dt,
173+
void f2comp(shared_ptr<DVectorT> f, shared_ptr<DVectorT> q, time t, time dt,
167174
shared_ptr<DVectorT> rhs)
168175
{
169176
auto* z = fft.forward(rhs);

include/pfasst/controller.hpp

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,26 @@ namespace pfasst
2626
deque<shared_ptr<ISweeper<time>>> levels;
2727
deque<shared_ptr<ITransfer<time>>> transfer;
2828

29-
size_t nsteps, niters;
30-
time dt;
29+
time dt;
3130

3231
public:
3332
//! @{
3433
void setup()
3534
{
3635
for (auto l = coarsest(); l <= finest(); ++l) {
36+
l.current()->set_controller(this);
3737
l.current()->setup();
3838
}
3939
}
4040

4141
void set_duration(time dt, size_t nsteps, size_t niters)
4242
{
4343
this->dt = dt;
44-
this->nsteps = nsteps;
45-
this->niters = niters;
44+
steps.set_size(nsteps);
45+
iterations.set_size(niters);
4646
}
4747

48-
void add_level(shared_ptr<ISweeper<time>> swpr,
48+
void add_level(shared_ptr<ISweeper<time>> swpr,
4949
shared_ptr<ITransfer<time>> trnsfr = shared_ptr<ITransfer<time>>(nullptr),
5050
bool coarse = true)
5151
{
@@ -63,32 +63,26 @@ namespace pfasst
6363
template<typename R = ISweeper<time>>
6464
shared_ptr<R> get_level(size_t level)
6565
{
66-
shared_ptr<R> r = dynamic_pointer_cast<R>(levels[level]);
67-
assert(r);
66+
shared_ptr<R> r = dynamic_pointer_cast<R>(levels[level]); assert(r);
6867
return r;
6968
}
7069

7170
template<typename R = ISweeper<time>>
7271
shared_ptr<R> get_finest()
7372
{
74-
shared_ptr<R> r = dynamic_pointer_cast<R>(levels.back());
75-
assert(r);
76-
return r;
73+
return get_level<R>(nlevels()-1);
7774
}
7875

7976
template<typename R = ISweeper<time>>
8077
shared_ptr<R> get_coarsest()
8178
{
82-
shared_ptr<R> r = dynamic_pointer_cast<R>(levels.front());
83-
assert(r);
84-
return r;
79+
return get_level<R>(0);
8580
}
8681

8782
template<typename R = ITransfer<time>>
8883
shared_ptr<R> get_transfer(size_t level)
8984
{
90-
shared_ptr<R> r = dynamic_pointer_cast<R>(transfer[level]);
91-
assert(r);
85+
shared_ptr<R> r = dynamic_pointer_cast<R>(transfer[level]); assert(r);
9286
return r;
9387
}
9488

@@ -100,13 +94,13 @@ namespace pfasst
10094

10195
/**
10296
* level (MLSDC/PFASST) iterator.
103-
*
97+
*
10498
* This iterator is used to walk through the MLSDC/PFASST hierarchy of sweepers.
105-
* It keeps track of the _current_ level, and has convenience routines to return the
99+
* It keeps track of the _current_ level, and has convenience routines to return the
106100
* LevelIter::current(), LevelIter::fine() (i.e. `current+1`), and LevelIter::coarse()
107101
* (`current-1`) sweepers.
108-
*
109-
* Under the hood it satisfies the requirements of std::random_access_iterator_tag, thus
102+
*
103+
* Under the hood it satisfies the requirements of std::random_access_iterator_tag, thus
110104
* implementing a `RandomAccessIterator`.
111105
*/
112106
class LevelIter
@@ -179,6 +173,41 @@ namespace pfasst
179173
LevelIter finest() { return LevelIter(nlevels() - 1, this); }
180174
LevelIter coarsest() { return LevelIter(0, this); }
181175
//! @}
176+
177+
178+
/**
179+
* Simple range iterator.
180+
*/
181+
class RangeIter {
182+
friend Controller;
183+
size_t i, n;
184+
public:
185+
void set_size(size_t n) { this->n = n; }
186+
void reset(size_t i = 0) { this->i = i; }
187+
bool valid() { return i < n; }
188+
void next() { i++; }
189+
} steps, iterations;
190+
191+
size_t get_step()
192+
{
193+
return steps.i;
194+
}
195+
196+
size_t get_iteration()
197+
{
198+
return iterations.i;
199+
}
200+
201+
time get_time()
202+
{
203+
return get_step() * get_time_step();
204+
}
205+
206+
time get_time_step()
207+
{
208+
return dt;
209+
}
210+
182211
};
183212
}
184213

include/pfasst/encap/imex_sweeper.hpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace pfasst
1919
using pfasst::encap::Encapsulation;
2020

2121
template<typename time = time_precision>
22-
class IMEXSweeper
22+
class IMEXSweeper
2323
: public pfasst::encap::EncapSweeper<time>
2424
{
2525
vector<shared_ptr<Encapsulation<time>>> Q, pQ, S, T, Fe, Fi;
@@ -94,12 +94,15 @@ namespace pfasst
9494
}
9595
}
9696

97-
virtual void sweep(time t0, time dt)
97+
virtual void sweep()
9898
{
9999
const auto nodes = this->get_nodes();
100100
const size_t nnodes = nodes.size();
101101
assert(nnodes >= 1);
102102

103+
time dt = this->get_controller()->get_time_step();
104+
time t = this->get_controller()->get_time();
105+
103106
// integrate
104107
S[0]->mat_apply(S, dt, SEmat, Fe, true);
105108
S[0]->mat_apply(S, dt, SImat, Fi, false);
@@ -112,7 +115,6 @@ namespace pfasst
112115
// sweep
113116
shared_ptr<Encapsulation<time>> rhs = this->get_factory()->create(pfasst::encap::solution);
114117

115-
time t = t0;
116118
for (size_t m = 0; m < nnodes - 1; m++) {
117119
time ds = dt * (nodes[m + 1] - nodes[m]);
118120

@@ -126,20 +128,22 @@ namespace pfasst
126128
}
127129
}
128130

129-
virtual void predict(time t0, time dt, bool initial)
131+
virtual void predict(bool initial)
130132
{
131133
const auto nodes = this->get_nodes();
132134
const size_t nnodes = nodes.size();
133135
assert(nnodes >= 1);
134136

137+
time dt = this->get_controller()->get_time_step();
138+
time t = this->get_controller()->get_time();
139+
135140
if (initial) {
136-
f1eval(Fe[0], Q[0], t0);
137-
f2eval(Fi[0], Q[0], t0);
141+
f1eval(Fe[0], Q[0], t);
142+
f2eval(Fi[0], Q[0], t);
138143
}
139144

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

142-
time t = t0;
143147
for (size_t m = 0; m < nnodes - 1; m++) {
144148
time ds = dt * (nodes[m + 1] - nodes[m]);
145149
rhs->copy(Q[m]);
@@ -165,19 +169,19 @@ namespace pfasst
165169
f2eval(Fi[m], Q[m], t);
166170
}
167171

168-
virtual void f1eval(shared_ptr<Encapsulation<time>> F, shared_ptr<Encapsulation<time>> Q,
172+
virtual void f1eval(shared_ptr<Encapsulation<time>> F, shared_ptr<Encapsulation<time>> Q,
169173
time t)
170174
{
171175
throw NotImplementedYet("imex (f1eval)");
172176
}
173177

174-
virtual void f2eval(shared_ptr<Encapsulation<time>> F, shared_ptr<Encapsulation<time>> Q,
178+
virtual void f2eval(shared_ptr<Encapsulation<time>> F, shared_ptr<Encapsulation<time>> Q,
175179
time t)
176180
{
177181
throw NotImplementedYet("imex (f2eval)");
178182
}
179183

180-
virtual void f2comp(shared_ptr<Encapsulation<time>> F, shared_ptr<Encapsulation<time>> Q,
184+
virtual void f2comp(shared_ptr<Encapsulation<time>> F, shared_ptr<Encapsulation<time>> Q,
181185
time t, time dt,
182186
shared_ptr<Encapsulation<time>> rhs)
183187
{

0 commit comments

Comments
 (0)