Skip to content
Merged
Show file tree
Hide file tree
Changes from 53 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
11 changes: 11 additions & 0 deletions docs/source/run/parameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,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 artefacts
originating from the boundary for long simulations.

* ``fields.open_boundary`` (`bool`) optional (default `0`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for future extensibility, you could use the same syntax as in WarpX here: boundary.field_lo and boundary.field_hi
https://warpx.readthedocs.io/en/latest/usage/parameters.html#domain-boundary-conditions

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because right now there is now functionality to have different boundary conditions for different sides of the box (and no use in hipace?). Moreover, as I understand it, the four combinations of fields.extended_solve = true/false and fields.open_boundary = true/false would require four differently name boundary conditions with that syntax.

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
39 changes: 23 additions & 16 deletions src/Hipace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,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 @@ -567,7 +567,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 @@ -863,10 +863,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 @@ -927,12 +930,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 @@ -961,10 +966,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, geom[lev], false, false, true, false, 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 @@ -294,6 +294,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 @@ -303,6 +306,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
165 changes: 119 additions & 46 deletions src/fields/Fields.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "fft_poisson_solver/FFTPoissonSolverPeriodic.H"
#include "fft_poisson_solver/FFTPoissonSolverDirichlet.H"
#include "Hipace.H"
#include "OpenBoundary.H"
#include "utils/HipaceProfilerWrapper.H"
#include "utils/Constants.H"
#include "particles/ShapeFactors.H"
Expand All @@ -16,6 +17,8 @@ Fields::Fields (Hipace const* a_hipace)
{
amrex::ParmParse ppf("fields");
queryWithParser(ppf, "do_dirichlet_poisson", m_do_dirichlet_poisson);
queryWithParser(ppf, "extended_solve", m_extended_solve);
queryWithParser(ppf, "open_boundary", m_open_boundary);
}

void
Expand All @@ -27,11 +30,25 @@ Fields::AllocData (
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(slice_ba.size() == 1,
"Parallel field solvers not supported yet");

// Need 1 extra guard cell transversally for transverse derivative
int nguards_xy = std::max(1, Hipace::m_depos_order_xy);
m_slices_nguards = {nguards_xy, nguards_xy, 0};
// Poisson solver same size as domain, no ghost cells
m_poisson_nguards = {0, 0, 0};
if (m_extended_solve) {
// Need 1 extra guard cell transversally for transverse derivative
int nguards_xy = (Hipace::m_depos_order_xy + 1) / 2 + 1;
m_slices_nguards = {nguards_xy, nguards_xy, 0};
// poisson solver same size as fields
m_poisson_nguards = m_slices_nguards;
// one cell less for transverse derivative
m_exmby_eypbx_nguard = m_slices_nguards - amrex::IntVect{1, 1, 0};
// cut off anything near edge of charge/current deposition
m_source_nguard = -m_slices_nguards;
} else {
// Need 1 extra guard cell transversally for transverse derivative
int nguards_xy = std::max(1, Hipace::m_depos_order_xy);
m_slices_nguards = {nguards_xy, nguards_xy, 0};
// Poisson solver same size as domain, no ghost cells
m_poisson_nguards = {0, 0, 0};
m_exmby_eypbx_nguard = {0, 0, 0};
m_source_nguard = {0, 0, 0};
}

for (int islice=0; islice<WhichSlice::N; islice++) {
m_slices[lev][islice].define(
Expand Down Expand Up @@ -82,19 +99,12 @@ struct derivative_inner {
// captured variables for GPU
amrex::Array4<amrex::Real const> array;
amrex::Real dx_inv;
int box_lo;
int box_hi;

// derivative of field in dir direction (x or y)
// the field is zero-extended such that this derivative can be accessed on the same box
AMREX_GPU_DEVICE amrex::Real operator() (int i, int j, int k) const noexcept {
constexpr bool is_x_dir = dir == Direction::x;
constexpr bool is_y_dir = dir == Direction::y;
const int ij_along_dir = is_x_dir * i + is_y_dir * j;
const bool lo_guard = ij_along_dir != box_lo;
const bool hi_guard = ij_along_dir != box_hi;
return (array(i+is_x_dir*hi_guard,j+is_y_dir*hi_guard,k)*hi_guard
-array(i-is_x_dir*lo_guard,j-is_y_dir*lo_guard,k)*lo_guard) * dx_inv;
return (array(i+is_x_dir,j+is_y_dir,k) - array(i-is_x_dir,j-is_y_dir,k)) * dx_inv;
}
};

Expand All @@ -112,8 +122,7 @@ struct derivative_inner<Direction::z> {
}
};

/** \brief derivative in x or y direction. Field is zero-extended by one cell such that this
* derivative can be accessed on the same box as the field */
/** \brief derivative in x or y direction */
template<int dir>
struct derivative {
// use brace initialization as constructor
Expand All @@ -122,9 +131,7 @@ struct derivative {

// use .array(mfi) like with amrex::MultiFab
derivative_inner<dir> array (amrex::MFIter& mfi) const {
amrex::Box bx = f_view[mfi].box();
return derivative_inner<dir>{f_view.array(mfi),
1._rt/(2._rt*geom.CellSize(dir)), bx.smallEnd(dir), bx.bigEnd(dir)};
return derivative_inner<dir>{f_view.array(mfi), 1._rt/(2._rt*geom.CellSize(dir))};
}
};

Expand Down Expand Up @@ -278,10 +285,16 @@ LinCombination (const amrex::IntVect box_grow, amrex::MultiFab dst,
const auto src_a_array = src_a.array(mfi);
const auto src_b_array = src_b.array(mfi);
const amrex::Box bx = mfi.growntilebox(box_grow);
amrex::ParallelFor(bx,
const int box_i_lo = bx.smallEnd(Direction::x);
const int box_j_lo = bx.smallEnd(Direction::y);
const int box_i_hi = bx.bigEnd(Direction::x);
const int box_j_hi = bx.bigEnd(Direction::y);
amrex::ParallelFor(mfi.growntilebox(),
[=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
{
dst_array(i,j,k) = factor_a * src_a_array(i,j,k) + factor_b * src_b_array(i,j,k);
const bool inside = box_i_lo<=i && i<=box_i_hi && box_j_lo<=j && j<=box_j_hi;
dst_array(i,j,k) =
inside ? factor_a * src_a_array(i,j,k) + factor_b * src_b_array(i,j,k) : 0._rt;
});
}
}
Expand Down Expand Up @@ -493,27 +506,85 @@ void
Fields::SetBoundaryCondition (amrex::Vector<amrex::Geometry> const& geom, const int lev,
std::string component, const int islice)
{
if (lev == 0) return; // keep lev==0 boundaries zero
HIPACE_PROFILE("Fields::SetBoundaryCondition()");
constexpr int interp_order = 2;
if (lev == 0 && m_open_boundary) {
// Coarsest level: use Taylor expansion of the Green's function
// to get Dirichlet boundary conditions

const amrex::Real ref_ratio_z = Hipace::GetRefRatio(lev)[2];
const amrex::Real islice_coarse = (islice + 0.5_rt) / ref_ratio_z;
const amrex::Real rel_z = islice_coarse - static_cast<int>(amrex::Math::floor(islice_coarse));
amrex::MultiFab staging_area = getStagingArea(lev);
// Open Boundaries only work for lev0 with everything in one box
amrex::FArrayBox& staging_area_fab = staging_area[0];

auto solution_interp = interpolated_field_xyz<interp_order>{
getField(lev-1, WhichSlice::This, component),
getField(lev-1, WhichSlice::Previous1, component),
rel_z, geom[lev-1]};
amrex::MultiFab staging_area = getStagingArea(lev);
const auto arr_staging_area = staging_area_fab.array();
const amrex::Box staging_box = staging_area_fab.box();

for (amrex::MFIter mfi(staging_area, false); mfi.isValid(); ++mfi)
{
const auto arr_solution_interp = solution_interp.array(mfi);
const auto arr_staging_area = staging_area.array(mfi);
const amrex::Box fine_staging_box = staging_area[mfi].box();
const amrex::Real poff_x = GetPosOffset(0, geom[lev], staging_box);
const amrex::Real poff_y = GetPosOffset(1, geom[lev], staging_box);
const amrex::Real dx = geom[lev].CellSize(0);
const amrex::Real dy = geom[lev].CellSize(1);
// scale factor cancels out for all multipole coefficients except the 0th, for wich it adds
// a constant therm to the potential
const amrex::Real scale = 3._rt/std::sqrt(
pow<2>(geom[lev].ProbLength(0)) + pow<2>(geom[lev].ProbLength(1)));
const amrex::Real radius = amrex::min(
std::abs(geom[lev].ProbLo(0)), std::abs(geom[lev].ProbHi(0)),
std::abs(geom[lev].ProbLo(1)), std::abs(geom[lev].ProbHi(1)));
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(radius > 0._rt, "The x=0, y=0 coordinate must be inside"
"the simulation box as it is used as the point of expansion for open boundaries");
// ignore everything outside of 95% the min radius as the Taylor expansion only converges
// outside of a circular patch containing the sources, i.e. the sources can't be further
// from the center than the closest boundary as it would be the case in the corners
const amrex::Real cutoff_sq = pow<2>(0.95_rt * radius * scale);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't 95% arbitrary? Should it be e.g. min radius minus 3 cells or so?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s not about a fixed number of Cells, rather it’s to stay a safe distance away from the convergence radius of the Taylor expansion.

const amrex::Real dxdy_div_4pi = dx*dy/(4._rt * MathConst::pi);

MultipoleTuple coeff_tuple =
amrex::ParReduce(MultipoleReduceOpList{}, MultipoleReduceTypeList{},
staging_area, m_source_nguard,
[=] AMREX_GPU_DEVICE (int /*box_num*/, int i, int j, int k) noexcept
{
const amrex::Real x = (i * dx + poff_x) * scale;
const amrex::Real y = (j * dy + poff_y) * scale;
if (x*x + y*y > cutoff_sq) return MultipoleTuple{}; //zero
amrex::Real s_v = arr_staging_area(i, j, k);
return GetMultipoleCoeffs(s_v, x, y);
}
);

if (component == "Ez" || component == "Bz") {
// Because Ez and Bz only have transverse derivatives of currents as sources, the
// integral over the whole box is zero, meaning they have no physical monopole component
amrex::get<0>(coeff_tuple) = 0._rt;
}

SetDirichletBoundaries(arr_staging_area, staging_box, geom[lev],
[=] AMREX_GPU_DEVICE (amrex::Real x, amrex::Real y) noexcept
{
return dxdy_div_4pi*GetFieldMultipole(coeff_tuple, x*scale, y*scale);
}
);

SetDirichletBoundaries(arr_staging_area, fine_staging_box, geom[lev], arr_solution_interp);
} else if (lev == 1) {
// Fine level: interpolate solution from coarser level to get Dirichlet boundary conditions
constexpr int interp_order = 2;

const amrex::Real ref_ratio_z = Hipace::GetRefRatio(lev)[2];
const amrex::Real islice_coarse = (islice + 0.5_rt) / ref_ratio_z;
const amrex::Real rel_z = islice_coarse-static_cast<int>(amrex::Math::floor(islice_coarse));

auto solution_interp = interpolated_field_xyz<interp_order>{
getField(lev-1, WhichSlice::This, component),
getField(lev-1, WhichSlice::Previous1, component),
rel_z, geom[lev-1]};
amrex::MultiFab staging_area = getStagingArea(lev);

for (amrex::MFIter mfi(staging_area, false); mfi.isValid(); ++mfi)
{
const auto arr_solution_interp = solution_interp.array(mfi);
const auto arr_staging_area = staging_area.array(mfi);
const amrex::Box fine_staging_box = staging_area[mfi].box();

SetDirichletBoundaries(arr_staging_area,fine_staging_box,geom[lev],arr_solution_interp);
}
}
}

Expand Down Expand Up @@ -588,17 +659,19 @@ Fields::SolvePoissonExmByAndEypBx (amrex::Vector<amrex::Geometry> const& geom,
InterpolateFromLev0toLev1(geom, lev, "rho", islice, m_poisson_nguards, -m_slices_nguards);

// calculating the right-hand side 1/episilon0 * -(rho-Jz/c)
LinCombination(m_poisson_nguards, getStagingArea(lev),
LinCombination(m_source_nguard, getStagingArea(lev),
1._rt/(phys_const.c*phys_const.ep0), getField(lev, WhichSlice::This, "jz"),
-1._rt/(phys_const.ep0), getField(lev, WhichSlice::This, "rho"));

SetBoundaryCondition(geom, lev, "Psi", islice);
m_poisson_solver[lev]->SolvePoissonEquation(lhs);

/* ---------- Transverse FillBoundary Psi ---------- */
amrex::ParallelContext::push(m_comm_xy);
lhs.FillBoundary(geom[lev].periodicity());
amrex::ParallelContext::pop();
if (!m_extended_solve) {
/* ---------- Transverse FillBoundary Psi ---------- */
amrex::ParallelContext::push(m_comm_xy);
lhs.FillBoundary(geom[lev].periodicity());
amrex::ParallelContext::pop();
}

InterpolateFromLev0toLev1(geom, lev, "Psi", islice, m_slices_nguards, m_poisson_nguards);

Expand All @@ -615,7 +688,7 @@ Fields::SolvePoissonExmByAndEypBx (amrex::Vector<amrex::Geometry> const& geom,
const amrex::Array4<amrex::Real> array_EypBx = f_EypBx.array(mfi);
const amrex::Array4<amrex::Real const> array_Psi = f_Psi.array(mfi);
// number of ghost cells where ExmBy and EypBx are calculated is 0 for now
const amrex::Box bx = mfi.growntilebox(amrex::IntVect{0, 0, 0});
const amrex::Box bx = mfi.growntilebox(m_exmby_eypbx_nguard);
const amrex::Real dx_inv = 1._rt/(2._rt*geom[lev].CellSize(Direction::x));
const amrex::Real dy_inv = 1._rt/(2._rt*geom[lev].CellSize(Direction::y));

Expand Down Expand Up @@ -643,7 +716,7 @@ Fields::SolvePoissonEz (amrex::Vector<amrex::Geometry> const& geom, const int le

// Right-Hand Side for Poisson equation: compute 1/(episilon0 *c0 )*(d_x(jx) + d_y(jy))
// from the slice MF, and store in the staging area of poisson_solver
LinCombination(m_poisson_nguards, getStagingArea(lev),
LinCombination(m_source_nguard, getStagingArea(lev),
1._rt/(phys_const.ep0*phys_const.c),
derivative<Direction::x>{getField(lev, WhichSlice::This, "jx"), geom[lev]},
1._rt/(phys_const.ep0*phys_const.c),
Expand All @@ -667,7 +740,7 @@ Fields::SolvePoissonBx (amrex::MultiFab& Bx_iter, amrex::Vector<amrex::Geometry>

// Right-Hand Side for Poisson equation: compute -mu_0*d_y(jz) from the slice MF,
// and store in the staging area of poisson_solver
LinCombination(m_poisson_nguards, getStagingArea(lev),
LinCombination(m_source_nguard, getStagingArea(lev),
-phys_const.mu0,
derivative<Direction::y>{getField(lev, WhichSlice::This, "jz"), geom[lev]},
phys_const.mu0,
Expand All @@ -692,7 +765,7 @@ Fields::SolvePoissonBy (amrex::MultiFab& By_iter, amrex::Vector<amrex::Geometry>

// Right-Hand Side for Poisson equation: compute mu_0*d_x(jz) from the slice MF,
// and store in the staging area of poisson_solver
LinCombination(m_poisson_nguards, getStagingArea(lev),
LinCombination(m_source_nguard, getStagingArea(lev),
phys_const.mu0,
derivative<Direction::x>{getField(lev, WhichSlice::This, "jz"), geom[lev]},
-phys_const.mu0,
Expand All @@ -719,7 +792,7 @@ Fields::SolvePoissonBz (amrex::Vector<amrex::Geometry> const& geom, const int le

// Right-Hand Side for Poisson equation: compute mu_0*(d_y(jx) - d_x(jy))
// from the slice MF, and store in the staging area of m_poisson_solver
LinCombination(m_poisson_nguards, getStagingArea(lev),
LinCombination(m_source_nguard, getStagingArea(lev),
phys_const.mu0,
derivative<Direction::y>{getField(lev, WhichSlice::This, "jx"), geom[lev]},
-phys_const.mu0,
Expand Down
Loading