-
Notifications
You must be signed in to change notification settings - Fork 195
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
Add PECInsulator
boundary condition
#4943
Changes from all commits
841770b
cf6f799
145e628
607ba8e
60613fd
611c0df
7548cbe
5c4cfc2
9c8d11a
e4aa5ae
ab07778
ab6254b
b3d9266
f915879
1e8d517
82fdbe7
8c60a03
a2212aa
0846580
5498195
89837c6
1f5c72d
37cbb0d
16078d2
59fc8f0
0973a4e
0b25492
3163c2a
e074f45
2c3263c
ca50303
9a15278
f21e856
5b1a429
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Maximum number of time steps | ||
max_step = 10 | ||
|
||
# number of grid points | ||
amr.n_cell = 32 32 | ||
amr.blocking_factor = 16 | ||
|
||
# Maximum level in hierarchy (for now must be 0, i.e., one level in total) | ||
amr.max_level = 0 | ||
|
||
# Geometry | ||
geometry.dims = 2 | ||
geometry.prob_lo = 0. 2.e-2 # physical domain | ||
geometry.prob_hi = 1.e-2 3.e-2 | ||
|
||
# Boundary condition | ||
boundary.field_lo = neumann periodic | ||
boundary.field_hi = PECInsulator periodic | ||
|
||
warpx.serialize_initial_conditions = 1 | ||
|
||
# Verbosity | ||
warpx.verbose = 1 | ||
|
||
# CFL | ||
warpx.cfl = 1.0 | ||
|
||
insulator.area_x_hi(y,z) = (2.25e-2 <= z and z <= 2.75e-2) | ||
insulator.By_x_hi(y,z,t) = min(t/1.0e-12,1)*1.e1*3.3e-4 | ||
|
||
# Diagnostics | ||
diagnostics.diags_names = diag1 | ||
diag1.intervals = 10 | ||
diag1.diag_type = Full |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"lev=0": { | ||
"Bx": 0.0, | ||
"By": 0.34938851065132936, | ||
"Bz": 0.0, | ||
"Ex": 31871402.236828588, | ||
"Ey": 0.0, | ||
"Ez": 104908439.18998256, | ||
"jx": 0.0, | ||
"jy": 0.0, | ||
"jz": 0.0 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
#ifndef PEC_INSULATOR_H_ | ||
#define PEC_INSULATOR_H_ | ||
|
||
#include "Utils/WarpXAlgorithmSelection.H" | ||
|
||
#include <AMReX_Array.H> | ||
#include <AMReX_Geometry.H> | ||
#include <AMReX_Vector.H> | ||
|
||
#include <AMReX_BaseFwd.H> | ||
|
||
#include <array> | ||
#include <memory> | ||
|
||
class PEC_Insulator | ||
{ | ||
public: | ||
|
||
PEC_Insulator(); | ||
|
||
/** | ||
* \brief Apply either the PEC or insulator boundary condition on the boundary and in the | ||
* guard cells. | ||
* In the PEC, the nodal fields (in a Yee mesh) are made even relative to the boundary, | ||
* the non-nodal fields are made odd. | ||
* In the insulator, the tangential fields are set to the value if specified, otherwise unchanged, | ||
* and the normal fields extrapolated from the valid cells. | ||
* | ||
* \param[in,out] Efield | ||
* \param[in] field_boundary_lo lower field boundary conditions | ||
* \param[in] field_boundary_hi upper field boundary conditions | ||
* \param[in] ng_fieldgather number of guard cells used by field gather | ||
* \param[in] geom geometry object of level "lev" | ||
* \param[in] lev level of the Multifab | ||
* \param[in] patch_type coarse or fine | ||
* \param[in] ref_ratios vector containing the refinement ratios of the refinement levels | ||
* \param[in] time current time of the simulation | ||
* \param[in] split_pml_field whether pml the multifab is the regular Efield or | ||
* split pml field | ||
*/ | ||
void ApplyPEC_InsulatortoEfield (std::array<amrex::MultiFab*, 3> Efield, | ||
amrex::Array<FieldBoundaryType,AMREX_SPACEDIM> const & field_boundary_lo, | ||
amrex::Array<FieldBoundaryType,AMREX_SPACEDIM> const & field_boundary_hi, | ||
amrex::IntVect const & ng_fieldgather, amrex::Geometry const & geom, | ||
int lev, PatchType patch_type, amrex::Vector<amrex::IntVect> const & ref_ratios, | ||
amrex::Real time, | ||
bool split_pml_field = false); | ||
/** | ||
* \brief Apply either the PEC or insulator boundary condition on the boundary and in the | ||
* guard cells. | ||
* In the PEC, the nodal fields (in a Yee mesh) are made even relative to the boundary, | ||
* the non-nodal fields are made odd. | ||
* In the insulator, the tangential fields are set to the value if specified, otherwise unchanged, | ||
* and the normal fields extrapolated from the valid cells. | ||
* | ||
* \param[in,out] Bfield | ||
* \param[in] field_boundary_lo lower field boundary conditions | ||
* \param[in] field_boundary_hi upper field boundary conditions | ||
* \param[in] ng_fieldgather number of guard cells used by field gather | ||
* \param[in] geom geometry object of level "lev" | ||
* \param[in] lev level of the Multifab | ||
* \param[in] patch_type coarse or fine | ||
* \param[in] ref_ratios vector containing the refinement ratios of the refinement levels | ||
* \param[in] time current time of the simulation | ||
*/ | ||
void ApplyPEC_InsulatortoBfield (std::array<amrex::MultiFab*, 3> Bfield, | ||
amrex::Array<FieldBoundaryType,AMREX_SPACEDIM> const & field_boundary_lo, | ||
amrex::Array<FieldBoundaryType,AMREX_SPACEDIM> const & field_boundary_hi, | ||
amrex::IntVect const & ng_fieldgather, amrex::Geometry const & geom, | ||
int lev, PatchType patch_type, amrex::Vector<amrex::IntVect> const & ref_ratios, | ||
amrex::Real time); | ||
Comment on lines
+66
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why don't we need a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question. I copied this pattern from the PEC boundary conditions. Do you know why the split is done there? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah interesting, I don't know. I think this would be a question for @RevathiJambunathan or @roelof-groenewald. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pinging @RevathiJambunathan and @roelof-groenewald just to make sure that the PR doesn't get stalled. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Re-Pinging @RevathiJambunathan and @roelof-groenewald. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the slow response. It looks like the flag was introduced in #2541 to fix an observed bug when one boundary is PEC and an adjacent one is PML. @RevathiJambunathan would know better but I expect it is not needed to apply the same to the B-field since the update to the E-field ensures that the B-field values come out appropriately in the B-field push. |
||
|
||
/** | ||
* \brief The work routine applying the boundary condition | ||
* | ||
* \param[in,out] field | ||
* \param[in] field_boundary_lo lower field boundary conditions | ||
* \param[in] field_boundary_hi upper field boundary conditions | ||
* \param[in] ng_fieldgather number of guard cells used by field gather | ||
* \param[in] geom geometry object of level "lev" | ||
* \param[in] lev level of the Multifab | ||
* \param[in] patch_type coarse or fine | ||
* \param[in] ref_ratios vector containing the refinement ratios of the refinement levels | ||
* \param[in] time current time of the simulation | ||
* \param[in] split_pml_field whether pml the multifab is the regular Efield or | ||
* split pml field | ||
* \param[in] E_like whether the field is E like or B like | ||
* \param[in] set_F_x_lo whether the tangential field at the boundary was specified | ||
* \param[in] set_F_x_hi whether the tangential field at the boundary was specified | ||
* \param[in] a_Fy_x_lo the parser for the tangential field at the boundary | ||
* \param[in] a_Fz_x_lo the parser for the tangential field at the boundary | ||
* \param[in] a_Fy_x_hi the parser for the tangential field at the boundary | ||
* \param[in] a_Fz_x_hi the parser for the tangential field at the boundary | ||
* \param[in] set_F_y_lo whether the tangential field at the boundary was specified | ||
* \param[in] set_F_y_hi whether the tangential field at the boundary was specified | ||
* \param[in] a_Fx_y_lo the parser for the tangential field at the boundary | ||
* \param[in] a_Fz_y_lo the parser for the tangential field at the boundary | ||
* \param[in] a_Fx_y_hi the parser for the tangential field at the boundary | ||
* \param[in] a_Fz_y_hi the parser for the tangential field at the boundary | ||
* \param[in] set_F_z_lo whether the tangential field at the boundary was specified | ||
* \param[in] set_F_z_hi whether the tangential field at the boundary was specified | ||
* \param[in] a_Fx_z_lo the parser for the tangential field at the boundary | ||
* \param[in] a_Fy_z_lo the parser for the tangential field at the boundary | ||
* \param[in] a_Fx_z_hi the parser for the tangential field at the boundary | ||
* \param[in] a_Fy_z_hi the parser for the tangential field at the boundary | ||
*/ | ||
void | ||
ApplyPEC_InsulatortoField (std::array<amrex::MultiFab*, 3> field, | ||
amrex::Array<FieldBoundaryType,AMREX_SPACEDIM> const & field_boundary_lo, | ||
amrex::Array<FieldBoundaryType,AMREX_SPACEDIM> const & field_boundary_hi, | ||
amrex::IntVect const & ng_fieldgather, amrex::Geometry const & geom, | ||
int lev, PatchType patch_type, amrex::Vector<amrex::IntVect> const & ref_ratios, | ||
amrex::Real time, | ||
bool split_pml_field, | ||
bool E_like, | ||
#if (AMREX_SPACEDIM > 1) | ||
bool set_F_x_lo, bool set_F_x_hi, | ||
std::unique_ptr<amrex::Parser> const & a_Fy_x_lo, std::unique_ptr<amrex::Parser> const & a_Fz_x_lo, | ||
std::unique_ptr<amrex::Parser> const & a_Fy_x_hi, std::unique_ptr<amrex::Parser> const & a_Fz_x_hi, | ||
#endif | ||
#if defined(WARPX_DIM_3D) | ||
bool set_F_y_lo, bool set_F_y_hi, | ||
std::unique_ptr<amrex::Parser> const & a_Fx_y_lo, std::unique_ptr<amrex::Parser> const & a_Fz_y_lo, | ||
std::unique_ptr<amrex::Parser> const & a_Fx_y_hi, std::unique_ptr<amrex::Parser> const & a_Fz_y_hi, | ||
#endif | ||
bool set_F_z_lo, bool set_F_z_hi, | ||
std::unique_ptr<amrex::Parser> const & a_Fx_z_lo, std::unique_ptr<amrex::Parser> const & a_Fy_z_lo, | ||
std::unique_ptr<amrex::Parser> const & a_Fx_z_hi, std::unique_ptr<amrex::Parser> const & a_Fy_z_hi); | ||
|
||
private: | ||
|
||
/* \brief Reads in the parsers for the tangential fields, returning whether | ||
* the input parameter was specified. | ||
* \param[in] pp_insulator ParmParse instance | ||
* \param[out] parser the parser generated from the input | ||
* \param[in] input_name the name of the input parameter | ||
* \param[in] coord1 the first coordinate in the plane | ||
* \param[in] coord2 the second coordinate in the plane | ||
*/ | ||
bool ReadTangentialFieldParser (amrex::ParmParse const & pp_insulator, | ||
std::unique_ptr<amrex::Parser> & parser, | ||
std::string const & input_name, | ||
std::string const & coord1, | ||
std::string const & coord2); | ||
|
||
std::vector<std::unique_ptr<amrex::Parser>> m_insulator_area_lo; | ||
std::vector<std::unique_ptr<amrex::Parser>> m_insulator_area_hi; | ||
|
||
#if (AMREX_SPACEDIM > 1) | ||
bool m_set_B_x_lo = false, m_set_B_x_hi = false; | ||
std::unique_ptr<amrex::Parser> m_By_x_lo, m_Bz_x_lo; | ||
std::unique_ptr<amrex::Parser> m_By_x_hi, m_Bz_x_hi; | ||
#endif | ||
#if defined(WARPX_DIM_3D) | ||
bool m_set_B_y_lo = false, m_set_B_y_hi = false; | ||
std::unique_ptr<amrex::Parser> m_Bx_y_lo, m_Bz_y_lo; | ||
std::unique_ptr<amrex::Parser> m_Bx_y_hi, m_Bz_y_hi; | ||
#endif | ||
bool m_set_B_z_lo = false, m_set_B_z_hi = false; | ||
std::unique_ptr<amrex::Parser> m_Bx_z_lo, m_By_z_lo; | ||
std::unique_ptr<amrex::Parser> m_Bx_z_hi, m_By_z_hi; | ||
|
||
|
||
#if (AMREX_SPACEDIM > 1) | ||
bool m_set_E_x_lo = false, m_set_E_x_hi = false; | ||
std::unique_ptr<amrex::Parser> m_Ey_x_lo, m_Ez_x_lo; | ||
std::unique_ptr<amrex::Parser> m_Ey_x_hi, m_Ez_x_hi; | ||
#endif | ||
#if defined(WARPX_DIM_3D) | ||
bool m_set_E_y_lo = false, m_set_E_y_hi = false; | ||
std::unique_ptr<amrex::Parser> m_Ex_y_lo, m_Ez_y_lo; | ||
std::unique_ptr<amrex::Parser> m_Ex_y_hi, m_Ez_y_hi; | ||
#endif | ||
bool m_set_E_z_lo = false, m_set_E_z_hi = false; | ||
std::unique_ptr<amrex::Parser> m_Ex_z_lo, m_Ey_z_lo; | ||
std::unique_ptr<amrex::Parser> m_Ex_z_hi, m_Ey_z_hi; | ||
|
||
|
||
}; | ||
#endif // PEC_INSULATOR_H_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the complexity of the new feature, is there a physics analysis that can be done, beyond the checksums analysis?
Also, is this intentionally tested only in 2D? The implementation seems to be general for all dimensions, so maybe it could be worth adding tests for those as well. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test was copied from the test case for the same boundary condition in the picnic code. That code's primary use is 2D. I don't know of any physics analysis that could be done beyond checking that the fields at the boundary are as expected. I could add other cases that do that simple check.