148int main(
int argc,
char* argv[]) {
153 Inform msg(
"LandauDamping");
156 auto start = std::chrono::high_resolution_clock::now();
161 for (
unsigned d = 0; d <
Dim; d++) {
162 nr[d] = std::atoi(argv[arg++]);
177 const size_type totalP = std::atoll(argv[arg++]);
178 const unsigned int nt = std::atoi(argv[arg++]);
180 msg <<
"Landau damping" <<
endl
181 <<
"nt " << nt <<
" Np= " << totalP <<
" grid = " << nr <<
endl;
185 std::unique_ptr<bunch_type> P;
188 for (
unsigned i = 0; i <
Dim; i++) {
192 std::array<bool, Dim> isParallel;
193 isParallel.fill(
true);
203 double Q = std::reduce(rmax.
begin(), rmax.
end(), -1., std::multiplies<double>());
205 const double dt = std::min(.05, 0.5 * *std::min_element(hr.
begin(), hr.
end()));
207 const bool isAllPeriodic =
true;
212 std::string solver = argv[arg++];
214 int gauss_seidel_inner_iterations;
215 int gauss_seidel_outer_iterations;
217 int chebyshev_degree;
218 int richardson_iterations;
221 std::string preconditioner_type =
"";
223 if (solver ==
"OPEN") {
225 "Open boundaries solver incompatible with this simulation!");
228 if (solver ==
"PCG") {
229 preconditioner_type = argv[arg++];
230 if (preconditioner_type ==
"newton") {
231 newton_level = std::atoi(argv[arg++]);
232 }
else if (preconditioner_type ==
"chebyshev") {
233 chebyshev_degree = std::atoi(argv[arg++]);
234 }
else if (preconditioner_type ==
"richardson") {
235 richardson_iterations = std::atoi(argv[arg++]);
236 communication = std::atoi(argv[arg++]);
237 }
else if (preconditioner_type ==
"gauss-seidel") {
238 gauss_seidel_inner_iterations = std::atoi(argv[arg++]);
239 gauss_seidel_outer_iterations = std::atoi(argv[arg++]);
240 communication = std::atoi(argv[arg++]);
241 }
else if (preconditioner_type ==
"ssor") {
242 gauss_seidel_inner_iterations = std::atoi(argv[arg++]);
243 gauss_seidel_outer_iterations = std::atoi(argv[arg++]);
244 ssor_omega = std::stod(argv[arg++]);
247 params.
add(
"preconditioner_type", preconditioner_type);
248 params.
add(
"gauss_seidel_inner_iterations", gauss_seidel_inner_iterations);
249 params.
add(
"gauss_seidel_outer_iterations", gauss_seidel_outer_iterations);
250 params.
add(
"newton_level", newton_level);
251 params.
add(
"chebyshev_degree", chebyshev_degree);
252 params.
add(
"richardson_iterations", richardson_iterations);
253 params.
add(
"communication", communication);
254 params.
add(
"ssor_omega", ssor_omega);
257 P = std::make_unique<bunch_type>(PL, hr, rmin, rmax, isParallel, Q, solver);
262 P->initializeFields(mesh, FL);
264 P->initSolver(params);
266 P->loadbalancethreshold_m = std::atof(argv[arg++]);
268 bool isFirstRepartition;
270 if ((P->loadbalancethreshold_m != 1.0) && (
ippl::Comm->size() > 1)) {
271 msg <<
"Starting first repartition" <<
endl;
273 isFirstRepartition =
true;
275 const int nghost = P->rho_m.getNghost();
276 auto rhoview = P->rho_m.getView();
280 "Assign initial rho based on PDF", P->rho_m.getFieldRangePolicy(),
281 KOKKOS_LAMBDA(
const index_array_type& args) {
292 P->initializeORB(FL, mesh);
293 P->repartition(FL, mesh, isFirstRepartition);
297 msg <<
"First domain decomposition done" <<
endl;
301 const RegionLayout_t& RLayout = PL.getRegionLayout();
302 const typename RegionLayout_t::host_mirror_type Regions = RLayout.
gethLocalRegions();
306 for (
unsigned d = 0; d <
Dim; ++d) {
307 Nr[d] =
CDF(Regions(myRank)[d].max(), alpha, kw[d])
308 -
CDF(Regions(myRank)[d].min(), alpha, kw[d]);
309 Dr[d] =
CDF(rmax[d], alpha, kw[d]) -
CDF(rmin[d], alpha, kw[d]);
310 minU[d] =
CDF(Regions(myRank)[d].min(), alpha, kw[d]);
311 maxU[d] =
CDF(Regions(myRank)[d].max(), alpha, kw[d]);
312 factor *= Nr[d] / Dr[d];
318 MPI_Allreduce(&nloc, &Total_particles, 1, MPI_UNSIGNED_LONG, MPI_SUM,
321 int rest = (int)(totalP - Total_particles);
329 Kokkos::parallel_for(
331 P->R.getView(), P->P.getView(), rand_pool64, alpha, kw, minU, maxU));
337 P->q = P->Q_m / totalP;
338 msg <<
"particles created and initial conditions assigned " <<
endl;
339 isFirstRepartition =
false;
348 P->scatterCIC(totalP, 0, hr);
358 P->gatherStatistics(totalP);
363 msg <<
"Starting iterations ..." <<
endl;
364 for (
unsigned int it = 0; it < nt; it++) {
372 P->P = P->P - 0.5 * dt * P->E;
377 P->R = P->R + dt * P->P;
387 if (P->balance(totalP, it + 1)) {
388 msg <<
"Starting repartition" <<
endl;
390 P->repartition(FL, mesh, isFirstRepartition);
398 P->scatterCIC(totalP, it + 1, hr);
410 P->P = P->P - 0.5 * dt * P->E;
416 P->gatherStatistics(totalP);
418 msg <<
"Finished time step: " << it + 1 <<
" time: " << P->time_m <<
endl;
427 msg <<
"LandauDamping: End." <<
endl;
431 auto end = std::chrono::high_resolution_clock::now();
433 std::chrono::duration<double> time_chrono =
434 std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
435 std::cout <<
"Elapsed time: " << time_chrono.count() << std::endl;