Skip to content

Commit a997b3e

Browse files
author
Daniel Ruprecht
committed
extended documentation for scalar example
1 parent c3df70d commit a997b3e

File tree

2 files changed

+86
-10
lines changed

2 files changed

+86
-10
lines changed

examples/scalar/scalar_sdc.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
/*
22
* Scalar test equation example using an encapsulated IMEX sweeper.
3-
* Solves Dahlquist's test equation
4-
* y' = a y + i b y
5-
* treating the real part implicitly and the imaginary part explicitly.
3+
*
4+
* Solves Dahlquist's test equation with single level SDC
5+
*
6+
* y' = lambda y = a y + i b y, y(0) = 1.0
7+
*
8+
* with complex lambda, treating the real part implicitly and the imaginary part
9+
* explicitly.
10+
*
611
*/
712

813
#include<complex>
@@ -13,26 +18,32 @@
1318

1419
#include "scalar_sweeper.hpp"
1520

16-
/*
17-
* A simple run routine with preset parameters
18-
*/
19-
2021
double run_scalar_sdc(const size_t nsteps, const double dt, const size_t nnodes,
2122
const size_t niters, const complex<double> lambda,
2223
const pfasst::QuadratureType nodetype)
2324
{
2425
pfasst::SDC<> sdc;
25-
26+
27+
/*
28+
* For test equation, set initial value to 1+i0
29+
*/
2630
const complex<double> y0 = complex<double>(1.0, 0.0);
2731

2832
auto nodes = pfasst::compute_nodes(nnodes, nodetype);
33+
/*
34+
* This is a scalar example, so we use the encap::VectorFactory with fixed
35+
* length of 1 and complex type.
36+
*/
2937
auto factory = make_shared<pfasst::encap::VectorFactory<complex<double>>>(1);
3038
auto sweeper = make_shared<ScalarSweeper<>>(lambda, y0);
3139

3240
sweeper->set_nodes(nodes);
3341
sweeper->set_factory(factory);
3442

3543
sdc.add_level(sweeper);
44+
/*
45+
* Final time Tend = dt*nsteps
46+
*/
3647
sdc.set_duration(0.0, dt*nsteps, dt, niters);
3748
sdc.setup();
3849

@@ -45,6 +56,9 @@ double run_scalar_sdc(const size_t nsteps, const double dt, const size_t nnodes,
4556
}
4657

4758
#ifndef PFASST_UNIT_TESTING
59+
/*
60+
* Main routine running the scalar example with a preset parameters
61+
*/
4862
int main(int /*argc*/, char** /*argv*/)
4963
{
5064
const size_t nsteps = 2;

examples/scalar/scalar_sweeper.hpp

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
/*
22
* Sweeper for scalar test equation
3+
*
4+
* u' = lambda*u, u(0) = u0
5+
*
6+
* with complex lambda using an IMEX scheme. Derived from the generic imex_sweeper
7+
*
38
*/
49

510
#ifndef _EXAMPLES__SCALAR__SCALAR_SWEEPER_HPP_
@@ -14,19 +19,47 @@
1419
using namespace std;
1520

1621
template<typename time = pfasst::time_precision>
22+
23+
/*
24+
* ScalarSweeper is derived from the generic IMEXSweeper
25+
*/
1726
class ScalarSweeper
1827
: public pfasst::encap::IMEXSweeper<time>
1928
{
29+
2030
private:
2131
typedef pfasst::encap::Encapsulation<time> encap_type;
32+
33+
/*
34+
* Define a type for a complex PFASST vector encapsulation.
35+
*/
2236
typedef pfasst::encap::VectorEncapsulation<complex<double>> complex_vector_type;
23-
37+
38+
/*
39+
* Parameter lambda and initial value u0
40+
*/
2441
complex<double> lambda, u0;
25-
size_t n_f_expl_eval, n_f_impl_eval, n_impl_solve;
42+
43+
/*
44+
* The complex unit i = sqrt(-1)
45+
*/
2646
const complex<double> i_complex = complex<double>(0, 1);
47+
48+
/*
49+
* Error at the final time. For the scalar example, an analytical solution is known.
50+
*/
2751
double error;
52+
53+
/*
54+
* Counters for how often f_expl_eval, f_impl_eval and impl_solve are called.
55+
*/
56+
size_t n_f_expl_eval, n_f_impl_eval, n_impl_solve;
2857

2958
public:
59+
60+
/*
61+
* Generic constructor; initialize all function call counters with zero.
62+
*/
3063
ScalarSweeper(complex<double> lambda, complex<double> u0)
3164
: lambda(lambda)
3265
, u0(u0)
@@ -36,6 +69,9 @@ class ScalarSweeper
3669
, error(0.0)
3770
{}
3871

72+
/*
73+
* Upon destruction, report final error and number of function calls
74+
*/
3975
virtual ~ScalarSweeper()
4076
{
4177
cout << "Final error: " << scientific << this->error << endl;
@@ -44,6 +80,9 @@ class ScalarSweeper
4480
cout << "Number of implicit solves: " << this->n_impl_solve << endl;
4581
}
4682

83+
/*
84+
* Compute error and print it to cout
85+
*/
4786
void echo_error(time t)
4887
{
4988
auto& qend = pfasst::encap::as_vector<complex<double>, time>(this->get_end_state());
@@ -56,11 +95,17 @@ class ScalarSweeper
5695
this->error = max_err;
5796
}
5897

98+
/*
99+
* Returns error, but does not update it!
100+
*/
59101
double get_errors()
60102
{
61103
return this->error;
62104
}
63105

106+
/*
107+
* Prediction step and update of error. Uses predictor as provided by IMEXSweeper.
108+
*/
64109
void predict(bool initial) override
65110
{
66111
pfasst::encap::IMEXSweeper<time>::predict(initial);
@@ -69,6 +114,9 @@ class ScalarSweeper
69114
this->echo_error(t + dt);
70115
}
71116

117+
/*
118+
* Perform a sweep and update error. Uses sweep as provided by IMEXSweeper.
119+
*/
72120
void sweep() override
73121
{
74122
pfasst::encap::IMEXSweeper<time>::sweep();
@@ -77,6 +125,9 @@ class ScalarSweeper
77125
this->echo_error(t + dt);
78126
}
79127

128+
/*
129+
* Computes the exact solution u0*exp(lambda*t) at a given time t.
130+
*/
80131
void exact(complex_vector_type& q, time t)
81132
{
82133
q[0] = this->u0 * exp(this->lambda * t);
@@ -88,6 +139,9 @@ class ScalarSweeper
88139
this->exact(q, t);
89140
}
90141

142+
/*
143+
* Evaluate the explicit part of the right hand side: Multiply with imag(lambda)
144+
*/
91145
void f_expl_eval(shared_ptr<encap_type> f_encap,
92146
shared_ptr<encap_type> q_encap, time t) override
93147
{
@@ -101,6 +155,9 @@ class ScalarSweeper
101155
this->n_f_expl_eval++;
102156
}
103157

158+
/*
159+
* Evaluate the implicit part of the right hand side: Multiply with real(lambda)
160+
*/
104161
void f_impl_eval(shared_ptr<encap_type> f_encap,
105162
shared_ptr<encap_type> q_encap, time t) override
106163
{
@@ -114,6 +171,9 @@ class ScalarSweeper
114171
this->n_f_impl_eval++;
115172
}
116173

174+
/*
175+
* For given b, solve (Id - dt*real(lambda))*u = b for u
176+
*/
117177
void impl_solve(shared_ptr<encap_type> f_encap,
118178
shared_ptr<encap_type> q_encap, time t, time dt,
119179
shared_ptr<encap_type> rhs_encap) override
@@ -126,6 +186,8 @@ class ScalarSweeper
126186
// invert f_impl = multiply with inverse of real part of lambda
127187
double inv = 1.0 / (1.0 - double(dt) * real(this->lambda));
128188
q[0] = inv * rhs[0];
189+
190+
// compute f_impl_eval of q[0], i.e. multiply with real(lambda)
129191
f[0] = real(this->lambda) * q[0];
130192

131193
this->n_impl_solve++;

0 commit comments

Comments
 (0)