PFASST++
injective_transfer.hpp
Go to the documentation of this file.
1 
5 #ifndef _EXAMPLES__BORIS__INJECTIVE_TRANSFER__HPP_
6 #define _EXAMPLES__BORIS__INJECTIVE_TRANSFER__HPP_
7 
8 #include <pfasst/logging.hpp>
9 #include <pfasst/interfaces.hpp>
11 
12 #include "boris_sweeper.hpp"
13 
14 
15 namespace pfasst
16 {
17  namespace examples
18  {
19  namespace boris
20  {
24  template<
25  typename scalar,
26  typename time = pfasst::time_precision
27  >
29  : public ITransfer<time>
30  {
31  public:
34 
35  public:
37  {}
38 
39 
40  virtual void interpolate_initial(shared_ptr<ISweeper<time>> dst,
41  shared_ptr<const ISweeper<time>> src) override
42  {
43  CVLOG(2, "BorisTransfer") << "interpolating initial particle only";
44  auto fine = dynamic_pointer_cast<BorisSweeper<scalar, time>>(dst);
45  assert(fine);
46  auto crse = dynamic_pointer_cast<const BorisSweeper<scalar, time>>(src);
47  assert(crse);
48  CVLOG(5, "BorisTransfer") << "coarse: " << crse->get_start_state();
49 
50  auto crse_factory = crse->get_factory();
51  auto fine_factory = fine->get_factory();
52 
53  shared_ptr<encap_type> crse_delta = dynamic_pointer_cast<encap_type>(crse_factory->create(solution));
54  this->restrict(crse_delta, dynamic_pointer_cast<const encap_type>(fine->get_start_state()));
55  crse_delta->positions() -= dynamic_pointer_cast<const encap_type>(crse->get_start_state())->positions();
56  crse_delta->velocities() -= dynamic_pointer_cast<const encap_type>(crse->get_start_state())->velocities();
57 
58  shared_ptr<encap_type> fine_delta = dynamic_pointer_cast<encap_type>(fine_factory->create(solution));
59  this->interpolate(fine_delta, crse_delta);
60  shared_ptr<encap_type> fine_start = dynamic_pointer_cast<encap_type>(fine->get_start_state());
61  fine_start->positions() -= fine_delta->positions();
62  fine_start->velocities() -= fine_delta->velocities();
63 
64  fine->set_start_state(fine_start);
65  CVLOG(5, "BorisTransfer") << "interpolated: " << fine->get_start_state();
66  }
67 
68  virtual void interpolate(shared_ptr<ISweeper<time>> dst,
69  shared_ptr<const ISweeper<time>> src,
70  bool interp_initial = false) override
71  {
72  CVLOG(2, "BorisTransfer") << "interpolating";
73  if (interp_initial) {
74  this->interpolate_initial(dst, src);
75  }
76 
77  auto fine = dynamic_pointer_cast<BorisSweeper<scalar, time>>(dst);
78  assert(fine);
79  auto crse = dynamic_pointer_cast<const BorisSweeper<scalar, time>>(src);
80  assert(crse);
81 
82  auto const ncrse = crse->get_nodes().size(); assert(ncrse >= 1);
83  auto const nfine = fine->get_nodes().size(); assert(nfine >= 1);
84 
85  auto crse_factory = crse->get_factory();
86  auto fine_factory = fine->get_factory();
87 
88  vector<shared_ptr<encap_type>> fine_delta(nfine), crse_delta(ncrse);
89 
90  for (size_t m = 0; m < fine->get_nodes().size(); ++m) {
91  shared_ptr<encap_type> crse_state = dynamic_pointer_cast<encap_type>(crse->get_state(m));
92  shared_ptr<encap_type> fine_state = dynamic_pointer_cast<encap_type>(fine->get_state(m));
93  CVLOG(5, "BorisTransfer") << "coarse[" << m << "]: " << crse_state;
94  CVLOG(5, "BorisTransfer") << "fine[" << m << "]: " << fine_state;
95 
96  crse_delta[m] = dynamic_pointer_cast<encap_type>(crse_factory->create(solution));
97  this->restrict(crse_delta[m], fine_state);
98  crse_delta[m]->positions() -= crse_state->positions();
99  crse_delta[m]->velocities() -= crse_state->velocities();
100  CVLOG(5, "BorisTransfer") << " crse_delta[" << m << "]: " << crse_delta[m];
101 
102  fine_delta[m] = dynamic_pointer_cast<encap_type>(fine_factory->create(solution));
103  this->interpolate(fine_delta[m], crse_delta[m]);
104  CVLOG(5, "BorisTransfer") << " fine_delta[" << m << "]: " << fine_delta[m];
105  fine_state->positions() -= fine_delta[m]->positions();
106  fine_state->velocities() -= fine_delta[m]->velocities();
107 
108  fine->set_state(fine_state, m);
109  fine->evaluate(m);
110  CVLOG(5, "BorisTransfer") << "interpolated[" << m << "]: "
111  << dynamic_pointer_cast<encap_type>(fine->get_state(m));
112  }
113  fine->save();
114  }
115 
116  virtual void interpolate(shared_ptr<ParticleCloud<scalar>> dst,
117  shared_ptr<const ParticleCloud<scalar>> src)
118  {
119  CVLOG(5, "BorisTransfer") << "interpolate cloud: " << src;
120  dst->copy(src);
121  CVLOG(5, "BorisTransfer") << " --> " << dst;
122  }
123 
124  virtual void interpolate(shared_ptr<ParticleCloudComponent<scalar>> dst,
125  shared_ptr<const ParticleCloudComponent<scalar>> src)
126  {
127  CVLOG(5, "BorisTransfer") << "interpolate cmpnt: <" << src << ">" << *(src.get());
128  *(dst.get()) = *(src.get());
129  CVLOG(5, "BorisTransfer") << " --> <" << dst << ">" << *(dst.get());
130  }
131 
132 
133  virtual void restrict_initial(shared_ptr<ISweeper<time>> dst,
134  shared_ptr<const ISweeper<time>> src) override
135  {
136  CVLOG(2, "BorisTransfer") << "restricting initial particle only";
137  auto coarse = dynamic_pointer_cast<BorisSweeper<scalar, time>>(dst);
138  assert(coarse);
139  auto fine = dynamic_pointer_cast<const BorisSweeper<scalar, time>>(src);
140  assert(fine);
141  CVLOG(5, "BorisTransfer") << "fine: " << fine->get_start_state();
142  coarse->set_start_state(dynamic_pointer_cast<typename BorisSweeper<scalar, time>::encap_type>(fine->get_start_state()));
143  CVLOG(5, "BorisTransfer") << "restricted: " << coarse->get_start_state();
144  }
145 
146  virtual void restrict(shared_ptr<ISweeper<time>> dst,
147  shared_ptr<const ISweeper<time>> src,
148  bool restrict_initial = false) override
149  {
150  CVLOG(2, "BorisTransfer") << "restricting";
151  if (restrict_initial) {
152  this->restrict_initial(dst, src);
153  }
154 
155  auto coarse = dynamic_pointer_cast<BorisSweeper<scalar, time>>(dst);
156  assert(coarse);
157  auto fine = dynamic_pointer_cast<const BorisSweeper<scalar, time>>(src);
158  assert(fine);
159 
160  for (size_t m = 0; m < coarse->get_nodes().size(); ++m) {
161  CVLOG(5, "BorisTransfer") << "fine[" << m << "]: "
162  << dynamic_pointer_cast<ParticleCloud<scalar>>(fine->get_state(m));
163  coarse->set_state(dynamic_pointer_cast<const encap_type>(fine->get_state(m)), m);
164  CVLOG(5, "BorisTransfer") << "restricted[" << m << "]: "
165  << dynamic_pointer_cast<ParticleCloud<scalar>>(coarse->get_state(m));
166  coarse->evaluate(m);
167  }
168  }
169 
170  virtual void restrict(shared_ptr<ParticleCloud<scalar>> dst,
171  shared_ptr<const ParticleCloud<scalar>> src)
172  {
173  CVLOG(5, "BorisTransfer") << "restrict cloud: " << src;
174  dst->copy(src);
175  CVLOG(5, "BorisTransfer") << " --> " << dst;
176  }
177 
178  virtual void restrict(shared_ptr<ParticleCloudComponent<scalar>> dst,
179  shared_ptr<const ParticleCloudComponent<scalar>> src)
180  {
181  CVLOG(5, "BorisTransfer") << "restrict cmpnt: <" << src << ">" << *(src.get());
182  *(dst.get()) = *(src.get());
183  CVLOG(5, "BorisTransfer") << " --> <" << dst << ">" << *(dst.get());
184  }
185 
186 
187  virtual void fas(time dt, shared_ptr<ISweeper<time>> dst,
188  shared_ptr<const ISweeper<time>> src) override
189  {
190  CVLOG(2, "BorisTransfer") << "computing FAS correction";
191  auto crse = dynamic_pointer_cast<BorisSweeper<scalar, time>>(dst);
192  assert(crse);
193  auto fine = dynamic_pointer_cast<const BorisSweeper<scalar, time>>(src);
194  assert(fine);
195 
197 
198  auto const ncrse = crse->get_nodes().size(); assert(ncrse >= 1);
199  auto const nfine = fine->get_nodes().size(); assert(nfine >= 1);
200 
201  auto crse_factory = dynamic_pointer_cast<ParticleCloudFactory<scalar>>(crse->get_factory());
202  const size_t crse_nparticle = crse_factory->num_particles();
203  const size_t crse_dim = crse_factory->dim();
204  // cloud_component_factory<scalar>(crse_nparticle, crse_dim);
205  auto fine_factory = dynamic_pointer_cast<ParticleCloudFactory<scalar>>(fine->get_factory());
206  const size_t fine_nparticle = fine_factory->num_particles();
207  const size_t fine_dim = fine_factory->dim();
208  // cloud_component_factory<scalar>(fine_nparticle, fine_dim);
209 
210  vector<shared_ptr<force_type>> crse_int_q(ncrse), fine_int_q(nfine), rstr_int_q(ncrse);
211  vector<shared_ptr<force_type>> crse_int_qq(ncrse), fine_int_qq(nfine), rstr_int_qq(ncrse);
212  for (size_t m = 0; m < ncrse; m++) {
213  crse_int_q[m] = make_shared<force_type>(cloud_component_factory<scalar>(crse_nparticle, crse_dim));
214  crse_int_qq[m] = make_shared<force_type>(cloud_component_factory<scalar>(crse_nparticle, crse_dim));
215  rstr_int_q[m] = make_shared<force_type>(cloud_component_factory<scalar>(crse_nparticle, crse_dim));
216  rstr_int_qq[m] = make_shared<force_type>(cloud_component_factory<scalar>(crse_nparticle, crse_dim));
217  }
218  for (size_t m = 0; m < nfine; m++) {
219  fine_int_q[m] = make_shared<force_type>(cloud_component_factory<scalar>(fine_nparticle, fine_dim));
220  fine_int_qq[m] = make_shared<force_type>(cloud_component_factory<scalar>(fine_nparticle, fine_dim));
221  }
222 
223  // compute '0 to node' integral on the coarse level
224  CVLOG(5, "BorisTransfer") << "computing coarse integral";
225  crse->integrate(dt, crse_int_q, crse_int_qq);
226 
227  // compute '0 to node' integral on the fine level
228  CVLOG(5, "BorisTransfer") << "computing fine integral";
229  fine->integrate(dt, fine_int_q, fine_int_qq);
230 
231  // restrict '0 to node' fine integral
232  CVLOG(5, "BorisTransfer") << "restricting fine integral";
233  int trat = (int(nfine) - 1) / (int(ncrse) - 1);
234  for (size_t m = 0; m < ncrse; m++) {
235  this->restrict(rstr_int_q[m], fine_int_q[m * trat]);
236  this->restrict(rstr_int_qq[m], fine_int_qq[m * trat]);
237  }
238 
239  CVLOG(5, "BorisTransfer") << "get previous node-to-node tau correction";
240  // compute 'node to node' tau correction
241  vector<shared_ptr<force_type>> tau_q(ncrse), tau_qq(ncrse);
242  for (size_t m = 0; m < ncrse; m++) {
243  tau_q[m] = crse->get_tau_q_as_force(m);
244  tau_qq[m] = crse->get_tau_qq_as_force(m);
245  CVLOG(5, "BorisTransfer") << "previous tau_q[" << m << "]: <" << tau_q[m] << ">" << *(tau_q[m].get());
246  CVLOG(5, "BorisTransfer") << "previous tau_qq[" << m << "]: <" << tau_qq[m] << ">" << *(tau_qq[m].get());
247  zero(*(tau_q[m].get()));
248  zero(*(tau_qq[m].get()));
249  }
250 
251  CVLOG(5, "BorisTransfer") << "convert node-to-node tau correction from 0-to-node";
252  for (size_t m = 0; m < ncrse; ++m) {
253  // compute 0-to-m FAS correction
254 // CVLOG(5, "BorisTransfer") << "0-to-m FAS_q[" << m << "]: "
255 // << *(tau_q[m].get()) << " += " << *(rstr_int_q[m].get()) << " - " << *(fine_int_q[m].get());
256  *(tau_q[m].get()) = *(rstr_int_q[m].get()) - *(crse_int_q[m].get());
257 // CVLOG(5, "BorisTransfer") << " --> " << *(tau_q[m].get());
258 // CVLOG(5, "BorisTransfer") << "0-to-m FAS_qq[" << m << "]: "
259 // << *(tau_qq[m].get()) << " += " << *(rstr_int_qq[m].get()) << " - " << *(fine_int_qq[m].get());
260  *(tau_qq[m].get()) = *(rstr_int_qq[m].get()) - *(crse_int_qq[m].get());
261 // CVLOG(5, "BorisTransfer") << " --> " << *(tau_qq[m].get());
262 
263 // CVLOG(5, "BorisTransfer") << " make it node-to-node";
264  // make it a (m-1)-to-m FAS correction
265 // for (size_t n = 0; n < m; ++n) {
266 // CVLOG(5, "BorisTransfer") << " tau_q[" << m << "] += " << *(rstr_int_q[n].get()) << " - " << *(crse_int_q[n].get());
267 // *(tau_q[m].get()) += *(rstr_int_q[n].get()) - *(crse_int_q[n].get());
268 // CVLOG(5, "BorisTransfer") << " --> " << *(tau_q[m].get());
269 // CVLOG(5, "BorisTransfer") << " tau_qq[" << m << "] += " << *(rstr_int_qq[n].get()) << " - " << *(crse_int_qq[n].get());
270 // *(tau_qq[m].get()) += *(rstr_int_qq[n].get()) - *(crse_int_qq[n].get());
271 // CVLOG(5, "BorisTransfer") << " --> " << *(tau_qq[m].get());
272 // }
273  }
274 
275  for (size_t m = 0; m < ncrse; ++m) {
276  CVLOG(5, "BorisTransfer") << "new tau_q[" << m << "]: <" << tau_q[m] << ">" << *(tau_q[m].get());
277  CVLOG(5, "BorisTransfer") << "new tau_qq[" << m << "]: <" << tau_qq[m] << ">" << *(tau_qq[m].get());
278  }
279  }
281  };
282  }
283  }
284 }
285 
286 #endif // _EXAMPLES__BORIS__INJECTIVE_TRANSFER__HPP_
virtual void restrict(shared_ptr< ParticleCloud< scalar >> dst, shared_ptr< const ParticleCloud< scalar >> src)
virtual void interpolate(shared_ptr< ParticleCloudComponent< scalar >> dst, shared_ptr< const ParticleCloudComponent< scalar >> src)
static void zero(vector< precision > &data)
double time_precision
Definition: interfaces.hpp:18
virtual void interpolate_initial(shared_ptr< ISweeper< time >> dst, shared_ptr< const ISweeper< time >> src) override
Interpolate initial condition from the coarse sweeper to the fine sweeper.
BorisSweeper< scalar, time >::encap_type encap_type
virtual void restrict(shared_ptr< ISweeper< time >> dst, shared_ptr< const ISweeper< time >> src, bool restrict_initial=false) override
Restrict, in time and space, from the fine sweeper to the coarse sweeper.
vector< precision > ParticleCloudComponent
BorisSweeper< scalar, time >::acceleration_type force_type
interfaces for SDC/MLSDC/PFASST algorithms.
Abstract time/space transfer (restrict/interpolate) class.
Definition: interfaces.hpp:295
virtual void restrict_initial(shared_ptr< ISweeper< time >> dst, shared_ptr< const ISweeper< time >> src) override
Restrict initial condition from the fine sweeper to the coarse sweeper.
ParticleCloudComponent< scalar > acceleration_type
virtual void interpolate(shared_ptr< ISweeper< time >> dst, shared_ptr< const ISweeper< time >> src, bool interp_initial=false) override
Interpolate, in time and space, from the coarse sweeper to the fine sweeper.
Abstract SDC sweeper.
Definition: interfaces.hpp:164
virtual void fas(time dt, shared_ptr< ISweeper< time >> dst, shared_ptr< const ISweeper< time >> src) override
Compute FAS correction between the coarse and fine sweepers.
virtual void interpolate(shared_ptr< ParticleCloud< scalar >> dst, shared_ptr< const ParticleCloud< scalar >> src)
float dt
Definition: plot.py:10
virtual void restrict(shared_ptr< ParticleCloudComponent< scalar >> dst, shared_ptr< const ParticleCloudComponent< scalar >> src)