@@ -123,37 +123,20 @@ namespace pfasst
123123 }
124124
125125 template <typename scalar, typename time>
126- scalar BorisSweeper<scalar, time>::compute_residual ()
126+ scalar BorisSweeper<scalar, time>::compute_residual_max ()
127127 {
128- BCVLOG (8 ) << " computing residual" ;
128+ BCVLOG (8 ) << " computing max residual" ;
129129 this ->log_indent ->increment (8 );
130- const auto nodes = this ->get_nodes ();
131- const size_t nnodes = nodes.size ();
132- time dt = this ->get_controller ()->get_time_step ();
133130
134- scalar max_residual = 0.0 ;
131+ this -> residual ( this -> get_controller ()-> get_time_step (), this -> residuals ) ;
135132
136- for (size_t m = 1 ; m < nnodes; ++m) {
137- BCVLOG (8 ) << " for node " << m;
138- position_type pos = cloud_component_factory<scalar>(this ->particles [0 ]->size (), this ->particles [0 ]->dim ());
139- velocity_type vel = cloud_component_factory<scalar>(this ->particles [0 ]->size (), this ->particles [0 ]->dim ());
140- for (size_t j = 0 ; j < nnodes; ++j) {
141- pos += this ->q_mat (m, j) * dt * this ->particles [j]->velocities ();
142- vel += this ->q_mat (m, j) * dt * this ->build_rhs (j);
143- }
144- pos += this ->start_particles ->positions () - this ->particles [m]->positions ();
145- vel += this ->start_particles ->velocities () - this ->particles [m]->velocities ();
133+ scalar max_residual = scalar (0.0 );
146134
147- for (size_t j = 0 ; j < pos.size (); ++j) {
148- for (size_t d = 0 ; d < pos[j].size (); ++d) {
149- max_residual = std::max (max_residual, abs (pos[j][d]));
150- max_residual = std::max (max_residual, abs (vel[j][d]));
151- }
152- }
135+ for (size_t m = 1 ; m < this ->residuals .size (); ++m) {
136+ max_residual = std::max (max_residual, this ->residuals [m]->norm0 ());
153137 }
154138
155- BCVLOG (8 ) << " => residual: " << max_residual;
156- this ->log_indent ->decrement (8 );
139+ BCVLOG (8 ) << " => max residual: " << max_residual;
157140 return max_residual;
158141 }
159142
@@ -412,7 +395,7 @@ namespace pfasst
412395 ErrorTuple<scalar> e_tuple;
413396 scalar e_end = this ->impl_solver ->energy (end, t);
414397 e_tuple.e_drift = abs (this ->initial_energy - e_end);
415- e_tuple.res = this ->compute_residual ();
398+ e_tuple.res = this ->compute_residual_max ();
416399
417400 size_t n = this ->get_controller ()->get_step ();
418401 size_t k = this ->get_controller ()->get_iteration ();
@@ -471,6 +454,7 @@ namespace pfasst
471454 this ->energy_evals .resize (nnodes);
472455 for (size_t m = 0 ; m < nnodes; ++m) {
473456 this ->particles .push_back (dynamic_pointer_cast<encap_type>(this ->get_factory ()->create (pfasst::encap::solution)));
457+ this ->residuals .push_back (dynamic_pointer_cast<encap_type>(this ->get_factory ()->create (pfasst::encap::solution)));
474458 this ->saved_particles .push_back (dynamic_pointer_cast<encap_type>(this ->get_factory ()->create (pfasst::encap::solution)));
475459 this ->forces .push_back (cloud_component_factory<scalar>(this ->particles [m]->size (), this ->particles [m]->dim ()));
476460 this ->saved_forces .push_back (cloud_component_factory<scalar>(this ->particles [m]->size (), this ->particles [m]->dim ()));
@@ -580,6 +564,35 @@ namespace pfasst
580564 this ->log_indent ->decrement (6 );
581565 }
582566
567+ template <typename scalar, typename time>
568+ void BorisSweeper<scalar, time>::residual(time dt, vector<shared_ptr<Encapsulation<time>>> dst) const
569+ {
570+ BCVLOG (8 ) << " computing residual" ;
571+ const auto nodes = this ->get_nodes ();
572+ const size_t nnodes = nodes.size ();
573+ assert (dst.size () == nnodes);
574+
575+ vector<shared_ptr<encap_type>> dst_cast (nnodes);
576+ for (size_t m = 0 ; m < nnodes; ++m) {
577+ dst_cast[m] = dynamic_pointer_cast<encap_type>(dst[m]);
578+ assert (dst_cast[m]);
579+ }
580+
581+ for (size_t m = 1 ; m < nnodes; ++m) {
582+ BCVLOG (8 ) << " for node " << m;
583+ zero (dst_cast[m]->positions ());
584+ zero (dst_cast[m]->velocities ());
585+ for (size_t j = 0 ; j < nnodes; ++j) {
586+ dst_cast[m]->positions () += this ->q_mat (m, j) * dt * this ->particles [j]->velocities ();
587+ dst_cast[m]->velocities () += this ->q_mat (m, j) * dt * this ->build_rhs (j);
588+ }
589+ dst_cast[m]->positions () += this ->start_particles ->positions () - this ->particles [m]->positions ();
590+ dst_cast[m]->velocities () += this ->start_particles ->velocities () - this ->particles [m]->velocities ();
591+ }
592+
593+ this ->log_indent ->decrement (8 );
594+ }
595+
583596 template <typename scalar, typename time>
584597 void BorisSweeper<scalar, time>::advance()
585598 {
@@ -805,7 +818,7 @@ namespace pfasst
805818 {
806819 UNUSED (comm); UNUSED (tag);
807820 // TODO: implement BorisSweeper::post
808- };
821+ }
809822
810823 template <typename scalar, typename time>
811824 void BorisSweeper<scalar, time>::send(ICommunicator* comm, int tag, bool blocking)
0 commit comments