20template <
unsigned Dim = 3>
23template <
typename T,
unsigned Dim = 3>
26template <
unsigned Dim = 3>
29template <
unsigned Dim = 3>
34template <
typename T,
unsigned Dim = 3>
37template <
typename T,
unsigned Dim = 3,
class... ViewArgs>
40template <
typename T =
double,
unsigned Dim = 3>
46template <
typename T,
unsigned Dim = 3>
49template <
unsigned Dim = 3,
class... ViewArgs>
52template <
typename T = double,
unsigned Dim = 3,
class... ViewArgs>
56template <
typename T =
double,
unsigned Dim = 3>
61template <
typename T =
double,
unsigned Dim = 3>
65template <
typename T =
double,
unsigned Dim = 3>
68template <
typename T =
double,
unsigned Dim = 3>
72template <
typename T =
double,
unsigned Dim = 3>
76const double pi = Kokkos::numbers::pi_v<double>;
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;
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;
123 std::stringstream fname;
125 fname << std::setw(4) << std::setfill(
'0') << iteration;
128 Kokkos::deep_copy(host_view, E.
getView());
132 vtkout.
setf(std::ios::scientific, std::ios::floatfield);
135 vtkout <<
"# vtk DataFile Version 2.0" <<
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;
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;
159 std::stringstream fname;
160 fname <<
"data/scalar_";
161 fname << std::setw(4) << std::setfill(
'0') << iteration;
164 Kokkos::deep_copy(host_view, rho.
getView());
168 vtkout.
setf(std::ios::scientific, std::ios::floatfield);
171 vtkout <<
"# vtk DataFile Version 2.0" <<
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;
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;
191template <
class PLayout,
typename T,
unsigned Dim = 3>
255 for (
unsigned int i = 0; i < 2 *
Dim; ++i) {
256 allPeriodic[i] = std::make_shared<ippl::PeriodicFace<Field<T, Dim>>>(i);
276 E_m.updateLayout(fl);
277 rho_m.updateLayout(fl);
285 layout.updateLayout(fl, mesh);
289 if (!isFirstRepartition) {
296 E_m.initialize(mesh, fl);
297 rho_m.initialize(mesh, fl);
299 phi_m.initialize(mesh, fl);
310 bool res =
orb.binaryRepartition(this->
R, fl, isFirstRepartition);
313 std::cout <<
"Could not repartition!" << std::endl;
318 if constexpr (
Dim == 2 ||
Dim == 3) {
322 if constexpr (
Dim == 3) {
325 }
else if (
stype_m ==
"OPEN") {
336 if (std::strcmp(
TestName,
"UniformPlasmaTest") == 0) {
341 double equalPart = (double)totalP /
ippl::Comm->size();
342 double dev = std::abs((
double)this->
getLocalNum() - equalPart) / totalP;
346 MPI_Allgather(&local, 1, MPI_INT, res.data(), 1, MPI_INT,
349 for (
unsigned int i = 0; i < res.size(); i++) {
360 double equalPart = (double)totalP /
ippl::Comm->size();
361 double dev = (std::abs((
double)this->
getLocalNum() - equalPart) / totalP) * 100.0;
365 std::stringstream fname;
366 fname <<
"data/LoadBalance_";
372 csvout.
setf(std::ios::scientific, std::ios::floatfield);
375 csvout <<
"time, rank, imbalance percentage" <<
endl;
378 for (
int r = 0; r <
ippl::Comm->size(); ++r) {
379 csvout <<
time_m <<
" " << r <<
" " << imb[r] <<
endl;
396 double Q_grid =
rho_m.sum();
401 ippl::Comm->reduce(local_particles, Total_particles, 1, std::plus<size_type>());
403 double rel_error = std::fabs((
Q_m - Q_grid) /
Q_m);
404 m <<
"Rel. error in charge conservation = " << rel_error <<
endl;
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;
417 std::reduce(hrField.
begin(), hrField.
end(), 1., std::multiplies<double>());
428 for (
unsigned d = 0; d <
Dim; d++) {
443 }
else if (
stype_m ==
"OPEN") {
446 m <<
"No solver matches the argument" <<
endl;
456 std::stringstream fname;
468 if (
time_m == 0 && iterations == 0) {
469 log <<
"time,residue,iterations" <<
endl;
472 if (
time_m > 0 || iterations > 0) {
478 if constexpr (
Dim == 2 ||
Dim == 3) {
482 if constexpr (
Dim == 3) {
485 }
else if (
stype_m ==
"OPEN") {
486 if constexpr (
Dim == 3) {
490 throw std::runtime_error(
"Unknown solver type");
494 template <
typename Solver>
496 solver_m.template emplace<Solver>();
499 solver.mergeParameters(sp);
501 solver.setRhs(
rho_m);
503 if constexpr (std::is_same_v<Solver, CGSolver_t<T, Dim>>) {
506 solver.setLhs(
phi_m);
507 solver.setGradient(
E_m);
520 sp.
add(
"tolerance", 1e-10);
521 std::string solver_type =
"";
523 solver_type =
"preconditioned";
524 ptype_m = sp.
get<std::string>(
"preconditioner_type");
526 sp.
add(
"solver", solver_type);
532 if constexpr (
Dim == 2 ||
Dim == 3) {
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);
540 sp.
add(
"r2c_direction", 0);
544 throw std::runtime_error(
"Unsupported dimensionality for FFT solver");
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);
557 sp.
add(
"r2c_direction", 0);
561 throw std::runtime_error(
"Unsupported dimensionality for TG solver");
566 if constexpr (
Dim == 3) {
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);
574 sp.
add(
"r2c_direction", 0);
579 throw std::runtime_error(
"Unsupported dimensionality for OPEN solver");
584 auto Pview =
P.getView();
586 double kinEnergy = 0.0;
587 double potEnergy = 0.0;
592 Kokkos::parallel_reduce(
594 KOKKOS_LAMBDA(
const int i,
double& valL) {
595 double myVal = dot(Pview(i), Pview(i)).apply();
598 Kokkos::Sum<double>(kinEnergy));
601 double gkinEnergy = 0.0;
603 ippl::Comm->reduce(kinEnergy, gkinEnergy, 1, std::plus<double>());
605 const int nghostE =
E_m.getNghost();
606 auto Eview =
E_m.getView();
610 for (
unsigned d = 0; d <
Dim; ++d) {
614 KOKKOS_LAMBDA(
const index_array_type& args,
T& valL) {
620 Kokkos::Sum<T>(temp));
622 ippl::Comm->reduce(temp, globaltemp, 1, std::plus<T>());
623 normE[d] = std::sqrt(globaltemp);
627 std::stringstream fname;
628 fname <<
"data/ParticleField_";
634 csvout.
setf(std::ios::scientific, std::ios::floatfield);
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";
644 csvout <<
time_m <<
" " << potEnergy <<
" " << gkinEnergy <<
" "
645 << potEnergy + gkinEnergy <<
" " <<
rhoNorm_m <<
" ";
646 for (
unsigned d = 0; d <
Dim; d++) {
647 csvout << normE[d] <<
" ";
656 auto Eview =
E_m.getHostMirror();
662 Kokkos::deep_copy(mirror,
E_m.getView());
667 template <
typename View>
669 const int nghostE =
E_m.getNghost();
672 double localEx2 = 0, localExNorm = 0;
675 KOKKOS_LAMBDA(
const index_array_type& args,
double& E2,
double& ENorm) {
679 double e2 = Kokkos::pow(val, 2);
682 double norm = Kokkos::fabs(
ippl::apply(Eview, args)[0]);
687 Kokkos::Sum<double>(localEx2), Kokkos::Max<double>(localExNorm));
689 double globaltemp = 0.0;
690 ippl::Comm->reduce(localEx2, globaltemp, 1, std::plus<double>());
692 std::reduce(
hr_m.begin(),
hr_m.end(), globaltemp, std::multiplies<double>());
695 ippl::Comm->reduce(localExNorm, ExAmp, 1, std::greater<double>());
698 std::stringstream fname;
699 fname <<
"data/FieldLandau_";
705 csvout.
setf(std::ios::scientific, std::ios::floatfield);
708 csvout <<
"time, Ex_field_energy, Ex_max_norm" <<
endl;
711 csvout <<
time_m <<
" " << fieldEnergy <<
" " << ExAmp <<
endl;
718 const int nghostE =
E_m.getNghost();
719 auto Eview =
E_m.getView();
720 double fieldEnergy, EzAmp;
726 KOKKOS_LAMBDA(
const index_array_type& args,
double& valL) {
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>());
737 double tempMax = 0.0;
740 KOKKOS_LAMBDA(
const index_array_type& args,
double& valL) {
748 Kokkos::Max<double>(tempMax));
750 ippl::Comm->reduce(tempMax, EzAmp, 1, std::greater<double>());
753 std::stringstream fname;
754 fname <<
"data/FieldBumponTail_";
760 csvout.
setf(std::ios::scientific, std::ios::floatfield);
763 csvout <<
"time, Ez_field_energy, Ez_max_norm" <<
endl;
766 csvout <<
time_m <<
" " << fieldEnergy <<
" " << EzAmp <<
endl;
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_";
783 pcsvout.
setf(std::ios::scientific, std::ios::floatfield);
784 pcsvout <<
"R_x, R_y, R_z, V_x, V_y, V_z" <<
endl;
786 for (
unsigned d = 0; d <
Dim; d++) {
787 pcsvout << R_host(i)[d] <<
" ";
789 for (
unsigned d = 0; d <
Dim; d++) {
790 pcsvout << P_host(i)[d] <<
" ";
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() <<
" ";
Field< Vector_t< T, Dim >, Dim, ViewArgs... > VField_t
Field< double, Dim, ViewArgs... > Field_t
ippl::ParticleAttrib< T > ParticleAttrib
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)
Field< Vector_t< T, Dim >, Dim, ViewArgs... > VField_t
ippl::detail::size_type size_type
Field< double, Dim, ViewArgs... > Field_t
VariantFromConditionalTypes< CGSolver_t< T, Dim >, FFTSolver_t< T, Dim >, FFTTruncatedGreenSolver_t< T, Dim >, OpenSolver_t< T, Dim >, NullSolver_t< T, Dim > > Solver_t
ippl::ParticleAttrib< T > ParticleAttrib
ippl::FieldLayout< Dim > FieldLayout_t
ippl::Vector< T, Dim > Vector_t
typename ippl::ParticleSpatialLayout< T, Dim, Mesh_t< Dim > > PLayout_t
ippl::Vector< T, Dim > Vector
ippl::OrthogonalRecursiveBisection< Field< double, Dim >, T > ORB
ConditionalType< Dim==3, ippl::FFTOpenPoissonSolver< VField_t< T, Dim >, Field_t< Dim > > > OpenSolver_t
typename Mesh_t< Dim >::DefaultCentering Centering_t
ippl::Field< T, Dim, Mesh_t< Dim >, Centering_t< Dim >, ViewArgs... > Field
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
ConditionalType< Dim==3, ippl::FFTTruncatedGreenPeriodicPoissonSolver< VField_t< T, Dim >, Field_t< Dim > > > FFTTruncatedGreenSolver_t
Inform & endl(Inform &inf)
KOKKOS_INLINE_FUNCTION auto & get(::ippl::Tuple< Ts... > &t)
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_reduce(const std::string &name, const ExecPolicy &policy, const FunctorType &functor, ReducerArgument &&... reducer)
std::unique_ptr< mpi::Communicator > Comm
typename ConstructVariant< std::variant< Types... >, std::variant<>, IsEnabled >::type VariantFromConditionalTypes
std::conditional_t< B, T, void > ConditionalType
HostMirror getHostMirror() const
typename view_type::host_mirror_type HostMirror
void updateLayout(Layout_t &, int nghost=1)
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)
detail::size_type size_type
typename PLayout::particle_position_type particle_position_type
size_type getLocalNum() const
KOKKOS_INLINE_FUNCTION constexpr iterator begin()
KOKKOS_INLINE_FUNCTION constexpr iterator end()
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
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)
void updateLayout(FieldLayout_t< Dim > &fl, Mesh_t< Dim > &mesh, bool &isFirstRepartition)
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)
Base::particle_position_type E
void initSolverWithParams(const ippl::ParameterList &sp)
Vector_t< double, Dim > rmin_m
Solver_t< T, Dim > solver_m
void registerAttributes()
Vector_t< double, Dim > rmax_m
double loadbalancethreshold_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())