aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Docs/source/usage/parameters.rst2
-rw-r--r--Examples/Tests/ElectrostaticSphereEB/inputs_3d_mixed_BCs26
-rw-r--r--Regression/Checksum/benchmarks_json/ElectrostaticSphereEB_mixedBCs.json9
-rw-r--r--Regression/WarpX-tests.ini17
-rw-r--r--Source/FieldSolver/ElectrostaticSolver.H4
-rw-r--r--Source/FieldSolver/ElectrostaticSolver.cpp59
6 files changed, 94 insertions, 23 deletions
diff --git a/Docs/source/usage/parameters.rst b/Docs/source/usage/parameters.rst
index 21b8764a8..95415665a 100644
--- a/Docs/source/usage/parameters.rst
+++ b/Docs/source/usage/parameters.rst
@@ -226,7 +226,7 @@ Domain Boundary Conditions
* ``pec``: This option can be used to set a Perfect Electric Conductor at the simulation boundary. For the electromagnetic solve, at PEC, the tangential electric field and the normal magnetic field are set to 0. This boundary can be used to model a dielectric or metallic surface. In the guard-cell region, the tangential electric field is set equal and opposite to the respective field component in the mirror location across the PEC boundary, and the normal electric field is set equal to the field component in the mirror location in the domain across the PEC boundary. Similarly, the tangential (and normal) magnetic field components are set equal (and opposite) to the respective magnetic field components in the mirror locations across the PEC boundary. Note that PEC boundary is invalid at `r=0` for the RZ solver. Please use ``none`` option. This boundary condition does not work with the spectral solver.
If an electrostatic field solve is used the boundary potentials can also be set through ``boundary.potential_lo_x/y/z`` and ``boundary.potential_hi_x/y/z`` (default `0`).
- * ``none``: No boundary condition is applied to the fields. This option must be used for the RZ-solver at `r=0`.
+ * ``none``: No boundary condition is applied to the fields with the electromagnetic solver. This option must be used for the RZ-solver at `r=0`. If the electrostatic solver is used, a Neumann boundary condition (with gradient equal to 0) will be applied on the specified boundary.
* ``boundary.particle_lo`` and ``boundary.particle_hi`` (`2 strings` for 2D, `3 strings` for 3D, `absorbing` by default)
Options are:
diff --git a/Examples/Tests/ElectrostaticSphereEB/inputs_3d_mixed_BCs b/Examples/Tests/ElectrostaticSphereEB/inputs_3d_mixed_BCs
new file mode 100644
index 000000000..e695916a8
--- /dev/null
+++ b/Examples/Tests/ElectrostaticSphereEB/inputs_3d_mixed_BCs
@@ -0,0 +1,26 @@
+max_step = 1
+amr.n_cell = 64 64 64
+amr.max_level = 0
+amr.blocking_factor = 8
+amr.max_grid_size = 128
+geometry.coord_sys = 0
+boundary.field_lo = pec pec none
+boundary.field_hi = pec none none
+boundary.potential_lo_x = 0
+boundary.potential_hi_x = 0
+boundary.potential_lo_y = 0
+geometry.prob_lo = -0.5 -0.5 -0.5
+geometry.prob_hi = 0.5 0.5 0.5
+warpx.const_dt = 1e-6
+
+warpx.do_electrostatic = labframe
+warpx.eb_implicit_function = "-(x**2+y**2+z**2-0.3**2)"
+warpx.eb_potential(x,y,z,t) = "1."
+warpx.self_fields_required_precision = 1.e-7
+
+algo.field_gathering = momentum-conserving
+
+diagnostics.diags_names = diag1
+diag1.intervals = 1
+diag1.diag_type = Full
+diag1.fields_to_plot = Ex Ey Ez rho phi
diff --git a/Regression/Checksum/benchmarks_json/ElectrostaticSphereEB_mixedBCs.json b/Regression/Checksum/benchmarks_json/ElectrostaticSphereEB_mixedBCs.json
new file mode 100644
index 000000000..25f7d84ff
--- /dev/null
+++ b/Regression/Checksum/benchmarks_json/ElectrostaticSphereEB_mixedBCs.json
@@ -0,0 +1,9 @@
+{
+ "lev=0": {
+ "Ex": 283813.7210786634,
+ "Ey": 276797.73520225764,
+ "Ez": 269948.47265632026,
+ "phi": 58143.83034821785,
+ "rho": 0.0
+ }
+} \ No newline at end of file
diff --git a/Regression/WarpX-tests.ini b/Regression/WarpX-tests.ini
index 223090ad4..eab14fade 100644
--- a/Regression/WarpX-tests.ini
+++ b/Regression/WarpX-tests.ini
@@ -2065,6 +2065,23 @@ doVis = 0
compareParticles = 0
analysisRoutine = Examples/Tests/ElectrostaticSphereEB/analysis.py
+[ElectrostaticSphereEB_mixedBCs]
+buildDir = .
+inputFile = Examples/Tests/ElectrostaticSphereEB/inputs_3d_mixed_BCs
+runtime_params =
+dim = 3
+addToCompileString = USE_EB=TRUE
+restartTest = 0
+useMPI = 1
+numprocs = 2
+useOMP = 1
+numthreads = 2
+compileTest = 0
+doVis = 0
+compareParticles = 0
+analysisRoutine = Examples/analysis_default_regression.py
+tolerance = 1.e-12
+
[ElectrostaticSphere]
buildDir = .
inputFile = Examples/Tests/ElectrostaticSphere/inputs_3d
diff --git a/Source/FieldSolver/ElectrostaticSolver.H b/Source/FieldSolver/ElectrostaticSolver.H
index c9d1d0cc5..725407407 100644
--- a/Source/FieldSolver/ElectrostaticSolver.H
+++ b/Source/FieldSolver/ElectrostaticSolver.H
@@ -47,8 +47,8 @@ public:
amrex::Array<amrex::LinOpBCType,AMREX_SPACEDIM> lobc, hibc;
bool bcs_set = false;
- std::array<bool,AMREX_SPACEDIM> dirichlet_flag;
- bool has_Dirichlet = false;
+ std::array<bool,AMREX_SPACEDIM*2> dirichlet_flag;
+ bool has_non_periodic = false;
bool phi_EB_only_t = true;
void definePhiBCs ();
diff --git a/Source/FieldSolver/ElectrostaticSolver.cpp b/Source/FieldSolver/ElectrostaticSolver.cpp
index 9f376b7b2..b12f0cc8e 100644
--- a/Source/FieldSolver/ElectrostaticSolver.cpp
+++ b/Source/FieldSolver/ElectrostaticSolver.cpp
@@ -463,8 +463,8 @@ WarpX::setPhiBC( amrex::Vector<std::unique_ptr<amrex::MultiFab>>& phi,
Array<amrex::Real,AMREX_SPACEDIM>& phi_bc_values_lo,
Array<amrex::Real,AMREX_SPACEDIM>& phi_bc_values_hi ) const
{
- // check if any dimension has Dirichlet boundary conditions
- if (!field_boundary_handler.has_Dirichlet) return;
+ // check if any dimension has non-periodic boundary conditions
+ if (!field_boundary_handler.has_non_periodic) return;
auto dirichlet_flag = field_boundary_handler.dirichlet_flag;
@@ -485,8 +485,8 @@ WarpX::setPhiBC( amrex::Vector<std::unique_ptr<amrex::MultiFab>>& phi,
// loop over dimensions
for (int idim=0; idim<AMREX_SPACEDIM; idim++){
- // check if the boundary in this dimension should be set
- if (!dirichlet_flag[idim]) continue;
+ // check if neither boundaries in this dimension should be set
+ if (!(dirichlet_flag[2*idim] || dirichlet_flag[2*idim+1])) continue;
// a check can be added below to test if the boundary values
// are already correct, in which case the ParallelFor over the
@@ -498,10 +498,10 @@ WarpX::setPhiBC( amrex::Vector<std::unique_ptr<amrex::MultiFab>>& phi,
IntVect iv(AMREX_D_DECL(i,j,k));
- if (iv[idim] == domain.smallEnd(idim)){
+ if (dirichlet_flag[2*idim] && iv[idim] == domain.smallEnd(idim)){
phi_arr(i,j,k) = phi_bc_values_lo[idim];
}
- if (iv[idim] == domain.bigEnd(idim)) {
+ if (dirichlet_flag[2*idim+1] && iv[idim] == domain.bigEnd(idim)) {
phi_arr(i,j,k) = phi_bc_values_hi[idim];
}
@@ -720,6 +720,7 @@ void ElectrostaticSolver::BoundaryHandler::definePhiBCs ( )
lobc[0] = LinOpBCType::Neumann;
hibc[0] = LinOpBCType::Dirichlet;
dirichlet_flag[0] = false;
+ dirichlet_flag[1] = false;
int dim_start=1;
#else
int dim_start=0;
@@ -729,22 +730,40 @@ void ElectrostaticSolver::BoundaryHandler::definePhiBCs ( )
&& WarpX::field_boundary_hi[idim] == FieldBoundaryType::Periodic ) {
lobc[idim] = LinOpBCType::Periodic;
hibc[idim] = LinOpBCType::Periodic;
- dirichlet_flag[idim] = false;
- } else if ( WarpX::field_boundary_lo[idim] == FieldBoundaryType::PEC
- && WarpX::field_boundary_hi[idim] == FieldBoundaryType::PEC ) {
- // Ideally, we would often want open boundary conditions here.
- lobc[idim] = LinOpBCType::Dirichlet;
- hibc[idim] = LinOpBCType::Dirichlet;
-
- // set flag so we know which dimensions to fix the potential for
- dirichlet_flag[idim] = true;
- has_Dirichlet = true;
+ dirichlet_flag[idim*2] = false;
+ dirichlet_flag[idim*2+1] = false;
}
else {
- AMREX_ALWAYS_ASSERT_WITH_MESSAGE(false,
- "Field boundary conditions have to be either periodic or PEC "
- "when using the electrostatic solver"
- );
+ has_non_periodic = true;
+ if ( WarpX::field_boundary_lo[idim] == FieldBoundaryType::PEC ) {
+ lobc[idim] = LinOpBCType::Dirichlet;
+ dirichlet_flag[idim*2] = true;
+ }
+ else if ( WarpX::field_boundary_lo[idim] == FieldBoundaryType::None ) {
+ lobc[idim] = LinOpBCType::Neumann;
+ dirichlet_flag[idim*2] = false;
+ }
+ else {
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(false,
+ "Field boundary conditions have to be either periodic, PEC or none "
+ "when using the electrostatic solver"
+ );
+ }
+
+ if ( WarpX::field_boundary_hi[idim] == FieldBoundaryType::PEC ) {
+ hibc[idim] = LinOpBCType::Dirichlet;
+ dirichlet_flag[idim*2+1] = true;
+ }
+ else if ( WarpX::field_boundary_hi[idim] == FieldBoundaryType::None ) {
+ hibc[idim] = LinOpBCType::Neumann;
+ dirichlet_flag[idim*2+1] = false;
+ }
+ else {
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(false,
+ "Field boundary conditions have to be either periodic, PEC or none "
+ "when using the electrostatic solver"
+ );
+ }
}
}
bcs_set = true;