IPPL (Independent Parallel Particle Layer)
IPPL
Loading...
Searching...
No Matches
ChargedParticles.hpp
Go to the documentation of this file.
1// ChargedParticles header file
2// Defines a particle attribute for charged particles to be used in
3// test programs
4//
5#include "Ippl.h"
6
7#include <csignal>
8#include <thread>
9
10#include "Utility/TypeUtils.h"
11
16
17unsigned LoggingPeriod = 1;
18
19// some typedefs
20template <unsigned Dim = 3>
22
23template <typename T, unsigned Dim = 3>
25
26template <unsigned Dim = 3>
28
29template <unsigned Dim = 3>
31
33
34template <typename T, unsigned Dim = 3>
36
37template <typename T, unsigned Dim = 3, class... ViewArgs>
39
40template <typename T = double, unsigned Dim = 3>
42
43template <typename T>
45
46template <typename T, unsigned Dim = 3>
48
49template <unsigned Dim = 3, class... ViewArgs>
50using Field_t = Field<double, Dim, ViewArgs...>;
51
52template <typename T = double, unsigned Dim = 3, class... ViewArgs>
53using VField_t = Field<Vector_t<T, Dim>, Dim, ViewArgs...>;
54
55// heFFTe does not support 1D FFTs, so we switch to CG in the 1D case
56template <typename T = double, unsigned Dim = 3>
58
60
61template <typename T = double, unsigned Dim = 3>
62using FFTSolver_t = ConditionalType<Dim == 2 || Dim == 3,
64
65template <typename T = double, unsigned Dim = 3>
67
68template <typename T = double, unsigned Dim = 3>
71
72template <typename T = double, unsigned Dim = 3>
75
76const double pi = Kokkos::numbers::pi_v<double>;
77
78// Test programs have to define this variable for VTK dump purposes
79extern const char* TestName;
80
81// Signal handling
83
88void interruptHandler(int signal) {
90}
91
97 ippl::Comm->barrier();
98 return interruptSignalReceived != 0;
99}
100
105 struct sigaction sa;
106 sa.sa_handler = interruptHandler;
107 sigemptyset(&sa.sa_mask);
108 if (sigaction(SIGTERM, &sa, NULL) == -1) {
109 std::cerr << ippl::Comm->rank() << ": failed to set up signal handler for SIGTERM ("
110 << SIGTERM << ")" << std::endl;
111 }
112 if (sigaction(SIGINT, &sa, NULL) == -1) {
113 std::cerr << ippl::Comm->rank() << ": failed to set up signal handler for SIGINT ("
114 << SIGINT << ")" << std::endl;
115 }
116}
117
118template <typename T>
119void dumpVTK(VField_t<T, 3>& E, int nx, int ny, int nz, int iteration, double dx, double dy,
120 double dz) {
122
123 std::stringstream fname;
124 fname << "data/ef_";
125 fname << std::setw(4) << std::setfill('0') << iteration;
126 fname << ".vtk";
127
128 Kokkos::deep_copy(host_view, E.getView());
129
130 Inform vtkout(NULL, fname.str().c_str(), Inform::OVERWRITE);
131 vtkout.precision(10);
132 vtkout.setf(std::ios::scientific, std::ios::floatfield);
133
134 // start with header
135 vtkout << "# vtk DataFile Version 2.0" << endl;
136 vtkout << TestName << endl;
137 vtkout << "ASCII" << endl;
138 vtkout << "DATASET STRUCTURED_POINTS" << endl;
139 vtkout << "DIMENSIONS " << nx + 3 << " " << ny + 3 << " " << nz + 3 << endl;
140 vtkout << "ORIGIN " << -dx << " " << -dy << " " << -dz << endl;
141 vtkout << "SPACING " << dx << " " << dy << " " << dz << endl;
142 vtkout << "CELL_DATA " << (nx + 2) * (ny + 2) * (nz + 2) << endl;
143
144 vtkout << "VECTORS E-Field float" << endl;
145 for (int z = 0; z < nz + 2; z++) {
146 for (int y = 0; y < ny + 2; y++) {
147 for (int x = 0; x < nx + 2; x++) {
148 vtkout << host_view(x, y, z)[0] << "\t" << host_view(x, y, z)[1] << "\t"
149 << host_view(x, y, z)[2] << endl;
150 }
151 }
152 }
153}
154
155void dumpVTK(Field_t<3>& rho, int nx, int ny, int nz, int iteration, double dx, double dy,
156 double dz) {
158
159 std::stringstream fname;
160 fname << "data/scalar_";
161 fname << std::setw(4) << std::setfill('0') << iteration;
162 fname << ".vtk";
163
164 Kokkos::deep_copy(host_view, rho.getView());
165
166 Inform vtkout(NULL, fname.str().c_str(), Inform::OVERWRITE);
167 vtkout.precision(10);
168 vtkout.setf(std::ios::scientific, std::ios::floatfield);
169
170 // start with header
171 vtkout << "# vtk DataFile Version 2.0" << endl;
172 vtkout << TestName << endl;
173 vtkout << "ASCII" << endl;
174 vtkout << "DATASET STRUCTURED_POINTS" << endl;
175 vtkout << "DIMENSIONS " << nx + 3 << " " << ny + 3 << " " << nz + 3 << endl;
176 vtkout << "ORIGIN " << -dx << " " << -dy << " " << -dz << endl;
177 vtkout << "SPACING " << dx << " " << dy << " " << dz << endl;
178 vtkout << "CELL_DATA " << (nx + 2) * (ny + 2) * (nz + 2) << endl;
179
180 vtkout << "SCALARS Rho float" << endl;
181 vtkout << "LOOKUP_TABLE default" << endl;
182 for (int z = 0; z < nz + 2; z++) {
183 for (int y = 0; y < ny + 2; y++) {
184 for (int x = 0; x < nx + 2; x++) {
185 vtkout << host_view(x, y, z) << endl;
186 }
187 }
188 }
189}
190
191template <class PLayout, typename T, unsigned Dim = 3>
192class ChargedParticles : public ippl::ParticleBase<PLayout> {
194
195public:
199
202
203 // ORB
205
207
211
212 std::string stype_m;
213 std::string ptype_m;
214
215 std::array<bool, Dim> isParallel_m;
216
217 double Q_m;
218
219private:
221
222public:
223 double time_m;
224
225 double rhoNorm_m;
226
227 unsigned int loadbalancefreq_m;
228
230
231public:
233 typename Base::particle_position_type P; // particle velocity
234 typename Base::particle_position_type E; // electric field at particle position
235
237 Vector_t<double, Dim> rmax, std::array<bool, Dim> isParallel, double Q,
238 std::string solver)
239 : Base(pl)
240 , hr_m(hr)
241 , rmin_m(rmin)
242 , rmax_m(rmax)
243 , stype_m(solver)
244 , isParallel_m(isParallel)
245 , Q_m(Q) {
247 setupBCs();
249 }
250
252 // CG requires explicit periodic boundary conditions while the periodic Poisson solver
253 // simply assumes them
254 if (stype_m == "CG" || stype_m == "PCG") {
255 for (unsigned int i = 0; i < 2 * Dim; ++i) {
256 allPeriodic[i] = std::make_shared<ippl::PeriodicFace<Field<T, Dim>>>(i);
257 }
258 }
259 }
260
262 // register the particle attributes
263 this->addAttribute(q);
264 this->addAttribute(P);
265 this->addAttribute(E);
266 }
267
269
271
272 void updateLayout(FieldLayout_t<Dim>& fl, Mesh_t<Dim>& mesh, bool& isFirstRepartition) {
273 // Update local fields
274 static IpplTimings::TimerRef tupdateLayout = IpplTimings::getTimer("updateLayout");
275 IpplTimings::startTimer(tupdateLayout);
276 E_m.updateLayout(fl);
277 rho_m.updateLayout(fl);
278 if (stype_m == "CG" || stype_m == "PCG") {
279 this->phi_m.updateLayout(fl);
280 phi_m.setFieldBC(allPeriodic);
281 }
282
283 // Update layout with new FieldLayout
284 PLayout& layout = this->getLayout();
285 layout.updateLayout(fl, mesh);
286 IpplTimings::stopTimer(tupdateLayout);
287 static IpplTimings::TimerRef tupdatePLayout = IpplTimings::getTimer("updatePB");
288 IpplTimings::startTimer(tupdatePLayout);
289 if (!isFirstRepartition) {
290 this->update();
291 }
292 IpplTimings::stopTimer(tupdatePLayout);
293 }
294
296 E_m.initialize(mesh, fl);
297 rho_m.initialize(mesh, fl);
298 if (stype_m == "CG" || stype_m == "PCG") {
299 phi_m.initialize(mesh, fl);
300 phi_m.setFieldBC(allPeriodic);
301 }
302 }
303
305 orb.initialize(fl, mesh, rho_m);
306 }
307
308 void repartition(FieldLayout_t<Dim>& fl, Mesh_t<Dim>& mesh, bool& isFirstRepartition) {
309 // Repartition the domains
310 bool res = orb.binaryRepartition(this->R, fl, isFirstRepartition);
311
312 if (res != true) {
313 std::cout << "Could not repartition!" << std::endl;
314 return;
315 }
316 // Update
317 this->updateLayout(fl, mesh, isFirstRepartition);
318 if constexpr (Dim == 2 || Dim == 3) {
319 if (stype_m == "FFT") {
321 }
322 if constexpr (Dim == 3) {
323 if (stype_m == "TG") {
325 } else if (stype_m == "OPEN") {
327 }
328 }
329 }
330 }
331
332 bool balance(size_type totalP, const unsigned int nstep) {
333 if (ippl::Comm->size() < 2) {
334 return false;
335 }
336 if (std::strcmp(TestName, "UniformPlasmaTest") == 0) {
337 return (nstep % loadbalancefreq_m == 0);
338 } else {
339 int local = 0;
340 std::vector<int> res(ippl::Comm->size());
341 double equalPart = (double)totalP / ippl::Comm->size();
342 double dev = std::abs((double)this->getLocalNum() - equalPart) / totalP;
343 if (dev > loadbalancethreshold_m) {
344 local = 1;
345 }
346 MPI_Allgather(&local, 1, MPI_INT, res.data(), 1, MPI_INT,
347 ippl::Comm->getCommunicator());
348
349 for (unsigned int i = 0; i < res.size(); i++) {
350 if (res[i] == 1) {
351 return true;
352 }
353 }
354 return false;
355 }
356 }
357
359 std::vector<double> imb(ippl::Comm->size());
360 double equalPart = (double)totalP / ippl::Comm->size();
361 double dev = (std::abs((double)this->getLocalNum() - equalPart) / totalP) * 100.0;
362 ippl::Comm->gather(&dev, imb.data(), 1);
363
364 if (ippl::Comm->rank() == 0) {
365 std::stringstream fname;
366 fname << "data/LoadBalance_";
367 fname << ippl::Comm->size();
368 fname << ".csv";
369
370 Inform csvout(NULL, fname.str().c_str(), Inform::APPEND);
371 csvout.precision(5);
372 csvout.setf(std::ios::scientific, std::ios::floatfield);
373
374 if (time_m == 0.0) {
375 csvout << "time, rank, imbalance percentage" << endl;
376 }
377
378 for (int r = 0; r < ippl::Comm->size(); ++r) {
379 csvout << time_m << " " << r << " " << imb[r] << endl;
380 }
381 }
382
383 ippl::Comm->barrier();
384 }
385
386 void gatherCIC() { gather(this->E, E_m, this->R); }
387
388 void scatterCIC(size_type totalP, unsigned int iteration, Vector_t<double, Dim>& hrField) {
389 Inform m("scatter ");
390
391 rho_m = 0.0;
392 scatter(q, rho_m, this->R);
393
394 static IpplTimings::TimerRef sumTimer = IpplTimings::getTimer("Check");
395 IpplTimings::startTimer(sumTimer);
396 double Q_grid = rho_m.sum();
397
398 size_type Total_particles = 0;
399 size_type local_particles = this->getLocalNum();
400
401 ippl::Comm->reduce(local_particles, Total_particles, 1, std::plus<size_type>());
402
403 double rel_error = std::fabs((Q_m - Q_grid) / Q_m);
404 m << "Rel. error in charge conservation = " << rel_error << endl;
405
406 if (ippl::Comm->rank() == 0) {
407 if (Total_particles != totalP || rel_error > 1e-10) {
408 m << "Time step: " << iteration << endl;
409 m << "Total particles in the sim. " << totalP << " "
410 << "after update: " << Total_particles << endl;
411 m << "Rel. error in charge conservation: " << rel_error << endl;
412 ippl::Comm->abort();
413 }
414 }
415
416 double cellVolume =
417 std::reduce(hrField.begin(), hrField.end(), 1., std::multiplies<double>());
418 rho_m = rho_m / cellVolume;
419
420 rhoNorm_m = norm(rho_m);
421 IpplTimings::stopTimer(sumTimer);
422
423 // dumpVTK(rho_m, nr_m[0], nr_m[1], nr_m[2], iteration, hrField[0], hrField[1], hrField[2]);
424
425 // rho = rho_e - rho_i (only if periodic BCs)
426 if (stype_m != "OPEN") {
427 double size = 1;
428 for (unsigned d = 0; d < Dim; d++) {
429 size *= rmax_m[d] - rmin_m[d];
430 }
431 rho_m = rho_m - (Q_m / size);
432 }
433 }
434
436 Inform m("solver ");
437 if (stype_m == "FFT") {
439 } else if (stype_m == "CG" || stype_m == "PCG") {
440 initCGSolver(sp);
441 } else if (stype_m == "TG") {
442 initTGSolver();
443 } else if (stype_m == "OPEN") {
445 } else {
446 m << "No solver matches the argument" << endl;
447 }
448 }
449
450 void runSolver() {
451 if (stype_m == "CG" || stype_m == "PCG") {
453 solver.solve();
454
455 if (ippl::Comm->rank() == 0) {
456 std::stringstream fname;
457 fname << "data/";
458 fname << stype_m << "_";
459 if (stype_m == "PCG") {
460 fname << ptype_m << "_";
461 }
462 fname << ippl::Comm->size();
463 fname << ".csv";
464
465 Inform log(NULL, fname.str().c_str(), Inform::APPEND);
466 int iterations = solver.getIterationCount();
467 // Assume the dummy solve is the first call
468 if (time_m == 0 && iterations == 0) {
469 log << "time,residue,iterations" << endl;
470 }
471 // Don't print the dummy solve
472 if (time_m > 0 || iterations > 0) {
473 log << time_m << "," << solver.getResidue() << "," << iterations << endl;
474 }
475 }
476 ippl::Comm->barrier();
477 } else if (stype_m == "FFT") {
478 if constexpr (Dim == 2 || Dim == 3) {
480 }
481 } else if (stype_m == "TG") {
482 if constexpr (Dim == 3) {
484 }
485 } else if (stype_m == "OPEN") {
486 if constexpr (Dim == 3) {
488 }
489 } else {
490 throw std::runtime_error("Unknown solver type");
491 }
492 }
493
494 template <typename Solver>
496 solver_m.template emplace<Solver>();
497 Solver& solver = std::get<Solver>(solver_m);
498
499 solver.mergeParameters(sp);
500
501 solver.setRhs(rho_m);
502
503 if constexpr (std::is_same_v<Solver, CGSolver_t<T, Dim>>) {
504 // The CG solver computes the potential directly and
505 // uses this to get the electric field
506 solver.setLhs(phi_m);
507 solver.setGradient(E_m);
508 } else {
509 // The periodic Poisson solver, Open boundaries solver,
510 // and the TG solver compute the electric field directly
511 solver.setLhs(E_m);
512 }
513 }
514
515 void initCGSolver(const ippl::ParameterList& sp_old) {
517 sp.merge(sp_old);
518 sp.add("output_type", CGSolver_t<T, Dim>::GRAD);
519 // Increase tolerance in the 1D case
520 sp.add("tolerance", 1e-10);
521 std::string solver_type = "";
522 if (stype_m == "PCG") {
523 solver_type = "preconditioned";
524 ptype_m = sp.get<std::string>("preconditioner_type");
525 }
526 sp.add("solver", solver_type);
527
529 }
530
532 if constexpr (Dim == 2 || Dim == 3) {
534 sp.add("output_type", FFTSolver_t<T, Dim>::GRAD);
535 sp.add("use_heffte_defaults", false);
536 sp.add("use_pencils", true);
537 sp.add("use_reorder", false);
538 sp.add("use_gpu_aware", true);
539 sp.add("comm", ippl::p2p_pl);
540 sp.add("r2c_direction", 0);
541
543 } else {
544 throw std::runtime_error("Unsupported dimensionality for FFT solver");
545 }
546 }
547
549 if constexpr (Dim == 3) {
552 sp.add("use_heffte_defaults", false);
553 sp.add("use_pencils", true);
554 sp.add("use_reorder", false);
555 sp.add("use_gpu_aware", true);
556 sp.add("comm", ippl::p2p_pl);
557 sp.add("r2c_direction", 0);
558
560 } else {
561 throw std::runtime_error("Unsupported dimensionality for TG solver");
562 }
563 }
564
566 if constexpr (Dim == 3) {
568 sp.add("output_type", OpenSolver_t<T, Dim>::GRAD);
569 sp.add("use_heffte_defaults", false);
570 sp.add("use_pencils", true);
571 sp.add("use_reorder", false);
572 sp.add("use_gpu_aware", true);
573 sp.add("comm", ippl::p2p_pl);
574 sp.add("r2c_direction", 0);
575 sp.add("algorithm", OpenSolver_t<T, Dim>::HOCKNEY);
576
578 } else {
579 throw std::runtime_error("Unsupported dimensionality for OPEN solver");
580 }
581 }
582
583 void dumpData() {
584 auto Pview = P.getView();
585
586 double kinEnergy = 0.0;
587 double potEnergy = 0.0;
588
589 rho_m = dot(E_m, E_m);
590 potEnergy = 0.5 * hr_m[0] * hr_m[1] * hr_m[2] * rho_m.sum();
591
592 Kokkos::parallel_reduce(
593 "Particle Kinetic Energy", this->getLocalNum(),
594 KOKKOS_LAMBDA(const int i, double& valL) {
595 double myVal = dot(Pview(i), Pview(i)).apply();
596 valL += myVal;
597 },
598 Kokkos::Sum<double>(kinEnergy));
599
600 kinEnergy *= 0.5;
601 double gkinEnergy = 0.0;
602
603 ippl::Comm->reduce(kinEnergy, gkinEnergy, 1, std::plus<double>());
604
605 const int nghostE = E_m.getNghost();
606 auto Eview = E_m.getView();
607 Vector_t<T, Dim> normE;
608
609 using index_array_type = typename ippl::RangePolicy<Dim>::index_array_type;
610 for (unsigned d = 0; d < Dim; ++d) {
611 T temp = 0.0;
613 "Vector E reduce", ippl::getRangePolicy(Eview, nghostE),
614 KOKKOS_LAMBDA(const index_array_type& args, T& valL) {
615 // ippl::apply accesses the view at the given indices and obtains a
616 // reference; see src/Expression/IpplOperations.h
617 T myVal = std::pow(ippl::apply(Eview, args)[d], 2);
618 valL += myVal;
619 },
620 Kokkos::Sum<T>(temp));
621 T globaltemp = 0.0;
622 ippl::Comm->reduce(temp, globaltemp, 1, std::plus<T>());
623 normE[d] = std::sqrt(globaltemp);
624 }
625
626 if (ippl::Comm->rank() == 0) {
627 std::stringstream fname;
628 fname << "data/ParticleField_";
629 fname << ippl::Comm->size();
630 fname << ".csv";
631
632 Inform csvout(NULL, fname.str().c_str(), Inform::APPEND);
633 csvout.precision(10);
634 csvout.setf(std::ios::scientific, std::ios::floatfield);
635
636 if (time_m == 0.0) {
637 csvout << "time, Potential energy, Kinetic energy, Total energy, Rho_norm2";
638 for (unsigned d = 0; d < Dim; d++) {
639 csvout << ", E" << static_cast<char>((Dim <= 3 ? 'x' : '1') + d) << "_norm2";
640 }
641 csvout << endl;
642 }
643
644 csvout << time_m << " " << potEnergy << " " << gkinEnergy << " "
645 << potEnergy + gkinEnergy << " " << rhoNorm_m << " ";
646 for (unsigned d = 0; d < Dim; d++) {
647 csvout << normE[d] << " ";
648 }
649 csvout << endl;
650 }
651
652 ippl::Comm->barrier();
653 }
654
656 auto Eview = E_m.getHostMirror();
657 updateEMirror(Eview);
658 return Eview;
659 }
660
661 void updateEMirror(typename VField_t<T, Dim>::HostMirror& mirror) const {
662 Kokkos::deep_copy(mirror, E_m.getView());
663 }
664
665 void dumpLandau() { dumpLandau(E_m.getView()); }
666
667 template <typename View>
668 void dumpLandau(const View& Eview) {
669 const int nghostE = E_m.getNghost();
670
671 using index_array_type = typename ippl::RangePolicy<Dim>::index_array_type;
672 double localEx2 = 0, localExNorm = 0;
674 "Ex stats", ippl::getRangePolicy(Eview, nghostE),
675 KOKKOS_LAMBDA(const index_array_type& args, double& E2, double& ENorm) {
676 // ippl::apply<unsigned> accesses the view at the given indices and obtains a
677 // reference; see src/Expression/IpplOperations.h
678 double val = ippl::apply(Eview, args)[0];
679 double e2 = Kokkos::pow(val, 2);
680 E2 += e2;
681
682 double norm = Kokkos::fabs(ippl::apply(Eview, args)[0]);
683 if (norm > ENorm) {
684 ENorm = norm;
685 }
686 },
687 Kokkos::Sum<double>(localEx2), Kokkos::Max<double>(localExNorm));
688
689 double globaltemp = 0.0;
690 ippl::Comm->reduce(localEx2, globaltemp, 1, std::plus<double>());
691 double fieldEnergy =
692 std::reduce(hr_m.begin(), hr_m.end(), globaltemp, std::multiplies<double>());
693
694 double ExAmp = 0.0;
695 ippl::Comm->reduce(localExNorm, ExAmp, 1, std::greater<double>());
696
697 if (ippl::Comm->rank() == 0) {
698 std::stringstream fname;
699 fname << "data/FieldLandau_";
700 fname << ippl::Comm->size();
701 fname << ".csv";
702
703 Inform csvout(NULL, fname.str().c_str(), Inform::APPEND);
704 csvout.precision(16);
705 csvout.setf(std::ios::scientific, std::ios::floatfield);
706
707 if (time_m == 0.0) {
708 csvout << "time, Ex_field_energy, Ex_max_norm" << endl;
709 }
710
711 csvout << time_m << " " << fieldEnergy << " " << ExAmp << endl;
712 }
713
714 ippl::Comm->barrier();
715 }
716
718 const int nghostE = E_m.getNghost();
719 auto Eview = E_m.getView();
720 double fieldEnergy, EzAmp;
721
722 using index_array_type = typename ippl::RangePolicy<Dim>::index_array_type;
723 double temp = 0.0;
725 "Ex inner product", ippl::getRangePolicy(Eview, nghostE),
726 KOKKOS_LAMBDA(const index_array_type& args, double& valL) {
727 // ippl::apply accesses the view at the given indices and obtains a
728 // reference; see src/Expression/IpplOperations.h
729 double myVal = std::pow(ippl::apply(Eview, args)[Dim - 1], 2);
730 valL += myVal;
731 },
732 Kokkos::Sum<double>(temp));
733 double globaltemp = 0.0;
734 ippl::Comm->reduce(temp, globaltemp, 1, std::plus<double>());
735 fieldEnergy = std::reduce(hr_m.begin(), hr_m.end(), globaltemp, std::multiplies<double>());
736
737 double tempMax = 0.0;
739 "Ex max norm", ippl::getRangePolicy(Eview, nghostE),
740 KOKKOS_LAMBDA(const index_array_type& args, double& valL) {
741 // ippl::apply accesses the view at the given indices and obtains a
742 // reference; see src/Expression/IpplOperations.h
743 double myVal = std::fabs(ippl::apply(Eview, args)[Dim - 1]);
744 if (myVal > valL) {
745 valL = myVal;
746 }
747 },
748 Kokkos::Max<double>(tempMax));
749 EzAmp = 0.0;
750 ippl::Comm->reduce(tempMax, EzAmp, 1, std::greater<double>());
751
752 if (ippl::Comm->rank() == 0) {
753 std::stringstream fname;
754 fname << "data/FieldBumponTail_";
755 fname << ippl::Comm->size();
756 fname << ".csv";
757
758 Inform csvout(NULL, fname.str().c_str(), Inform::APPEND);
759 csvout.precision(10);
760 csvout.setf(std::ios::scientific, std::ios::floatfield);
761
762 if (time_m == 0.0) {
763 csvout << "time, Ez_field_energy, Ez_max_norm" << endl;
764 }
765
766 csvout << time_m << " " << fieldEnergy << " " << EzAmp << endl;
767 }
768
769 ippl::Comm->barrier();
770 }
771
773 typename ParticleAttrib<Vector_t<T, Dim>>::HostMirror R_host = this->R.getHostMirror();
774 typename ParticleAttrib<Vector_t<T, Dim>>::HostMirror P_host = this->P.getHostMirror();
775 Kokkos::deep_copy(R_host, this->R.getView());
776 Kokkos::deep_copy(P_host, P.getView());
777 std::stringstream pname;
778 pname << "data/ParticleIC_";
779 pname << ippl::Comm->rank();
780 pname << ".csv";
781 Inform pcsvout(NULL, pname.str().c_str(), Inform::OVERWRITE, ippl::Comm->rank());
782 pcsvout.precision(10);
783 pcsvout.setf(std::ios::scientific, std::ios::floatfield);
784 pcsvout << "R_x, R_y, R_z, V_x, V_y, V_z" << endl;
785 for (size_type i = 0; i < this->getLocalNum(); i++) {
786 for (unsigned d = 0; d < Dim; d++) {
787 pcsvout << R_host(i)[d] << " ";
788 }
789 for (unsigned d = 0; d < Dim; d++) {
790 pcsvout << P_host(i)[d] << " ";
791 }
792 pcsvout << endl;
793 }
794 ippl::Comm->barrier();
795 }
796
797 void dumpLocalDomains(const FieldLayout_t<Dim>& fl, const unsigned int step) {
798 if (ippl::Comm->rank() == 0) {
799 const typename FieldLayout_t<Dim>::host_mirror_type domains = fl.getHostLocalDomains();
800 std::ofstream myfile;
801 myfile.open("data/domains" + std::to_string(step) + ".txt");
802 for (unsigned int i = 0; i < domains.size(); ++i) {
803 for (unsigned d = 0; d < Dim; d++) {
804 myfile << domains[i][d].first() << " " << domains[i][d].last() << " ";
805 }
806 myfile << "\n";
807 }
808 myfile.close();
809 }
810 ippl::Comm->barrier();
811 }
812
813private:
815};
Field< Vector_t< T, Dim >, Dim, ViewArgs... > VField_t
unsigned LoggingPeriod
const char * TestName
Field< double, Dim, ViewArgs... > Field_t
ippl::ParticleAttrib< T > ParticleAttrib
const double pi
VariantFromConditionalTypes< CGSolver_t< T, Dim >, FFTSolver_t< T, Dim >, FFTTruncatedGreenSolver_t< T, Dim >, OpenSolver_t< T, Dim > > Solver_t
bool checkSignalHandler()
ippl::FieldLayout< Dim > FieldLayout_t
ippl::Vector< T, Dim > Vector_t
ippl::OrthogonalRecursiveBisection< Field< double, Dim >, T > ORB
ConditionalType< Dim==3, ippl::FFTOpenPoissonSolver< VField_t< T, Dim >, Field_t< Dim > > > OpenSolver_t
void dumpVTK(VField_t< T, 3 > &E, int nx, int ny, int nz, int iteration, double dx, double dy, double dz)
ConditionalType< Dim==3, ippl::FFTTruncatedGreenPeriodicPoissonSolver< VField_t< T, Dim >, Field_t< Dim > > > FFTTruncatedGreenSolver_t
ippl::Field< T, Dim, Mesh_t< Dim >, Centering_t< Dim >, ViewArgs... > Field
int interruptSignalReceived
ippl::UniformCartesian< double, Dim > Mesh_t
ConditionalType< Dim==2||Dim==3, ippl::FFTPeriodicPoissonSolver< VField_t< T, Dim >, Field_t< Dim > > > FFTSolver_t
ippl::PoissonCG< Field< T, Dim >, Field_t< Dim > > CGSolver_t
void interruptHandler(int signal)
void setSignalHandler()
constexpr unsigned Dim
Field< Vector_t< T, Dim >, Dim, ViewArgs... > VField_t
Definition datatypes.h:44
ippl::detail::size_type size_type
Definition datatypes.h:23
const char * TestName
Field< double, Dim, ViewArgs... > Field_t
Definition datatypes.h:41
VariantFromConditionalTypes< CGSolver_t< T, Dim >, FFTSolver_t< T, Dim >, FFTTruncatedGreenSolver_t< T, Dim >, OpenSolver_t< T, Dim >, NullSolver_t< T, Dim > > Solver_t
Definition datatypes.h:68
ippl::ParticleAttrib< T > ParticleAttrib
Definition datatypes.h:35
ippl::FieldLayout< Dim > FieldLayout_t
Definition datatypes.h:21
ippl::Vector< T, Dim > Vector_t
Definition datatypes.h:38
typename ippl::ParticleSpatialLayout< T, Dim, Mesh_t< Dim > > PLayout_t
Definition datatypes.h:15
ippl::Vector< T, Dim > Vector
Definition datatypes.h:26
ippl::OrthogonalRecursiveBisection< Field< double, Dim >, T > ORB
Definition datatypes.h:32
ConditionalType< Dim==3, ippl::FFTOpenPoissonSolver< VField_t< T, Dim >, Field_t< Dim > > > OpenSolver_t
Definition datatypes.h:64
typename Mesh_t< Dim >::DefaultCentering Centering_t
Definition datatypes.h:18
ippl::Field< T, Dim, Mesh_t< Dim >, Centering_t< Dim >, ViewArgs... > Field
Definition datatypes.h:29
ippl::UniformCartesian< double, Dim > Mesh_t
Definition datatypes.h:12
ConditionalType< Dim==2||Dim==3, ippl::FFTPeriodicPoissonSolver< VField_t< T, Dim >, Field_t< Dim > > > FFTSolver_t
Definition datatypes.h:55
ippl::PoissonCG< Field< T, Dim >, Field_t< Dim > > CGSolver_t
Definition datatypes.h:47
ConditionalType< Dim==3, ippl::FFTTruncatedGreenPeriodicPoissonSolver< VField_t< T, Dim >, Field_t< Dim > > > FFTTruncatedGreenSolver_t
Definition datatypes.h:59
Inform & endl(Inform &inf)
Definition Inform.cpp:42
KOKKOS_INLINE_FUNCTION auto & get(::ippl::Tuple< Ts... > &t)
Definition Tuple.h:362
@ p2p_pl
Definition FFT.h:59
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)
@ PERIODIC
Definition ParticleBC.h:12
void parallel_reduce(const std::string &name, const ExecPolicy &policy, const FunctorType &functor, ReducerArgument &&... reducer)
std::unique_ptr< mpi::Communicator > Comm
Definition Ippl.h:22
typename ConstructVariant< std::variant< Types... >, std::variant<>, IsEnabled >::type VariantFromConditionalTypes
Definition TypeUtils.h:146
std::conditional_t< B, T, void > ConditionalType
Definition TypeUtils.h:56
std::size_t size_type
Definition IpplTypes.h:13
void updateLayout(Layout_t &, int nghost=1)
Definition Field.hpp:71
typename view_type::host_mirror_type host_mirror_type
const host_mirror_type getHostLocalDomains() const
void setParticleBC(const bc_container_type &bcs)
void addAttribute(detail::ParticleAttribBase< MemorySpace > &pa)
typename PLayout::particle_position_type particle_position_type
particle_position_type R
size_type getLocalNum() const
int getIterationCount()
Definition PoissonCG.h:139
void solve() override
Definition PoissonCG.h:123
Tlhs getResidue() const
Definition PoissonCG.h:145
KOKKOS_INLINE_FUNCTION constexpr iterator begin()
Definition Vector.hpp:160
KOKKOS_INLINE_FUNCTION constexpr iterator end()
Definition Vector.hpp:165
@ APPEND
Definition Inform.h:45
@ OVERWRITE
Definition Inform.h:44
FmtFlags_t setf(FmtFlags_t setbits, FmtFlags_t field)
Definition Inform.h:101
int precision() const
Definition Inform.h:111
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
T get(const std::string &key) const
void merge(const ParameterList &p) noexcept
void add(const std::string &key, const T &value)
void repartition(FieldLayout_t< Dim > &fl, Mesh_t< Dim > &mesh, bool &isFirstRepartition)
std::array< bool, Dim > isParallel_m
ChargedParticles(PLayout &pl, Vector_t< double, Dim > hr, Vector_t< double, Dim > rmin, Vector_t< double, Dim > rmax, std::array< bool, Dim > isParallel, double Q, std::string solver)
void dumpLandau(const View &Eview)
Vector_t< T, Dim > nr_m
void updateLayout(FieldLayout_t< Dim > &fl, Mesh_t< Dim > &mesh, bool &isFirstRepartition)
Field< T, Dim > phi_m
void initCGSolver(const ippl::ParameterList &sp_old)
unsigned int loadbalancefreq_m
bool balance(size_type totalP, const unsigned int nstep)
void initializeORB(FieldLayout_t< Dim > &fl, Mesh_t< Dim > &mesh)
void updateEMirror(typename VField_t< T, Dim >::HostMirror &mirror) const
ippl::ParticleBase< PLayout > Base
void dumpLocalDomains(const FieldLayout_t< Dim > &fl, const unsigned int step)
void scatterCIC(size_type totalP, unsigned int iteration, Vector_t< double, Dim > &hrField)
VField_t< T, Dim > E_m
Base::particle_position_type E
void initSolverWithParams(const ippl::ParameterList &sp)
Vector_t< double, Dim > rmin_m
Solver_t< T, Dim > solver_m
Vector_t< double, Dim > rmax_m
Base::particle_position_type P
Vector_t< double, Dim > hr_m
void gatherStatistics(size_type totalP)
VField_t< T, Dim >::HostMirror getEMirror() const
ippl::BConds< Field< T, Dim >, Dim > bc_type
void initializeFields(Mesh_t< Dim > &mesh, FieldLayout_t< Dim > &fl)
ParticleAttrib< double > q
void initSolver(const ippl::ParameterList &sp=ippl::ParameterList())