PFASST++
boris_pfasst.cpp
Go to the documentation of this file.
1 #include <memory>
2 
3 #include <pfasst.hpp>
4 #include <pfasst/config.hpp>
5 #include <pfasst/logging.hpp>
8 using namespace pfasst;
9 
10 #include "particle.hpp"
11 #include "particle_cloud.hpp"
14 #include "boris_sweeper.hpp"
15 #include "injective_transfer.hpp"
16 
17 
18 namespace pfasst
19 {
20  namespace examples
21  {
22  namespace boris
23  {
24  template<typename scalar>
25  error_map<scalar> run_boris_pfasst(const size_t nsteps, const scalar dt, const size_t nnodes,
26  const size_t nparticles, const size_t niters,
27  const double abs_res_tol, const double rel_res_tol)
28  {
29  PFASST<> controller;
30  mpi::MPICommunicator comm(MPI_COMM_WORLD);
31  controller.set_comm(&comm);
32 
33  const double mass = 1.0;
34  const double charge = 1.0;
35 
36  shared_ptr<bindings::WrapperInterface<double, double>> impl_solver = \
37  make_shared<bindings::WrapperSimplePhysicsSolver<double, double>>();
39 
40  // fine level
41  auto quad1 = quadrature::quadrature_factory<double>(nnodes,
43  auto factory1 = make_shared<ParticleCloudFactory<double>>(nparticles, 3, mass, charge);
44  string data_file1 = "s" + to_string(nsteps) + "_i" + to_string(niters)
45  + "_dt" + to_string(dt) + "_m" + to_string(nnodes)
46  + "_p" + to_string(nparticles) + "_level1.csv";
47  auto sweeper1 = make_shared<BorisSweeper<double, double>>(impl_solver, data_file1);
48  auto transfer1 = make_shared<InjectiveTransfer<double, double>>();
49  sweeper1->set_quadrature(quad1);
50  sweeper1->set_factory(factory1);
51  sweeper1->set_residual_tolerances(abs_res_tol, rel_res_tol);
52  controller.add_level(sweeper1, transfer1);
53 
54  // coarse level
55  auto quad2 = quadrature::quadrature_factory<double>(nnodes,
57  auto factory2 = make_shared<ParticleCloudFactory<double>>(nparticles, 3, mass, charge);
58  string data_file2 = "s" + to_string(nsteps) + "_i" + to_string(niters)
59  + "_dt" + to_string(dt) + "_m" + to_string(nnodes)
60  + "_p" + to_string(nparticles) + "_level2.csv";
61  auto sweeper2 = make_shared<BorisSweeper<double, double>>(impl_solver, data_file2);
62  auto transfer2 = make_shared<InjectiveTransfer<double, double>>();
63  sweeper2->set_quadrature(quad2);
64  sweeper2->set_factory(factory2);
65  controller.add_level(sweeper2, transfer2);
66 
67  controller.set_duration(0.0, nsteps*dt, dt, niters);
68  controller.set_options();
69  controller.setup();
70 
71  shared_ptr<Particle<double>> center = make_shared<Particle<double>>();
72  center->pos()[0] = 10;
73  center->vel()[0] = 100;
74  center->vel()[2] = 100;
75 
76  auto fine_sweeper = controller.get_finest<BorisSweeper<double, double>>();
77  shared_ptr<ParticleCloud<double>> q0 = \
78  dynamic_pointer_cast<ParticleCloud<double>>(fine_sweeper->get_start_state());
79  q0->distribute_around_center(center);
80  ML_CLOG(INFO, "Boris", "Initial Particle (fine) : "
81  << *(dynamic_pointer_cast<ParticleCloud<double>>(fine_sweeper->get_start_state())));
82  fine_sweeper->set_initial_energy();
83 
84  controller.run();
85 
86  return fine_sweeper->get_errors();
87  }
88  } // ::pfasst::examples::boris
89  } // ::pfasst::examples
90 } // ::pfasst
91 
92 #ifndef PFASST_UNIT_TESTING
93 int main(int argc, char** argv)
94 {
95  MPI_Init(&argc, &argv);
96  pfasst::init(argc, argv,
97  pfasst::examples::boris::init_opts<>,
98  pfasst::examples::boris::init_logs<>);
99 
100  const size_t nsteps = pfasst::config::get_value<size_t>("num_steps", 1);
101  const double dt = pfasst::config::get_value<double>("delta_step", 0.015625);
102  const size_t nnodes = pfasst::config::get_value<size_t>("num_nodes", 5);
103  const size_t nparticles = pfasst::config::get_value<size_t>("num_particles", 1);
104  const size_t niters = pfasst::config::get_value<size_t>("num_iter", 2);
105  const double abs_res_tol = pfasst::config::get_value<double>("abs_res_tol", 0.0);
106  const double rel_res_tol = pfasst::config::get_value<double>("rel_res_tol", 0.0);
107 
108  ML_CLOG(INFO, "Boris", "nsteps=" << nsteps << ", "
109  << "dt=" << dt << ", "
110  << "nnodes=" << nnodes << ", "
111  << "nparticles=" << nparticles << ", "
112  << "niter=" << niters << ", "
113  << "abs res=" << abs_res_tol << ", "
114  << "rel res=" << rel_res_tol);
115 
116  pfasst::examples::boris::run_boris_pfasst<double>(nsteps, dt, nnodes, nparticles, niters, abs_res_tol, rel_res_tol);
117  MPI_Finalize();
118 }
119 #endif
int main(int argc, char **argv)
map< error_index, ErrorTuple< scalar >> error_map
void setup(shared_ptr< WrapperInterface< scalar, time >> wrapper)
virtual void set_options(bool all_sweepers=true)
Set options from command line etc.
virtual void add_level(shared_ptr< ISweeper< time >> sweeper, shared_ptr< ITransfer< time >> transfer=shared_ptr< ITransfer< time >>(nullptr), bool coarse=true)
Adding a level to the controller.
#define ML_CLOG(level, logger_id, x)
same as CLOG(level, logger, x) from easylogging++
Definition: logging.hpp:117
Implementation of the PFASST algorithm as described in .
Definition: pfasst.hpp:19
static void init(int argc, char **argv, std::function< void()> opts=nullptr, std::function< void()> logs=nullptr)
Definition: pfasst.hpp:13
virtual void set_duration(time t0, time tend, time dt, size_t niters)
Set basic time scope of the Controller.
virtual void setup() override
Basic setup routine for this controller.
Definition: mlsdc_impl.hpp:45
shared_ptr< R > get_finest()
Get coarsest level.
Definition: interface.hpp:163
virtual void set_comm(ICommunicator *comm)
Set communicator.
Definition: pfasst_impl.hpp:30
error_map< scalar > run_boris_pfasst(const size_t nsteps, const scalar dt, const size_t nnodes, const size_t nparticles, const size_t niters, const double abs_res_tol, const double rel_res_tol)
virtual void run() override
Solve ODE using PFASST.
Definition: pfasst_impl.hpp:40
float dt
Definition: plot.py:10