Alamo
Expression.H
Go to the documentation of this file.
1//
2// Boundary condition similar to BC::Constant, except that "values"
3// are given as strings which are functions of x,y,z,t.
4//
5
6#ifndef BC_EXPRESSION_H_
7#define BC_EXPRESSION_H_
8
9#include <AMReX_ParallelDescriptor.H>
10#include <AMReX_ParmParse.H>
11#include <AMReX_BCRec.H>
12#include <AMReX_PhysBCFunct.H>
13#include <AMReX_Array.H>
14#include <AMReX_Parser.H>
15
16#include "IO/ParmParse.H"
17#include "BC/BC.H"
18
19namespace BC
20{
22 : public BC<Set::Scalar>
23{
24public:
25 static constexpr const char* name = "expression";
26
27 //static constexpr const char* const Elastic::strings[];
28 #if AMREX_SPACEDIM==2
29 static const constexpr char * const facestr[] = {
30 "xlo","ylo","xhi","yhi"
31 };
32 #elif AMREX_SPACEDIM==3
33 static const constexpr char * const facestr[] = {
34 "xlo","ylo","zlo","xhi","yhi","zhi",
35 };
36 #endif
37
38#if AMREX_SPACEDIM==2
39 enum Face {
40 XLO, YLO, XHI, YHI,
41 INT
42 };
43#elif AMREX_SPACEDIM==3
44 enum Face {
45 XLO, YLO, ZLO, XHI, YHI, ZHI, // 6
46 INT
47 };
48#endif
49
50public:
51 //Constant (amrex::Vector<amrex::Geometry> &_geom) : geom(_geom) {};
52 Expression(int a_ncomp) : m_ncomp(a_ncomp) {};
53 Expression(int a_ncomp, IO::ParmParse& pp, std::string name) : m_ncomp(a_ncomp)
54 {
55 pp_queryclass(name, *this);
56 };
57
58 virtual ~Expression() {};
59
60 virtual void FillBoundary(amrex::BaseFab<Set::Scalar>& in, const amrex::Box& box,
61 int ngrow, int dcomp, int ncomp, amrex::Real time,
63 const amrex::Mask* mask = nullptr) override;
64
65 using BC::FillBoundary;
66
67 amrex::BCRec GetBCRec() override;
68 virtual amrex::Array<int, AMREX_SPACEDIM> IsPeriodic() override;
69 virtual amrex::Periodicity Periodicity() const override;
70 virtual amrex::Periodicity Periodicity(const amrex::Box& b) override;
71
72
73
74 template<class T>
75 const amrex::Array<amrex::Array<T, AMREX_SPACEDIM>, 2> GetBCTypes()
76 {
77 return { {{AMREX_D_DECL((T)m_bc_type[Face::XLO][0],(T)m_bc_type[Face::YLO][0],(T)m_bc_type[Face::ZLO][0])},
78 {AMREX_D_DECL((T)m_bc_type[Face::XLO][0],(T)m_bc_type[Face::YLO][0],(T)m_bc_type[Face::ZLO][0])}} };
79 }
80
81
82private:
83#if AMREX_SPACEDIM==2
84 static const int m_nfaces = 4;
85#elif AMREX_SPACEDIM==3
86 static const int m_nfaces = 6;
87#endif
88
89 unsigned int m_ncomp = 0;
90
91 std::array<std::vector<int>, m_nfaces> m_bc_type;
92 std::array<std::vector<amrex::Parser>, m_nfaces> m_bc_func_parser;
93 std::array<std::vector<amrex::ParserExecutor<4>>, m_nfaces> m_bc_func;
94
95 //std::array<std::vector<Numeric::Interpolator::Linear<Set::Scalar>>, m_nfaces> m_bc_val;
96
97public:
98 static void Parse(Expression& value, IO::ParmParse& pp)
99 {
100 std::map<std::string, int> bcmap;
101 bcmap["BOGUS_BC"] = amrex::BCType::mathematicalBndryTypes::bogus;
102 bcmap["INT_DIR"] = amrex::BCType::mathematicalBndryTypes::int_dir;
103 bcmap["REFLECT_ODD"] = amrex::BCType::mathematicalBndryTypes::reflect_odd;
104 bcmap["INT_DIR"] = amrex::BCType::mathematicalBndryTypes::int_dir;
105 bcmap["REFLECT_EVEN"] = amrex::BCType::mathematicalBndryTypes::reflect_even;
106 bcmap["FOEXTRAP"] = amrex::BCType::mathematicalBndryTypes::foextrap;
107 bcmap["EXT_DIR"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
108 bcmap["HOEXTRAP"] = amrex::BCType::mathematicalBndryTypes::hoextrap;
109 bcmap["Interior"] = amrex::BCType::mathematicalBndryTypes::int_dir;
110 bcmap["Inflow"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
111 bcmap["Outflow"] = amrex::BCType::mathematicalBndryTypes::foextrap;
112 bcmap["Symmetry"] = amrex::BCType::mathematicalBndryTypes::reflect_even;
113 bcmap["SlipWall"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
114 bcmap["NoSlipWall"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
115 // From <AMReX_LO_BCTYPES.H>
116 bcmap["interior"] = (int)amrex::LinOpBCType::interior;
117 bcmap["Dirichlet"] = (int)amrex::LinOpBCType::Dirichlet;
118 bcmap["dirichlet"] = (int)amrex::LinOpBCType::Dirichlet;
119 bcmap["Neumann"] = (int)amrex::LinOpBCType::Neumann;
120 bcmap["NEUMANN"] = (int)amrex::LinOpBCType::Neumann;
121 bcmap["neumann"] = (int)amrex::LinOpBCType::Neumann;
122 bcmap["reflect_odd"] = (int)amrex::LinOpBCType::reflect_odd;
123 bcmap["Marshak"] = (int)amrex::LinOpBCType::Marshak;
124 bcmap["SanchezPomraning"] = (int)amrex::LinOpBCType::SanchezPomraning;
125 bcmap["inflow"] = (int)amrex::LinOpBCType::inflow;
126 bcmap["Periodic"] = (int)amrex::LinOpBCType::Periodic;
127 bcmap["periodic"] = (int)amrex::LinOpBCType::Periodic;
128
129
130
131 // TYPES
132
133 std::vector<std::string> str;
134 pp_queryarr_default("type.xlo", str,"dirichlet"); // BC type on the lower x edge (2d) face (3d)
135 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Abort(INFO, "Invalid BC: ", str[i]);
136 if (str.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_type[Face::XLO].push_back(bcmap[str[i]]);
137 else if (str.size() == 1) value.m_bc_type[Face::XLO].resize(value.m_ncomp, bcmap[str[0]]);
138 else Util::Abort(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
139 pp_queryarr_default("type.xhi", str,"dirichlet"); // BC type on the upper x edge (2d) face (3d)
140 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Abort(INFO, "Invalid BC: ", str[i]);
141 if (str.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_type[Face::XHI].push_back(bcmap[str[i]]);
142 else if (str.size() == 1) value.m_bc_type[Face::XHI].resize(value.m_ncomp, bcmap[str[0]]);
143 else Util::Abort(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
144 pp_queryarr_default("type.ylo", str,"dirichlet"); // BC type on the lower y edge (2d) face (3d)
145 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Abort(INFO, "Invalid BC: ", str[i]);
146 if (str.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_type[Face::YLO].push_back(bcmap[str[i]]);
147 else if (str.size() == 1) value.m_bc_type[Face::YLO].resize(value.m_ncomp, bcmap[str[0]]);
148 else Util::Abort(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
149 pp_queryarr_default("type.yhi", str,"dirichlet"); // BC type on the upper y edge (2d) face (3d)
150 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Abort(INFO, "Invalid BC: ", str[i]);
151 if (str.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_type[Face::YHI].push_back(bcmap[str[i]]);
152 else if (str.size() == 1) value.m_bc_type[Face::YHI].resize(value.m_ncomp, bcmap[str[0]]);
153 else Util::Abort(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
154 pp_queryarr_default("type.zlo", str,"dirichlet"); // BC type on the lower z face (processed but ignored in 2d to prevent unused input errors)
155#if AMREX_SPACEDIM==3
156 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Abort(INFO, "Invalid BC: ", str[i]);
157 if (str.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_type[Face::ZLO].push_back(bcmap[str[i]]);
158 else if (str.size() == 1) value.m_bc_type[Face::ZLO].resize(value.m_ncomp, bcmap[str[0]]);
159 else Util::Abort(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
160#endif
161 pp_queryarr_default("type.zhi", str,"dirichlet"); // BC type on the upper z face (processed but ignored in 2d to prevent unused input errors)
162#if AMREX_SPACEDIM==3
163 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Abort(INFO, "Invalid BC: ", str[i]);
164 if (str.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_type[Face::ZHI].push_back(bcmap[str[i]]);
165 else if (str.size() == 1) value.m_bc_type[Face::ZHI].resize(value.m_ncomp, bcmap[str[0]]);
166 else Util::Abort(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
167#endif
168
169 // VALS
170 std::vector<std::string> val;
171 for (int face = 0; face != Face::INT; face++)
172 {
173 std::string querystr = std::string("val.") + std::string(facestr[face]);
174 if (pp.contains(querystr.c_str())) pp_queryarr(querystr.c_str(),val);
175 else val.resize(value.m_ncomp,"0.0");
176 if (val.size() != value.m_ncomp) Util::Abort(INFO,"Incorrect number of expressions specified for ",querystr,": expected 1 or ",value.m_ncomp," but received ",val.size());
177
178 value.m_bc_func_parser[face].clear();
179 value.m_bc_func[face].clear();
180 for (unsigned int i = 0 ; i < value.m_ncomp; i++)
181 {
182 value.m_bc_func_parser[face].push_back( amrex::Parser(val[i].c_str()) );
183 value.m_bc_func_parser[face][i].registerVariables({"x","y","z","t"});
184 value.m_bc_func[face].push_back( value.m_bc_func_parser[face][i].compile<4>() );
185 }
186 }
187
188#if AMREX_SPACEDIM==2
189 // We may wish to use an input file that has 3D BC inputs
190 // This will prevent the parser from complaining that there are unused inputs.
191 std::vector<std::string> ignore_in_2d = {
192 "zlo","zhi",
193 "zhixlo","zloxlo","zhixhi","zloxhi","ylozlo","ylozhi","yhizlo","yhizhi",
194 "xloylozlo","xloylozhi","xloyhizlo","xloyhizhi","xhiylozlo","xhiylozhi","xhiyhizlo","xhiyhizhi"};
195 for (unsigned int n = 0; n < ignore_in_2d.size(); n++)
196 {
197 std::string querystr = std::string("val.") + ignore_in_2d[n];
198 pp.ignore(querystr);
199 querystr = std::string("type.") + ignore_in_2d[n];
200 pp.ignore(querystr);
201 }
202#endif
203
204 }
205};
206}
207#endif
#define pp_queryarr(...)
Definition ParmParse.H:103
#define pp_queryarr_default(...)
Definition ParmParse.H:105
#define pp_queryclass(...)
Definition ParmParse.H:107
#define INFO
Definition Util.H:20
virtual void FillBoundary(amrex::BaseFab< T > &in, const amrex::Box &box, int ngrow, int dcomp, int ncomp, amrex::Real time, Orientation face=Orientation::All, const amrex::Mask *mask=nullptr)=0
std::array< std::vector< int >, m_nfaces > m_bc_type
Definition Expression.H:91
amrex::BCRec GetBCRec() override
virtual ~Expression()
Definition Expression.H:58
Expression(int a_ncomp, IO::ParmParse &pp, std::string name)
Definition Expression.H:53
virtual void FillBoundary(amrex::BaseFab< Set::Scalar > &in, const amrex::Box &box, int ngrow, int dcomp, int ncomp, amrex::Real time, Orientation face=Orientation::All, const amrex::Mask *mask=nullptr) override
Definition Expression.cpp:7
static void Parse(Expression &value, IO::ParmParse &pp)
Definition Expression.H:98
static constexpr const char * name
Definition Expression.H:25
const amrex::Array< amrex::Array< T, AMREX_SPACEDIM >, 2 > GetBCTypes()
Definition Expression.H:75
Expression(int a_ncomp)
Definition Expression.H:52
virtual amrex::Array< int, AMREX_SPACEDIM > IsPeriodic() override
std::array< std::vector< amrex::Parser >, m_nfaces > m_bc_func_parser
Definition Expression.H:92
std::array< std::vector< amrex::ParserExecutor< 4 > >, m_nfaces > m_bc_func
Definition Expression.H:93
unsigned int m_ncomp
Definition Expression.H:89
virtual amrex::Periodicity Periodicity() const override
bool contains(std::string name)
Definition ParmParse.H:154
std::string prefix()
Definition ParmParse.H:590
void ignore(std::string name)
Definition ParmParse.H:135
Collection of boundary condition (BC) objects.
Definition BC.cpp:5
Orientation
Definition BC.H:30
@ All
Definition BC.H:31
@ AMREX_D_DECL
Definition BC.H:32
@ Face
Definition Set.H:32
void Abort(const char *msg)
Definition Util.cpp:170