-
Notifications
You must be signed in to change notification settings - Fork 201
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
Move external field parameters out of WarpX class #4441
Changes from 6 commits
ce9896c
c6072d1
c1f29a7
a4892a7
731f8e4
becdfce
209c9a7
3cb54bc
e160fb8
a31783f
2925d6f
6054cb9
b658458
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,70 @@ | ||
/* Copyright 2023 Luca Fedeli | ||
* | ||
* | ||
* This file is part of WarpX. | ||
* | ||
* License: BSD-3-Clause-LBNL | ||
*/ | ||
#ifndef EXTERNAL_FIELD_H_ | ||
#define EXTERNAL_FIELD_H_ | ||
|
||
#include "ExternalField_fwd.H" | ||
|
||
#include <AMReX_Array.H> | ||
#include <AMReX_ParmParse.H> | ||
#include <AMReX_REAL.H> | ||
|
||
#include <memory> | ||
#include <string> | ||
|
||
enum class ExternalFieldType | ||
{ | ||
default_zero, | ||
constant, | ||
parse_ext_grid_function, | ||
read_from_file | ||
}; | ||
|
||
/** | ||
* \brief Struct to store data related to external electromagnetic fields | ||
* (flags, field values, and field parsers) | ||
*/ | ||
struct ExternalFieldParams | ||
{ | ||
//! Initial electric field on the grid | ||
amrex::GpuArray<amrex::Real,3> E_external_grid = {0,0,0}; | ||
//! Initial magnetic field on the grid | ||
amrex::GpuArray<amrex::Real,3> B_external_grid = {0,0,0}; | ||
|
||
//! Initialization type for external magnetic field on the grid | ||
ExternalFieldType B_ext_grid_type = ExternalFieldType::default_zero; | ||
//! Initialization type for external electric field on the grid | ||
ExternalFieldType E_ext_grid_type = ExternalFieldType::default_zero; | ||
|
||
//! User-defined parser to initialize x-component of the magnetic field on the grid | ||
std::unique_ptr<amrex::Parser> Bxfield_parser; | ||
//! User-defined parser to initialize y-component of the magnetic field on the grid | ||
std::unique_ptr<amrex::Parser> Byfield_parser; | ||
//! User-defined parser to initialize z-component of the magnetic field on the grid | ||
std::unique_ptr<amrex::Parser> Bzfield_parser; | ||
//! User-defined parser to initialize x-component of the electric field on the grid | ||
std::unique_ptr<amrex::Parser> Exfield_parser; | ||
//! User-defined parser to initialize y-component of the electric field on the grid | ||
std::unique_ptr<amrex::Parser> Eyfield_parser; | ||
//! User-defined parser to initialize z-component of the electric field on the grid | ||
std::unique_ptr<amrex::Parser> Ezfield_parser; | ||
|
||
//! Path of the file where external fields are stored | ||
std::string external_fields_path; | ||
}; | ||
|
||
/** | ||
* \brief This function reads the ExternalField data, initializes an ExternalFieldParams struct and returns | ||
* a unique pointer containing the initialized struct. "pp_warpx" must point at | ||
* the "warpx" parameter group in the inputfile. | ||
* | ||
*/ | ||
[[nodiscard]] std::unique_ptr<ExternalFieldParams> | ||
ReadExternalFieldParams(const amrex::ParmParse& pp_warpx); | ||
|
||
#endif //EXTERNAL_FIELD_H_ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
/* Copyright 2023 Luca Fedeli | ||
* | ||
* | ||
* This file is part of WarpX. | ||
* | ||
* License: BSD-3-Clause-LBNL | ||
*/ | ||
|
||
#include "ExternalField.H" | ||
|
||
#include "Utils/TextMsg.H" | ||
#include "Utils/Parser/ParserUtils.H" | ||
|
||
#include <ablastr/warn_manager/WarnManager.H> | ||
|
||
#include <algorithm> | ||
#include <vector> | ||
|
||
namespace | ||
{ | ||
|
||
enum class EMFieldType{E, B}; | ||
|
||
template <EMFieldType T> | ||
ExternalFieldType string_to_external_field_type(std::string s) | ||
{ | ||
std::transform(s.begin(), s.end(), s.begin(), ::tolower); | ||
|
||
if ( s.empty() || s == "default") | ||
return ExternalFieldType::default_zero; | ||
else if ( s == "constant") | ||
return ExternalFieldType::constant; | ||
else if ( s == "parse_b_ext_grid_function" || s == "parse_e_ext_grid_function") | ||
return ExternalFieldType::parse_ext_grid_function; | ||
else if ( s == "read_from_file") | ||
return ExternalFieldType::read_from_file; | ||
else | ||
WARPX_ABORT_WITH_MESSAGE( | ||
"'" + s + "' is an unknown external field type!"); | ||
|
||
if constexpr (T == EMFieldType::E){ | ||
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. The logic here doesn't look correct. Since the above 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. I've moved the check before this block. As you remarked, the logic was wrong and the second if block was ignored. |
||
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(s != "parse_b_ext_grid_function", | ||
"parse_B_ext_grid_function can be used only for B_ext_grid_init_style"); | ||
} | ||
else{ | ||
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(s != "parse_e_ext_grid_function", | ||
"parse_E_ext_grid_function can be used only for E_ext_grid_init_style"); | ||
} | ||
|
||
return ExternalFieldType::default_zero; | ||
} | ||
} | ||
|
||
std::unique_ptr<ExternalFieldParams> ReadExternalFieldParams(const amrex::ParmParse& pp_warpx) | ||
lucafedeli88 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
auto p_external_field = std::make_unique<ExternalFieldParams>(); | ||
|
||
// default values of E_external_grid and B_external_grid | ||
// are used to set the E and B field when "constant" or | ||
// "parser" is not explicitly used in the input. | ||
std::string B_ext_grid_s; | ||
pp_warpx.query("B_ext_grid_init_style", B_ext_grid_s); | ||
p_external_field->B_ext_grid_type = string_to_external_field_type<EMFieldType::B>(B_ext_grid_s); | ||
|
||
std::string E_ext_grid_s; | ||
pp_warpx.query("E_ext_grid_init_style", E_ext_grid_s); | ||
p_external_field->E_ext_grid_type = string_to_external_field_type<EMFieldType::E>(E_ext_grid_s); | ||
|
||
// | ||
// Constant external field | ||
// | ||
|
||
// if the input string is "constant", the values for the | ||
// external grid must be provided in the input. | ||
auto v_B = std::vector<amrex::Real>(3); | ||
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. Is there a reason for the temporary vector, instead of doing 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. Yes. The reason is that |
||
if (p_external_field->B_ext_grid_type == ExternalFieldType::constant) | ||
utils::parser::getArrWithParser(pp_warpx, "B_external_grid", v_B); | ||
std::copy(v_B.begin(), v_B.end(), p_external_field->B_external_grid.begin()); | ||
|
||
// if the input string is "constant", the values for the | ||
// external grid must be provided in the input. | ||
auto v_E = std::vector<amrex::Real>(3); | ||
if (p_external_field->E_ext_grid_type == ExternalFieldType::constant) | ||
utils::parser::getArrWithParser(pp_warpx, "E_external_grid", v_E); | ||
std::copy(v_E.begin(), v_E.end(), p_external_field->E_external_grid.begin()); | ||
//___________________________________________________________________________ | ||
|
||
|
||
// | ||
// External E field with parser | ||
// | ||
|
||
// if the input string for the B-field is "parse_b_ext_grid_function", | ||
// then the analytical expression or function must be | ||
// provided in the input file. | ||
if (p_external_field->B_ext_grid_type == ExternalFieldType::parse_ext_grid_function) { | ||
|
||
//! Strings storing parser function to initialize the components of the magnetic field on the grid | ||
std::string str_Bx_ext_grid_function; | ||
std::string str_By_ext_grid_function; | ||
std::string str_Bz_ext_grid_function; | ||
|
||
#ifdef WARPX_DIM_RZ | ||
std::stringstream warnMsg; | ||
warnMsg << "Parser for external B (r and theta) fields does not work with RZ\n" | ||
<< "The initial Br and Bt fields are currently hardcoded to 0.\n" | ||
<< "The initial Bz field should only be a function of z.\n"; | ||
ablastr::warn_manager::WMRecordWarning( | ||
"Inputs", warnMsg.str(), ablastr::warn_manager::WarnPriority::high); | ||
str_Bx_ext_grid_function = "0"; | ||
str_By_ext_grid_function = "0"; | ||
#else | ||
utils::parser::Store_parserString(pp_warpx, "Bx_external_grid_function(x,y,z)", | ||
str_Bx_ext_grid_function); | ||
utils::parser::Store_parserString(pp_warpx, "By_external_grid_function(x,y,z)", | ||
str_By_ext_grid_function); | ||
#endif | ||
utils::parser::Store_parserString(pp_warpx, "Bz_external_grid_function(x,y,z)", | ||
str_Bz_ext_grid_function); | ||
|
||
p_external_field->Bxfield_parser = std::make_unique<amrex::Parser>( | ||
utils::parser::makeParser(str_Bx_ext_grid_function,{"x","y","z"})); | ||
p_external_field->Byfield_parser = std::make_unique<amrex::Parser>( | ||
utils::parser::makeParser(str_By_ext_grid_function,{"x","y","z"})); | ||
p_external_field->Bzfield_parser = std::make_unique<amrex::Parser>( | ||
utils::parser::makeParser(str_Bz_ext_grid_function,{"x","y","z"})); | ||
} | ||
//___________________________________________________________________________ | ||
|
||
|
||
// | ||
// External B field with parser | ||
// | ||
|
||
// if the input string for the E-field is "parse_e_ext_grid_function", | ||
// then the analytical expression or function must be | ||
// provided in the input file. | ||
if (p_external_field->E_ext_grid_type == ExternalFieldType::parse_ext_grid_function) { | ||
|
||
#ifdef WARPX_DIM_RZ | ||
WARPX_ABORT_WITH_MESSAGE( | ||
"E parser for external fields does not work with RZ -- TO DO"); | ||
#endif | ||
|
||
//! Strings storing parser function to initialize the components of the electric field on the grid | ||
std::string str_Ex_ext_grid_function; | ||
std::string str_Ey_ext_grid_function; | ||
std::string str_Ez_ext_grid_function; | ||
|
||
utils::parser::Store_parserString(pp_warpx, "Ex_external_grid_function(x,y,z)", | ||
str_Ex_ext_grid_function); | ||
utils::parser::Store_parserString(pp_warpx, "Ey_external_grid_function(x,y,z)", | ||
str_Ey_ext_grid_function); | ||
utils::parser::Store_parserString(pp_warpx, "Ez_external_grid_function(x,y,z)", | ||
str_Ez_ext_grid_function); | ||
|
||
p_external_field->Exfield_parser = std::make_unique<amrex::Parser>( | ||
utils::parser::makeParser(str_Ex_ext_grid_function,{"x","y","z"})); | ||
p_external_field->Eyfield_parser = std::make_unique<amrex::Parser>( | ||
utils::parser::makeParser(str_Ey_ext_grid_function,{"x","y","z"})); | ||
p_external_field->Ezfield_parser = std::make_unique<amrex::Parser>( | ||
utils::parser::makeParser(str_Ez_ext_grid_function,{"x","y","z"})); | ||
} | ||
//___________________________________________________________________________ | ||
|
||
|
||
// | ||
// External fields from file | ||
// | ||
|
||
if (p_external_field->E_ext_grid_type == ExternalFieldType::read_from_file || | ||
p_external_field->B_ext_grid_type == ExternalFieldType::read_from_file){ | ||
std::string read_fields_from_path="./"; | ||
pp_warpx.query("read_fields_from_path", p_external_field->external_fields_path); | ||
} | ||
//___________________________________________________________________________ | ||
|
||
return p_external_field; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* Copyright 2023 Luca Fedeli | ||
* | ||
* | ||
* This file is part of WarpX. | ||
* | ||
* License: BSD-3-Clause-LBNL | ||
*/ | ||
#ifndef EXTERNAL_FIELD_FWD_H_ | ||
#define EXTERNAL_FIELD_FWD_H_ | ||
|
||
#include <AMReX_Parser.H> | ||
lucafedeli88 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#include <AMReX_REAL.H> | ||
#include <AMReX_Vector.H> | ||
|
||
#include <memory> | ||
#include <string> | ||
|
||
struct ExternalFieldParams; | ||
|
||
#endif //EXTERNAL_FIELD_FWD_H_ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,12 @@ | ||
CEXE_sources += WarpXAMReXInit.cpp | ||
CEXE_sources += WarpXInitData.cpp | ||
CEXE_sources += PlasmaInjector.cpp | ||
CEXE_sources += ExternalField.cpp | ||
CEXE_sources += GetTemperature.cpp | ||
CEXE_sources += GetVelocity.cpp | ||
CEXE_sources += InjectorDensity.cpp | ||
CEXE_sources += InjectorMomentum.cpp | ||
CEXE_sources += PlasmaInjector.cpp | ||
CEXE_sources += TemperatureProperties.cpp | ||
CEXE_sources += GetTemperature.cpp | ||
CEXE_sources += VelocityProperties.cpp | ||
CEXE_sources += GetVelocity.cpp | ||
CEXE_sources += WarpXAMReXInit.cpp | ||
CEXE_sources += WarpXInitData.cpp | ||
|
||
VPATH_LOCATIONS += $(WARPX_HOME)/Source/Initialization |
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.
It has been suggested as a standard to always use curly braces and not have single line
if
blocks.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.
I am not sure that we follow this rule systematically in WarpX, but it is certainly a good practice! I've added the curly braces.