Skip to content

Commit 80e5b9d

Browse files
committed
Merge branch 'pr/81/head' into release/v0.2.0
* pr/81/head: removed const keywords in scalar_sweeper; they should be there, no idea why it worked even with them more documentation for scalar example; added mathjax directives at multiple points improved docu for scalar example; added ** at several points extended documentation for scalar example Signed-off-by: Torbjörn Klatt <[email protected]>
2 parents c3df70d + 18b2000 commit 80e5b9d

File tree

2 files changed

+88
-17
lines changed

2 files changed

+88
-17
lines changed

examples/scalar/scalar_sdc.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
/*
1+
/**
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+
* \\( u' = \\lambda*u \\quad\\text{ , } u(0) = u_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+0i )\\
29+
*/
2630
const complex<double> y0 = complex<double>(1.0, 0.0);
2731

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

3241
sweeper->set_nodes(nodes);
3342
sweeper->set_factory(factory);
3443

3544
sdc.add_level(sweeper);
45+
46+
// Final time Tend = dt*nsteps
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: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
/*
2-
* Sweeper for scalar test equation
3-
*/
4-
51
#ifndef _EXAMPLES__SCALAR__SCALAR_SWEEPER_HPP_
62
#define _EXAMPLES__SCALAR__SCALAR_SWEEPER_HPP_
73

@@ -14,20 +10,45 @@
1410
using namespace std;
1511

1612
template<typename time = pfasst::time_precision>
13+
14+
/**
15+
* Sweeper for scalar test equation
16+
*
17+
* \\( u' = \\lambda*u \\quad\\text{ , } u(0) = u_0 \\)
18+
*
19+
* with complex lambda using an IMEX scheme. Derived from the generic imex_sweeper.
20+
*
21+
*/
1722
class ScalarSweeper
1823
: public pfasst::encap::IMEXSweeper<time>
1924
{
25+
2026
private:
2127
typedef pfasst::encap::Encapsulation<time> encap_type;
28+
29+
//! Define a type for a complex PFASST vector encapsulation.
2230
typedef pfasst::encap::VectorEncapsulation<complex<double>> complex_vector_type;
23-
31+
32+
//! Parameter lambda and initial value u0
2433
complex<double> lambda, u0;
25-
size_t n_f_expl_eval, n_f_impl_eval, n_impl_solve;
26-
const complex<double> i_complex = complex<double>(0, 1);
34+
35+
//! The complex unit i = sqrt(-1)
36+
complex<double> i_complex = complex<double>(0, 1);
37+
38+
//! Error at the final time. For the scalar example, an analytical solution is known.
2739
double error;
40+
41+
//! Counters for how often f_expl_eval, f_impl_eval and impl_solve are called.
42+
size_t n_f_expl_eval, n_f_impl_eval, n_impl_solve;
2843

2944
public:
30-
ScalarSweeper(complex<double> lambda, complex<double> u0)
45+
46+
/**
47+
* Generic constructor; initialize all function call counters with zero.
48+
* @param[in] lambda coefficient in test equation
49+
* @param[in] u0initial value at \\( t=0 \\)
50+
*/
51+
ScalarSweeper(const complex<double> lambda, const complex<double> u0)
3152
: lambda(lambda)
3253
, u0(u0)
3354
, n_f_expl_eval(0)
@@ -36,6 +57,9 @@ class ScalarSweeper
3657
, error(0.0)
3758
{}
3859

60+
/**
61+
* Upon destruction, report final error and number of function calls
62+
*/
3963
virtual ~ScalarSweeper()
4064
{
4165
cout << "Final error: " << scientific << this->error << endl;
@@ -44,6 +68,10 @@ class ScalarSweeper
4468
cout << "Number of implicit solves: " << this->n_impl_solve << endl;
4569
}
4670

71+
/**
72+
* Compute error between last state and exact solution at time tand print it to cout
73+
* @param[in] Time t
74+
*/
4775
void echo_error(time t)
4876
{
4977
auto& qend = pfasst::encap::as_vector<complex<double>, time>(this->get_end_state());
@@ -56,11 +84,17 @@ class ScalarSweeper
5684
this->error = max_err;
5785
}
5886

87+
/**
88+
* Returns error, but does not update it!
89+
*/
5990
double get_errors()
6091
{
6192
return this->error;
6293
}
6394

95+
/**
96+
* Prediction step and update of error. Uses predictor as provided by IMEXSweeper.
97+
*/
6498
void predict(bool initial) override
6599
{
66100
pfasst::encap::IMEXSweeper<time>::predict(initial);
@@ -69,6 +103,9 @@ class ScalarSweeper
69103
this->echo_error(t + dt);
70104
}
71105

106+
/**
107+
* Perform a sweep and update error. Uses sweep as provided by IMEXSweeper.
108+
*/
72109
void sweep() override
73110
{
74111
pfasst::encap::IMEXSweeper<time>::sweep();
@@ -77,6 +114,11 @@ class ScalarSweeper
77114
this->echo_error(t + dt);
78115
}
79116

117+
/**
118+
* Computes the exact solution \\( u_0 \\exp \\left( \\lambda*t \\right) \\)
119+
* at a given time t.
120+
* @param[in] Time t
121+
*/
80122
void exact(complex_vector_type& q, time t)
81123
{
82124
q[0] = this->u0 * exp(this->lambda * t);
@@ -88,6 +130,10 @@ class ScalarSweeper
88130
this->exact(q, t);
89131
}
90132

133+
/**
134+
* Evaluate the explicit part of the right hand side: Multiply with
135+
* \\( \\text{imag}(\\lambda) \\)
136+
*/
91137
void f_expl_eval(shared_ptr<encap_type> f_encap,
92138
shared_ptr<encap_type> q_encap, time t) override
93139
{
@@ -101,6 +147,10 @@ class ScalarSweeper
101147
this->n_f_expl_eval++;
102148
}
103149

150+
/**
151+
* Evaluate the implicit part of the right hand side: Multiply with
152+
* \\( \\text{real}(\\lambda) \\)
153+
*/
104154
void f_impl_eval(shared_ptr<encap_type> f_encap,
105155
shared_ptr<encap_type> q_encap, time t) override
106156
{
@@ -114,6 +164,11 @@ class ScalarSweeper
114164
this->n_f_impl_eval++;
115165
}
116166

167+
/**
168+
* For given \\( b \\), solve
169+
* \\( \\left( \\mathbb{I}_d - \\Delta t \\text{real}(\\lambda) \\right) u = b \\)
170+
* for \\( u \\) and set f_encap to \\( \\text{real}(\\lambda) u \\)
171+
*/
117172
void impl_solve(shared_ptr<encap_type> f_encap,
118173
shared_ptr<encap_type> q_encap, time t, time dt,
119174
shared_ptr<encap_type> rhs_encap) override
@@ -126,6 +181,8 @@ class ScalarSweeper
126181
// invert f_impl = multiply with inverse of real part of lambda
127182
double inv = 1.0 / (1.0 - double(dt) * real(this->lambda));
128183
q[0] = inv * rhs[0];
184+
185+
// compute f_impl_eval of q[0], i.e. multiply with real(lambda)
129186
f[0] = real(this->lambda) * q[0];
130187

131188
this->n_impl_solve++;

0 commit comments

Comments
 (0)