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