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

[WIP] Expose electrostatic solver that only accounts for boundary potentials #5506

Open
wants to merge 8 commits into
base: development
Choose a base branch
from
9 changes: 9 additions & 0 deletions Source/FieldSolver/ElectrostaticSolvers/ElectrostaticSolver.H
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,15 @@ public:
std::array<amrex::Real, 3> beta
) const;

/** Compute the potential `phi` by solving the Poisson equation with the
simulation specific boundary conditions and boundary values, then add the
E field due to that `phi` to `Efield_fp`.
* \param[in] Efield Efield updated to include potential gradient from boundary condition
*/
void AddBoundaryField (
RemiLehe marked this conversation as resolved.
Show resolved Hide resolved
ablastr::fields::MultiLevelVectorField& Efield
) const;

/** Maximum levels for the electrostatic solver grid */
int num_levels;

Expand Down
36 changes: 36 additions & 0 deletions Source/FieldSolver/ElectrostaticSolvers/ElectrostaticSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,3 +549,39 @@ void ElectrostaticSolver::computeB (
}
}
}

void ElectrostaticSolver::AddBoundaryField (ablastr::fields::MultiLevelVectorField& Efield_fp) const
{
WARPX_PROFILE("RelativisticExplicitES::AddBoundaryField");

auto & warpx = WarpX::GetInstance();

// Allocate fields for charge and potential
Vector<std::unique_ptr<MultiFab>> rho(num_levels);
Vector<std::unique_ptr<MultiFab>> phi(num_levels);
// Use number of guard cells used for local deposition of rho
const amrex::IntVect ng = warpx.get_ng_depos_rho();
for (int lev = 0; lev < num_levels; lev++) {
BoxArray nba = warpx.boxArray(lev);
nba.surroundingNodes();
rho[lev] = std::make_unique<amrex::MultiFab>(nba, warpx.DistributionMap(lev), 1, ng);
rho[lev]->setVal(0.);
phi[lev] = std::make_unique<amrex::MultiFab>(nba, warpx.DistributionMap(lev), 1, 1);
phi[lev]->setVal(0.);
}

// Set the boundary potentials appropriately
setPhiBC( amrex::GetVecOfPtrs(phi), warpx.gett_new(0));

// beta is zero for boundaries
const std::array<Real, 3> beta = {0._rt};

// Compute the potential phi, by solving the Poisson equation
computePhi( amrex::GetVecOfPtrs(rho), amrex::GetVecOfPtrs(phi),
beta, self_fields_required_precision,
self_fields_absolute_tolerance, self_fields_max_iters,
self_fields_verbosity, is_igf_2d_slices );

// Compute the corresponding electric field, from the potential phi.
computeE( Efield_fp, amrex::GetVecOfPtrs(phi), beta );
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,6 @@ public:
ablastr::fields::MultiLevelVectorField& Bfield_fp
);

/** Compute the potential `phi` by solving the Poisson equation with the
simulation specific boundary conditions and boundary values, then add the
E field due to that `phi` to `Efield_fp`.
* \param[in] Efield Efield updated to include potential gradient from boundary condition
*/
void AddBoundaryField (
ablastr::fields::MultiLevelVectorField& Efield
);
};

#endif // WARPX_RELATIVISTICEXPLICITES_H_
36 changes: 0 additions & 36 deletions Source/FieldSolver/ElectrostaticSolvers/RelativisticExplicitES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,39 +137,3 @@ void RelativisticExplicitES::AddSpaceChargeField (
computeB( Bfield_fp, amrex::GetVecOfPtrs(phi), beta );

}

void RelativisticExplicitES::AddBoundaryField (ablastr::fields::MultiLevelVectorField& Efield_fp)
{
WARPX_PROFILE("RelativisticExplicitES::AddBoundaryField");

auto & warpx = WarpX::GetInstance();

// Allocate fields for charge and potential
Vector<std::unique_ptr<MultiFab>> rho(num_levels);
Vector<std::unique_ptr<MultiFab>> phi(num_levels);
// Use number of guard cells used for local deposition of rho
const amrex::IntVect ng = warpx.get_ng_depos_rho();
for (int lev = 0; lev < num_levels; lev++) {
BoxArray nba = warpx.boxArray(lev);
nba.surroundingNodes();
rho[lev] = std::make_unique<amrex::MultiFab>(nba, warpx.DistributionMap(lev), 1, ng);
rho[lev]->setVal(0.);
phi[lev] = std::make_unique<amrex::MultiFab>(nba, warpx.DistributionMap(lev), 1, 1);
phi[lev]->setVal(0.);
}

// Set the boundary potentials appropriately
setPhiBC( amrex::GetVecOfPtrs(phi), warpx.gett_new(0));

// beta is zero for boundaries
const std::array<Real, 3> beta = {0._rt};

// Compute the potential phi, by solving the Poisson equation
computePhi( amrex::GetVecOfPtrs(rho), amrex::GetVecOfPtrs(phi),
beta, self_fields_required_precision,
self_fields_absolute_tolerance, self_fields_max_iters,
self_fields_verbosity, is_igf_2d_slices);

// Compute the corresponding electric field, from the potential phi.
computeE( Efield_fp, amrex::GetVecOfPtrs(phi), beta );
}
8 changes: 8 additions & 0 deletions Source/Python/WarpX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
# include <FieldSolver/SpectralSolver/SpectralSolver.H>
# endif // RZ ifdef
#endif // use PSATD ifdef
#include <FieldSolver/ElectrostaticSolvers/RelativisticExplicitES.H>
#include <FieldSolver/WarpX_FDTD.H>
#include <Filter/NCIGodfreyFilter.H>
#include <Initialization/ExternalField.H>
Expand Down Expand Up @@ -274,6 +275,13 @@ The physical fields in WarpX have the following naming:
[] (WarpX& wx) { wx.Synchronize(); },
"Synchronize particle velocities and positions."
)
.def("add_boundary_electrostatic_field",
[] (WarpX& wx) {
auto Efield_fp = wx.m_fields.get_mr_levels_alldirs("Efield_fp", wx.maxLevel());
wx.GetElectrostaticSolver().AddBoundaryField( Efield_fp );
},
"Compute the electric field due to the potential specified on the domain boundaries and embedded boundaries."
)
;

py::class_<warpx::Config>(m, "Config")
Expand Down
Loading