PFASST++
poly_interp_impl.hpp
Go to the documentation of this file.
2 
3 #include <cassert>
4 using namespace std;
5 
6 #include "pfasst/globals.hpp"
7 #include "pfasst/quadrature.hpp"
9 
10 
11 namespace pfasst
12 {
13  namespace encap
14  {
15  template<typename time>
17  {}
18 
19  template<typename time>
21  shared_ptr<const ISweeper<time>> src)
22  {
23  auto& fine = as_encap_sweeper(dst);
24  auto& crse = as_encap_sweeper(src);
25 
26  auto crse_factory = crse.get_factory();
27  auto fine_factory = fine.get_factory();
28 
29  auto crse_delta = crse_factory->create(solution);
30  this->restrict(crse_delta, fine.get_start_state());
31  crse_delta->saxpy(-1.0, crse.get_start_state());
32 
33  auto fine_delta = fine_factory->create(solution);
34  this->interpolate(fine_delta, crse_delta);
35  fine.get_start_state()->saxpy(-1.0, fine_delta);
36 
37  fine.reevaluate(true);
38  }
39 
40  template<typename time>
42  shared_ptr<const ISweeper<time>> src,
43  bool interp_initial)
44  {
45  auto& fine = as_encap_sweeper(dst);
46  auto& crse = as_encap_sweeper(src);
47 
48  if (tmat.rows() == 0) {
49  tmat = pfasst::quadrature::compute_interp<time>(fine.get_nodes(), crse.get_nodes());
50  }
51 
52  if (interp_initial) {
53  this->interpolate_initial(dst, src);
54  }
55 
56  size_t nfine = fine.get_nodes().size();
57  size_t ncrse = crse.get_nodes().size();
58 
59  auto crse_factory = crse.get_factory();
60  auto fine_factory = fine.get_factory();
61 
62  EncapVecT fine_state(nfine), fine_delta(ncrse);
63 
64  for (size_t m = 0; m < nfine; m++) { fine_state[m] = fine.get_state(m); }
65  for (size_t m = 0; m < ncrse; m++) { fine_delta[m] = fine_factory->create(solution); }
66 
67  auto crse_delta = crse_factory->create(solution);
68  for (size_t m = 0; m < ncrse; m++) {
69  crse_delta->copy(crse.get_state(m));
70  crse_delta->saxpy(-1.0, crse.get_saved_state(m));
71  interpolate(fine_delta[m], crse_delta);
72  }
73 
74  fine.get_state(0)->mat_apply(fine_state, 1.0, tmat, fine_delta, false);
75 
76  fine.reevaluate();
77  }
78 
79  template<typename time>
81  shared_ptr<const Encapsulation<time>> src)
82  {
83  UNUSED(dst); UNUSED(src);
84  throw NotImplementedYet("mlsdc/pfasst");
85  }
86 
87  template<typename time>
89  shared_ptr<const ISweeper<time>> src)
90  {
91  auto& crse = as_encap_sweeper(dst);
92  auto& fine = as_encap_sweeper(src);
93  this->restrict(crse.get_start_state(), fine.get_start_state());
94  crse.reevaluate(true);
95  }
96 
97  template<typename time>
99  shared_ptr<const ISweeper<time>> src,
100  bool restrict_initial)
101  {
102  auto& crse = pfasst::encap::as_encap_sweeper(dst);
103  auto& fine = pfasst::encap::as_encap_sweeper(src);
104 
105  auto const crse_nodes = crse.get_nodes();
106  auto const fine_nodes = fine.get_nodes();
107  auto const num_crse = crse_nodes.size();
108  auto const num_fine = fine_nodes.size();
109 
110  if (restrict_initial) {
111  this->restrict_initial(dst, src);
112  }
113 
114  int trat = (int(num_fine) - 1) / (int(num_crse) - 1);
115 
116  for (size_t m = 0; m < num_crse; m++) {
117  if (crse_nodes[m] != fine_nodes[m * trat]) {
118  ML_CLOG(FATAL, "Controller", "coarse nodes must be nested");
119  throw NotImplementedYet("coarse nodes must be nested");
120  }
121  this->restrict(crse.get_state(m), fine.get_state(m * trat));
122  }
123 
124  crse.reevaluate();
125  }
126 
127  template<typename time>
129  shared_ptr<const Encapsulation<time>> src)
130  {
131  UNUSED(dst); UNUSED(src);
132  throw NotImplementedYet("mlsdc/pfasst");
133  }
134 
135  template<typename time>
136  void PolyInterpMixin<time>::fas(time dt, shared_ptr<ISweeper<time>> dst,
137  shared_ptr<const ISweeper<time>> src)
138  {
139  auto& crse = pfasst::encap::as_encap_sweeper(dst);
140  auto& fine = pfasst::encap::as_encap_sweeper(src);
141 
142  auto const ncrse = crse.get_nodes().size(); assert(ncrse >= 1);
143  auto const nfine = fine.get_nodes().size(); assert(nfine >= 1);
144 
145  auto crse_factory = crse.get_factory();
146  auto fine_factory = fine.get_factory();
147 
148  EncapVecT crse_int(ncrse), fine_int(nfine), rstr_int(ncrse);
149 
150  for (size_t m = 0; m < ncrse; m++) { crse_int[m] = crse_factory->create(solution); }
151  for (size_t m = 0; m < ncrse; m++) { rstr_int[m] = crse_factory->create(solution); }
152  for (size_t m = 0; m < nfine; m++) { fine_int[m] = fine_factory->create(solution); }
153 
154  // compute '0 to node' integral on the coarse level
155  crse.integrate(dt, crse_int);
156 
157  // compute '0 to node' integral on the fine level
158  fine.integrate(dt, fine_int);
159 
160  // restrict '0 to node' fine integral
161  int trat = (int(nfine) - 1) / (int(ncrse) - 1);
162  for (size_t m = 0; m < ncrse; m++) {
163  this->restrict(rstr_int[m], fine_int[m * trat]);
164  }
165 
166  // compute 'node to node' tau correction
167  EncapVecT tau(ncrse), rstr_and_crse(2 * ncrse);
168  // Attention: tau is getting filled with pointers to the crse's member
169  for (size_t m = 0; m < ncrse; m++) { tau[m] = crse.get_tau(m); }
170  for (size_t m = 0; m < ncrse; m++) { rstr_and_crse[m] = rstr_int[m]; }
171  for (size_t m = 0; m < ncrse; m++) { rstr_and_crse[ncrse + m] = crse_int[m]; }
172 
173  if (fmat.rows() == 0) {
174  fmat.resize(ncrse, 2 * ncrse);
175  fmat.fill(0.0);
176 
177  for (size_t m = 0; m < ncrse; m++) {
178  fmat(m, m) = 1.0;
179  fmat(m, ncrse + m) = -1.0;
180 
181  // subtract 0-to-(m-1) FAS so resulting FAS is (m-1)-to-m FAS,
182  // which will be required in the sweeper logic
183  for (size_t n = 0; n < m; n++) {
184  fmat(m, n) = -1.0;
185  fmat(m, ncrse + n) = 1.0;
186  }
187  }
188  }
189 
190  tau[0]->mat_apply(tau, 1.0, fmat, rstr_and_crse, true);
191  }
192  } // ::pfasst::encap
193 } // ::pfasst
Not implemented yet exception.
Definition: interfaces.hpp:29
STL namespace.
#define ML_CLOG(level, logger_id, x)
same as CLOG(level, logger, x) from easylogging++
Definition: logging.hpp:117
EncapSweeper< time > & as_encap_sweeper(shared_ptr< ISweeper< time >> x)
Polynomial time interpolation mixin.
Definition: poly_interp.hpp:20
vector< shared_ptr< Encapsulation< time > > > EncapVecT
Definition: poly_interp.hpp:25
Data/solution encapsulation.
#define UNUSED(expr)
Denoting unused function parameters for omitting compiler warnings.
Definition: globals.hpp:32
Abstract SDC sweeper.
Definition: interfaces.hpp:164
float dt
Definition: plot.py:10