Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open Boundaries #666

Merged
merged 73 commits into from
Apr 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
662947f
field boundary change and less kernel launches
AlexanderSinn Nov 24, 2021
c61f4f8
fix doc
AlexanderSinn Nov 24, 2021
1b44ecd
fix tiling
AlexanderSinn Nov 25, 2021
5b9dd1c
change box sizes again
AlexanderSinn Nov 29, 2021
741c2e6
fix conversion and some cleaning
AlexanderSinn Nov 29, 2021
6a62d50
test tests
AlexanderSinn Nov 29, 2021
755252e
more fixes and decrease B mixing factor
AlexanderSinn Dec 5, 2021
7997b27
fix output slicing
AlexanderSinn Dec 5, 2021
8466220
fix? mesh refinement
AlexanderSinn Dec 9, 2021
fc7fccd
shrink fft back to original size
AlexanderSinn Dec 9, 2021
7281c99
add FillBoundary back in
AlexanderSinn Dec 9, 2021
272b402
put error back to pass tests
AlexanderSinn Dec 9, 2021
8a13ccf
slightly change box
AlexanderSinn Dec 9, 2021
99875d8
add header doc
AlexanderSinn Dec 11, 2021
244955c
fix header doc
AlexanderSinn Dec 11, 2021
fc392b5
add doc in Fields.cpp
AlexanderSinn Dec 11, 2021
79a5f19
add changes ROCm FFT as well
AlexanderSinn Dec 11, 2021
e4afa2d
remove ghost cell output feature
AlexanderSinn Dec 13, 2021
3ecb1a4
update FFTPoissonSolverPeriodic
AlexanderSinn Dec 15, 2021
0fd899b
Merge branch 'development' into extended-field
AlexanderSinn Jan 5, 2022
3d51ba5
add some suggestions
AlexanderSinn Jan 5, 2022
ee50414
fix doc
AlexanderSinn Jan 5, 2022
60d97cb
Merge branch 'development' into extended-field
AlexanderSinn Jan 12, 2022
33e826f
Merge branch 'development' into extended-field
AlexanderSinn Jan 19, 2022
d8c98d0
remove FieldView and add +0.5 back to fix striping
AlexanderSinn Jan 19, 2022
7b3446b
Merge branch 'extended-field' of https://github.com/AlexanderSinn/hip…
AlexanderSinn Jan 19, 2022
0e46aa0
enable z interpolation for output
AlexanderSinn Jan 20, 2022
762b237
fix MR lev1 output size
AlexanderSinn Jan 21, 2022
936aaf5
Merge branch 'development' into better_copy
AlexanderSinn Jan 25, 2022
6f82a70
reduce time used for Copy
AlexanderSinn Jan 26, 2022
e654a32
Merge branch 'development' into better_copy
AlexanderSinn Jan 26, 2022
c3f7be6
clean up
AlexanderSinn Jan 26, 2022
a77a335
add doc
AlexanderSinn Jan 26, 2022
1368e59
add open boundary
AlexanderSinn Jan 28, 2022
94266c7
fix critical allocation bug and include vector
AlexanderSinn Jan 31, 2022
4424c86
add _rt
AlexanderSinn Feb 2, 2022
d4856a8
add doc
AlexanderSinn Feb 2, 2022
043d5a5
fix doc
AlexanderSinn Feb 2, 2022
7e04397
merge
AlexanderSinn Feb 3, 2022
a13bce3
speed test
AlexanderSinn Feb 3, 2022
244b2ed
ugly mess
AlexanderSinn Feb 3, 2022
cbcc2e3
merge development
AlexanderSinn Feb 8, 2022
a2936da
clean up
AlexanderSinn Feb 8, 2022
f2ee319
add4py
AlexanderSinn Feb 10, 2022
8f4e3f9
make boundary more stable
AlexanderSinn Feb 22, 2022
f97af35
add doc
AlexanderSinn Feb 22, 2022
77b3e65
Merge branch 'development' into change_numerics
AlexanderSinn Feb 22, 2022
375b591
Merge branch 'development' into change_numerics
AlexanderSinn Feb 22, 2022
ee3ecfe
test CI
AlexanderSinn Feb 22, 2022
8d7e99a
add more doc
AlexanderSinn Feb 23, 2022
ed39bb1
remove detailed profiling
AlexanderSinn Feb 23, 2022
e04d164
use old amrex to fix CI
AlexanderSinn Feb 23, 2022
6da3233
Merge remote-tracking branch 'origin/development' into change_numerics
AlexanderSinn Feb 28, 2022
99c9ec5
add some suggestions
AlexanderSinn Mar 8, 2022
b4e2858
Merge branch 'development' into change_numerics
AlexanderSinn Mar 15, 2022
332e2fd
Merge branch 'development' into change_numerics
AlexanderSinn Mar 15, 2022
d547415
add code generator
AlexanderSinn Mar 15, 2022
f35927e
Merge branch 'development' of https://github.com/AlexanderSinn/hipace…
AlexanderSinn Mar 25, 2022
84b5613
allow for offset fixed ppc beam
AlexanderSinn Mar 25, 2022
9ad75d1
Merge branch 'offset_beam' into change_numerics
AlexanderSinn Mar 26, 2022
d6932f2
Update enforcePeriodic call (change in AMReX)
AlexanderSinn Mar 26, 2022
6ed1783
Merge branch 'fix_enforcePeriodic' into change_numerics
AlexanderSinn Mar 26, 2022
1aa044b
add CI test
AlexanderSinn Mar 26, 2022
8bb6429
Test CI performance
AlexanderSinn Mar 26, 2022
a4984c9
Merge branch 'fix_enforcePeriodic' into CI_perf_test
AlexanderSinn Mar 26, 2022
bd6964f
change openpmd-viewer backend in checksum to h5py
AlexanderSinn Mar 26, 2022
43b3fb6
change permissions
AlexanderSinn Mar 26, 2022
02533a2
change permissions again
AlexanderSinn Mar 26, 2022
939b0b8
Merge branch 'CI_perf_test' into change_numerics
AlexanderSinn Mar 26, 2022
7033464
add brackets
AlexanderSinn Mar 28, 2022
5418ccf
Merge branch 'fix_enforcePeriodic' into offset_beam
AlexanderSinn Mar 28, 2022
9a927b1
Merge branch 'offset_beam' into change_numerics
AlexanderSinn Mar 28, 2022
6bbedff
Merge branch 'development' into change_numerics
AlexanderSinn Apr 5, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,12 @@ if(BUILD_TESTING)
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)

add_test(NAME beam_in_vacuum_open_boundary.normalized.1Rank
COMMAND ${HiPACE_SOURCE_DIR}/tests/beam_in_vacuum_open_boundary.normalized.1Rank.sh
$<TARGET_FILE:HiPACE> ${HiPACE_SOURCE_DIR}
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)

endif()
endif()

Expand Down
11 changes: 11 additions & 0 deletions docs/source/run/parameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@ Modeling ion motion is not yet supported by the explicit solver
The small dst is quicker for simulations with :math:`\geq 511` transverse grid points.
The default is set accordingly.

* ``fields.extended_solve`` (`bool`) optional (default `0`)
Extends the area of the FFT Poisson solver to the ghost cells. This can reduce artifacts
originating from the boundary for long simulations.

* ``fields.open_boundary`` (`bool`) optional (default `0`)
Uses a Taylor approximation of the Greens function to solve the Poisson equations with
open boundary conditions. It's recommended to use this together with
``fields.extended_solve = true`` and ``geometry.is_periodic = false false false``.
Not implemented for the explicit Helmholtz solver.


Predictor-corrector loop parameters
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
179 changes: 179 additions & 0 deletions examples/beam_in_vacuum/analysis_open_boundary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
#! /usr/bin/env python3

# Copyright 2020-2022
#
# This file is part of HiPACE++.
#
# Authors: AlexanderSinn, MaxThevenet, Severin Diederichs
# License: BSD-3-Clause-LBNL


# This script compares the transverse field By with the theoretical value, plots both
# the simulation result and the theory on the same plot, and asserts that the
# difference is small.
#
# To use it, run the simulation and execute this script with
# > ../../build/bin/hipace inputs_SI
# > python analysis.py

import numpy as np
import scipy.constants as scc
import argparse
import sys
from openpmd_viewer import OpenPMDTimeSeries
import matplotlib
import matplotlib.pyplot as plt

parser = argparse.ArgumentParser(description='Script to analyze the correctness of the beam in vacuum')
parser.add_argument('--normalized-units',
dest='norm_units',
action='store_true',
default=False,
help='Run the analysis in normalized units')
parser.add_argument('--do-plot',
dest='do_plot',
action='store_true',
default=False,
help='Plot figures and save them to file')
parser.add_argument('--output-dir',
dest='output_dir',
default='diags/hdf5',
help='Path to the directory containing output files')
args = parser.parse_args()

ts = OpenPMDTimeSeries(args.output_dir)

if args.norm_units:
c = 1.
jz0 = -1.
rho0 = -1.
mu_0 = 1.
eps_0 = 1.
R = 1.
else:
# Density of the can beam
dens = 2.8239587008591567e23 # at this density, 1/kp = 10um, allowing for an easy comparison with normalized units
# Define array for transverse coordinate and theory for By and Bx
jz0 = - scc.e * scc.c * dens
rho0 = - scc.e * dens
c = scc.c
mu_0 = scc.mu_0
eps_0 = scc.epsilon_0
# Radius of the can beam
R = 10.e-6

x_beam_mid = 2
y_beam_mid = -1
x_domain_len = 8
y_domain_len = 8

# Load HiPACE++ data for By in SI units
Bx_sim, Bx_meta = ts.get_field(field='Bx', iteration=0, slice_across=['x','z'], slice_relative_position=[2*x_beam_mid/x_domain_len,0])
By_sim, By_meta = ts.get_field(field='By', iteration=0, slice_across=['y','z'], slice_relative_position=[2*y_beam_mid/y_domain_len,0])
jz_sim = ts.get_field(field='jz_beam', iteration=0, slice_across=['y','z'], slice_relative_position=[2*y_beam_mid/y_domain_len,0])[0]
rho_sim = ts.get_field(field='rho', iteration=0, slice_across=['y','z'], slice_relative_position=[2*y_beam_mid/y_domain_len,0])[0]
Ex_sim = ts.get_field(field='ExmBy', iteration=0, slice_across=['y','z'], slice_relative_position=[2*y_beam_mid/y_domain_len,0])[0] + c*By_sim
Ey_sim = ts.get_field(field='EypBx', iteration=0, slice_across=['x','z'], slice_relative_position=[2*x_beam_mid/x_domain_len,0])[0] - c*Bx_sim
y = Bx_meta.y
x = By_meta.x

By_th = mu_0 * jz0 * (x-x_beam_mid) / 2.
By_th[abs(x-x_beam_mid)>=R] = mu_0 * jz0 * R**2/(2*(x[abs(x-x_beam_mid)>R]-x_beam_mid))
Ex_th = rho0 / eps_0 * (x-x_beam_mid) / 2.
Ex_th[abs(x-x_beam_mid)>=R] = rho0 / eps_0 * R**2/(2*(x[abs(x-x_beam_mid)>R]-x_beam_mid))

Bx_th = -mu_0 * jz0 * (y-y_beam_mid) / 2.
Bx_th[abs(y-y_beam_mid)>=R] = -mu_0 * jz0 * R**2/(2*(y[abs(y-y_beam_mid)>R]-y_beam_mid))
Ey_th = rho0 / eps_0 * (y-y_beam_mid) / 2.
Ey_th[abs(y-y_beam_mid)>=R] = rho0 / eps_0 * R**2/(2*(y[abs(y-y_beam_mid)>R]-y_beam_mid))

jz_th = np.ones_like(x) * jz0
jz_th[abs(x-x_beam_mid)>=R] = 0.
rho_th = np.ones_like(x) * rho0
rho_th[abs(x-x_beam_mid)>=R] = 0.

# Plot simulation result and theory
if args.do_plot:
matplotlib.rcParams.update({'font.size': 14})
plt.figure(figsize=(12,4))

if not args.norm_units:
plt.subplot(131)
plt.plot(1.e6*y, Bx_sim, '+-', label='HiPACE++')
plt.plot(1.e6*y, Bx_th, 'k--', label='theory')
plt.grid()
plt.legend()
plt.xlim(-50., 50.)
plt.xlabel('y (um)')
plt.ylabel('Bx (T)')

plt.subplot(132)
plt.plot(1.e6*x, By_sim, '+-', label='HiPACE++')
plt.plot(1.e6*x, By_th, 'k--', label='theory')
plt.grid()
plt.legend()
plt.xlim(-50., 50.)
plt.xlabel('x (um)')
plt.ylabel('By (T)')

plt.subplot(133)
plt.plot(1.e6*x, jz_sim, '+-', label='HiPACE++')
plt.plot(1.e6*x, jz_th, 'k--', label='theory')
plt.grid()
plt.legend()
plt.xlim(-50., 50.)
plt.xlabel('x (um)')
plt.ylabel('jz (A/m2)')
else:
plt.subplot(131)
plt.plot(y, Bx_sim, '+-', label='HiPACE++')
plt.plot(y, Bx_th, 'k--', label='theory')
plt.grid()
plt.legend()
plt.xlim(-5., 5.)
plt.xlabel('kp y')
plt.ylabel('c Bx / E0')

plt.subplot(132)
plt.plot(x, By_sim, '+-', label='HiPACE++')
plt.plot(x, By_th, 'k--', label='theory')
plt.grid()
plt.legend()
plt.xlim(-5., 5.)
plt.xlabel('kp x')
plt.ylabel('c By / E0')

plt.subplot(133)
plt.plot(x, jz_sim, '+-', label='HiPACE++')
plt.plot(x, jz_th, 'k--', label='theory')
plt.grid()
plt.legend()
plt.xlim(-5., 5.)
plt.xlabel('kp x')
plt.ylabel('jz /IA')

plt.tight_layout()

plt.savefig("beam_in_vacuum.png", bbox_inches="tight")

# Assert that the simulation result is close enough to theory
error_jz = np.sum((jz_sim-jz_th)**2) / np.sum((jz_th)**2)
print("total relative error jz: " + str(error_jz) + " (tolerance = 0.1)")

error_Bx = np.sum((Bx_sim-Bx_th)**2) / np.sum((Bx_th)**2)
print("total relative error Bx: " + str(error_Bx) + " (tolerance = 0.005)")

error_By = np.sum((By_sim-By_th)**2) / np.sum((By_th)**2)
print("total relative error By: " + str(error_By) + " (tolerance = 0.015)")

error_Ex = np.sum((Ex_sim-Ex_th)**2) / np.sum((Ex_th)**2)
print("total relative error Ex: " + str(error_Ex) + " (tolerance = 0.015)")

error_Ey = np.sum((Ey_sim-Ey_th)**2) / np.sum((Ey_th)**2)
print("total relative error Ey: " + str(error_Ey) + " (tolerance = 0.005)")

assert(error_jz < .1)
assert(error_Bx < .005)
assert(error_By < .015)
assert(error_Ex < .015)
assert(error_Ey < .005)
39 changes: 23 additions & 16 deletions src/Hipace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ Hipace::SolveOneSlice (int islice_coarse, const int ibox,
ijz == ijx+4 && ijz_beam == ijx+5 && irho == ijx+6 );
amrex::MultiFab j_slice(m_fields.getSlices(lev, WhichSlice::This),
amrex::make_alias, Comps[WhichSlice::This]["jx"], 7);
j_slice.FillBoundary(Geom(lev).periodicity());
if (!m_fields.m_extended_solve) j_slice.FillBoundary(Geom(lev).periodicity());

m_fields.SolvePoissonExmByAndEypBx(Geom(), m_comm_xy, lev, islice);

Expand All @@ -583,7 +583,7 @@ Hipace::SolveOneSlice (int islice_coarse, const int ibox,
WhichSlice::This);
m_fields.AddBeamCurrents(lev, WhichSlice::This);

j_slice.FillBoundary(Geom(lev).periodicity());
if (!m_fields.m_extended_solve) j_slice.FillBoundary(Geom(lev).periodicity());

m_fields.SolvePoissonEz(Geom(), lev, islice);
m_fields.SolvePoissonBz(Geom(), lev, islice);
Expand Down Expand Up @@ -912,10 +912,13 @@ Hipace::PredictorCorrectorLoopToSolveBxBy (const int islice_local, const int lev

/* Guess Bx and By */
m_fields.InitialBfieldGuess(relative_Bfield_error, m_predcorr_B_error_tolerance, lev);
amrex::ParallelContext::push(m_comm_xy);
// exchange ExmBy EypBx Ez Bx By Bz
m_fields.getSlices(lev, WhichSlice::This).FillBoundary(Geom(lev).periodicity());
amrex::ParallelContext::pop();

if (!m_fields.m_extended_solve) {
amrex::ParallelContext::push(m_comm_xy);
// exchange ExmBy EypBx Ez Bx By Bz
m_fields.getSlices(lev, WhichSlice::This).FillBoundary(Geom(lev).periodicity());
amrex::ParallelContext::pop();
}

/* creating temporary Bx and By arrays for the current and previous iteration */
amrex::MultiFab Bx_iter(m_fields.getSlices(lev, WhichSlice::This).boxArray(),
Expand Down Expand Up @@ -976,12 +979,14 @@ Hipace::PredictorCorrectorLoopToSolveBxBy (const int islice_local, const int lev
ibox, m_do_beam_jx_jy_deposition, WhichSlice::Next);
m_fields.AddBeamCurrents(lev, WhichSlice::Next);

amrex::ParallelContext::push(m_comm_xy);
// need to exchange jx jy jx_beam jy_beam
amrex::MultiFab j_slice_next(m_fields.getSlices(lev, WhichSlice::Next),
amrex::make_alias, Comps[WhichSlice::Next]["jx"], 4);
j_slice_next.FillBoundary(Geom(lev).periodicity());
amrex::ParallelContext::pop();
if (!m_fields.m_extended_solve) {
amrex::ParallelContext::push(m_comm_xy);
// need to exchange jx jy jx_beam jy_beam
amrex::MultiFab j_slice_next(m_fields.getSlices(lev, WhichSlice::Next),
amrex::make_alias, Comps[WhichSlice::Next]["jx"], 4);
j_slice_next.FillBoundary(Geom(lev).periodicity());
amrex::ParallelContext::pop();
}

/* Calculate Bx and By */
m_fields.SolvePoissonBx(Bx_iter, Geom(), lev, islice);
Expand Down Expand Up @@ -1010,10 +1015,12 @@ Hipace::PredictorCorrectorLoopToSolveBxBy (const int islice_local, const int lev
jx_beam_next.setVal(0., m_fields.m_slices_nguards);
jy_beam_next.setVal(0., m_fields.m_slices_nguards);

amrex::ParallelContext::push(m_comm_xy);
// exchange Bx By
m_fields.getSlices(lev, WhichSlice::This).FillBoundary(Geom(lev).periodicity());
amrex::ParallelContext::pop();
if (!m_fields.m_extended_solve) {
amrex::ParallelContext::push(m_comm_xy);
// exchange Bx By
m_fields.getSlices(lev, WhichSlice::This).FillBoundary(Geom(lev).periodicity());
amrex::ParallelContext::pop();
}

/* Update force terms using the calculated Bx and By */
m_multi_plasma.AdvanceParticles(m_fields, m_laser, geom[lev],
Expand Down
9 changes: 9 additions & 0 deletions src/fields/Fields.H
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@ public:
static amrex::IntVect m_slices_nguards;
/** Number of guard cells for poisson solver MultiFab */
static amrex::IntVect m_poisson_nguards;
/** If the poisson solver should include the guard cells */
bool m_extended_solve = false;

private:
/** Vector over levels, array of 4 slices required to compute current slice */
amrex::Vector<std::array<amrex::MultiFab, m_nslices>> m_slices;
Expand All @@ -316,6 +319,12 @@ private:
amrex::Vector<amrex::FArrayBox> m_tmp_densities;
/** Stores temporary values for z interpolation in Fields::Copy */
amrex::Gpu::DeviceVector<amrex::Real> m_rel_z_vec;
/** Number of guard cells where ExmBy and EypBx are calculated */
amrex::IntVect m_exmby_eypbx_nguard;
/** Number of guard cells where sources for poisson equation are included */
amrex::IntVect m_source_nguard;
/** If lev_0 should be solved with open boundary conditions */
bool m_open_boundary = false;
};

#endif
Loading