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_
1419using namespace std ;
1520
1621template <typename time = pfasst::time_precision>
22+
23+ /*
24+ * ScalarSweeper is derived from the generic IMEXSweeper
25+ */
1726class 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