1#ifndef IPPL_PENNING_TRAP_MANAGER_H
2#define IPPL_PENNING_TRAP_MANAGER_H
19template <
typename T,
unsigned Dim>
28 std::string& solver_, std::string& stepMethod_)
32 std::string& solver_, std::string& stepMethod_,
33 std::vector<std::string> preconditioner_params_)
35 preconditioner_params_) {}
50 for (
unsigned i = 0; i <
Dim; i++) {
72 this->alpha_m = -0.5 * this->
dt_m;
73 DrInv_m = 1.0 / (1 + (std::pow((this->alpha_m *
Bext_m), 2)));
75 m <<
"Discretization:" <<
endl
85 this->
fcontainer_m->getMesh(), this->fcontainer_m->getFL()));
92 &this->fcontainer_m->getPhi(), this->preconditioner_params_m));
96 &this->fcontainer_m->getPhi()));
132 Inform m(
"Initialize Particles");
137 for (
unsigned d = 0; d <
Dim; d++) {
145 double parR[2 *
Dim];
146 for (
unsigned int i = 0; i <
Dim; i++) {
148 parR[i * 2 + 1] = sd[i];
156 m <<
"Starting first repartition" <<
endl;
160 const int nghost = this->
fcontainer_m->getRho().getNghost();
165 "Assign initial rho based on PDF",
167 KOKKOS_LAMBDA(
const index_array_type& args) {
173 ippl::apply(rhoview, args) = distR.getFullPdf(xvec);
192 Kokkos::Random_XorShift64_Pool<> rand_pool64((
size_type)(seed + 100 *
ippl::Comm->rank()));
199 samplingR_t samplingR(distR, rmax, rmin, rlayout, totalP);
200 size_type nlocal = samplingR.getLocalSamplesNum();
205 samplingR.generate(*R, rand_pool64);
209 double muP[
Dim] = {0.0, 0.0, 0.0};
210 double sdP[
Dim] = {1.0, 1.0, 1.0};
219 m <<
"particles created and initial conditions assigned " <<
endl;
241 double alpha = this->alpha_m;
242 double Bext = this->Bext_m;
243 double DrInv = this->DrInv_m;
244 double V0 = 30 * this->length_m[2];
247 double dt = this->
dt_m;
248 std::shared_ptr<ParticleContainer_t> pc = this->
pcontainer_m;
249 std::shared_ptr<FieldContainer_t> fc = this->
fcontainer_m;
252 auto Rview = pc->R.getView();
253 auto Pview = pc->P.getView();
254 auto Eview = pc->E.getView();
255 Kokkos::parallel_for(
256 "Kick1", pc->getLocalNum(), KOKKOS_LAMBDA(
const size_t j) {
257 double Eext_x = -(Rview(j)[0] - origin[0] - 0.5 * length[0])
258 * (V0 / (2 * Kokkos::pow(length[2], 2)));
259 double Eext_y = -(Rview(j)[1] - origin[1] - 0.5 * length[1])
260 * (V0 / (2 * Kokkos::pow(length[2], 2)));
261 double Eext_z = (Rview(j)[2] - origin[2] - 0.5 * length[2])
262 * (V0 / (Kokkos::pow(length[2], 2)));
264 Eext_x += Eview(j)[0];
265 Eext_y += Eview(j)[1];
266 Eext_z += Eview(j)[2];
268 Pview(j)[0] += alpha * (Eext_x + Pview(j)[1] * Bext);
269 Pview(j)[1] += alpha * (Eext_y - Pview(j)[0] * Bext);
270 Pview(j)[2] += alpha * Eext_z;
278 pc->R = pc->R + dt * pc->P;
288 bool isFirstRepartition =
false;
291 auto* mesh = &fc->getRho().get_mesh();
292 auto* FL = &fc->getFL();
309 auto R2view = pc->R.getView();
310 auto P2view = pc->P.getView();
311 auto E2view = pc->E.getView();
312 Kokkos::parallel_for(
313 "Kick2", pc->getLocalNum(), KOKKOS_LAMBDA(
const size_t j) {
314 double Eext_x = -(R2view(j)[0] - origin[0] - 0.5 * length[0])
315 * (V0 / (2 * Kokkos::pow(length[2], 2)));
316 double Eext_y = -(R2view(j)[1] - origin[1] - 0.5 * length[1])
317 * (V0 / (2 * Kokkos::pow(length[2], 2)));
318 double Eext_z = (R2view(j)[2] - origin[2] - 0.5 * length[2])
319 * (V0 / (Kokkos::pow(length[2], 2)));
321 Eext_x += E2view(j)[0];
322 Eext_y += E2view(j)[1];
323 Eext_z += E2view(j)[2];
327 + alpha * (Eext_x + P2view(j)[1] * Bext + alpha * Bext * Eext_y));
330 + alpha * (Eext_y - P2view(j)[0] * Bext - alpha * Bext * Eext_x));
331 P2view(j)[2] += alpha * Eext_z;
347 double kinEnergy = 0.0;
348 double potEnergy = 0.0;
350 potEnergy = 0.5 * this->
hr_m[0] * this->
hr_m[1] * this->
hr_m[2]
353 Kokkos::parallel_reduce(
354 "Particle Kinetic Energy", this->
pcontainer_m->getLocalNum(),
355 KOKKOS_LAMBDA(
const int i,
double& valL) {
356 double myVal = dot(Pview(i), Pview(i)).apply();
359 Kokkos::Sum<double>(kinEnergy));
362 double gkinEnergy = 0.0;
364 ippl::Comm->reduce(kinEnergy, gkinEnergy, 1, std::plus<double>());
366 const int nghostE = this->
fcontainer_m->getE().getNghost();
371 for (
unsigned d = 0; d <
Dim; ++d) {
375 KOKKOS_LAMBDA(
const index_array_type& args,
T& valL) {
381 Kokkos::Sum<T>(temp));
384 ippl::Comm->reduce(temp, globaltemp, 1, std::plus<double>());
386 normE[d] = std::sqrt(globaltemp);
391 std::stringstream fname;
392 fname <<
"data/ParticleField_";
399 csvout.
setf(std::ios::scientific, std::ios::floatfield);
401 if (std::fabs(this->
time_m) < 1e-14) {
402 csvout <<
"time, Potential energy, Kinetic energy, Total energy, Rho_norm2";
403 for (
unsigned d = 0; d <
Dim; d++) {
404 csvout <<
", E" <<
static_cast<char>((
Dim <= 3 ?
'x' :
'1') + d) <<
"_norm2";
409 csvout << this->
time_m <<
" " << potEnergy <<
" " << gkinEnergy <<
" "
410 << potEnergy + gkinEnergy <<
" " << this->
rhoNorm_m <<
" ";
411 for (
unsigned d = 0; d <
Dim; d++) {
412 csvout << normE[d] <<
" ";
typename ippl::detail::ViewType< ippl::Vector< double, Dim >, 1 >::view_type view_type
typename ippl::detail::ViewType< ippl::Vector< double, Dim >, 1 >::view_type view_type
ippl::detail::size_type size_type
ippl::Vector< T, Dim > Vector_t
Inform & endl(Inform &inf)
KOKKOS_INLINE_FUNCTION constexpr decltype(auto) apply(const View &view, const Coords &coords)
RangePolicy< View::rank, typenameView::execution_space, PolicyArgs... >::policy_type getRangePolicy(const View &view, int shift=0)
void parallel_for(const std::string &name, const ExecPolicy &policy, const FunctorType &functor)
void parallel_reduce(const std::string &name, const ExecPolicy &policy, const FunctorType &functor, ReducerArgument &&... reducer)
std::unique_ptr< mpi::Communicator > Comm
KOKKOS_INLINE_FUNCTION Vector< int, Dim > first() const
void setFieldSolver(std::shared_ptr< ippl::FieldSolverBase< T, Dim > > fsolver)
std::shared_ptr< ParticleContainer< T, Dim > > pcontainer_m
void setParticleContainer(std::shared_ptr< ParticleContainer< T, Dim > > pcontainer)
std::shared_ptr< ippl::FieldSolverBase< T, Dim > > fsolver_m
void setLoadBalancer(std::shared_ptr< LoadBalancer< T, Dim > > loadbalancer)
std::shared_ptr< FieldContainer< T, Dim > > fcontainer_m
std::shared_ptr< LoadBalancer< T, Dim > > loadbalancer_m
void setFieldContainer(std::shared_ptr< FieldContainer< T, Dim > > fcontainer)
A class for inverse transform sampling.
Functor to generate random numbers from a normal distribution.
FmtFlags_t setf(FmtFlags_t setbits, FmtFlags_t field)
Timing::TimerRef TimerRef
static TimerRef getTimer(const char *nm)
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)
::ippl::Vector< index_type, Dim > index_array_type
void par2grid() override
Particle-to-grid operation.
Vector_t< double, Dim > origin_m
ippl::NDIndex< Dim > domain_m
Vector_t< int, Dim > nr_m
Vector_t< double, Dim > hr_m
Vector_t< double, Dim > rmin_m
const std::string & getSolver() const
bool isFirstRepartition_m
std::array< bool, Dim > decomp_m
Vector_t< double, Dim > rmax_m
AlpineManager(size_type totalP_, int nt_, Vector_t< int, Dim > &nr_, double lbt_, std::string &solver_, std::string &stepMethod_, std::vector< std::string > preconditioner_params={})
void grid2par() override
Grid-to-particle operation.
PenningTrapManager(size_type totalP_, int nt_, Vector_t< int, Dim > &nr_, double lbt_, std::string &solver_, std::string &stepMethod_)
FieldContainer< T, Dim > FieldContainer_t
ParticleContainer< T, Dim > ParticleContainer_t
void pre_run() override
A method that should be used for setting up the simulation.
LoadBalancer< T, Dim > LoadBalancer_t
PenningTrapManager(size_type totalP_, int nt_, Vector_t< int, Dim > &nr_, double lbt_, std::string &solver_, std::string &stepMethod_, std::vector< std::string > preconditioner_params_)
void advance() override
A method that should be used to execute/advance a step of simulation.
FieldSolver< T, Dim > FieldSolver_t
Vector_t< double, Dim > length_m
void initializeParticles()