Alamo
Constant.H
Go to the documentation of this file.
1//
2// This is the most commonly used standard boundary condition implementation.
3// The name "Constant" refers to the invariance of the BC value or character along each face
4// of the simulation domain; however, you may cause a change in the value with time by using a
5// :ref:`Numeric::Interpolator::Linear` string.
6//
7// The BC on each face is specified with a :code:`type` string that specifies the nature of
8// the BC, and a :code:`val` that specifies the value.
9// By default, all types are Dirichlet and all values are 0.0.
10// The complete list of BC types are below:
11//
12// `Dirichlet <https://en.wikipedia.org/wiki/Dirichlet_boundary_condition>`_ boundary condition
13// types can be specified with :code:`Dirichlet`, :code:`dirichlet`, :code:`EXT_DIR`.
14// `Neumann <https://en.wikipedia.org/wiki/Neumann_boundary_condition>`_ boundary condition
15// types are specified with :code:`Neumann`, :code:`neumann`.
16// `Periodic <https://en.wikipedia.org/wiki/Periodic_boundary_conditions>`_ boundary conditions
17// can be specified with :code:`Periodic`, :code:`periodic`, :code:`INT_DIR`.
18// **Important**: Ensure that your geometry is specified to be periodic using :code:`geometry.is_periodic`.
19// For instance, if periodic in x, set to :code:`1 0 0`
20//
21// The BC values can be specified either as a number (e.g. :code:`1.0`) or using a linear interpolator
22// string (e.g. :code:`(0,1:2.3,-0.1)`).
23//
24// The number of values and types must be either 0 (for defaults), 1 (to set the same for all field components)
25// or N (where N=number of field components).
26//
27
28#ifndef BC_CONSTANT_H_
29#define BC_CONSTANT_H_
30
31#include <AMReX_ParallelDescriptor.H>
32#include <AMReX_ParmParse.H>
33#include <AMReX_BCRec.H>
34#include <AMReX_PhysBCFunct.H>
35#include <AMReX_Array.H>
36
37#include "Set/Set.H"
38#include "BC/BC.H"
40
41namespace BC
42{
44 : public BC<Set::Scalar>
45{
46
47#if AMREX_SPACEDIM==2
48 enum Face {
49 XLO, YLO, XHI, YHI,
50 INT
51 };
52#elif AMREX_SPACEDIM==3
53 enum Face {
54 XLO, YLO, ZLO, XHI, YHI, ZHI, // 6
55 INT
56 };
57#endif
58
59public:
60 static constexpr const char* name = "constant";
61
62 //Constant (amrex::Vector<amrex::Geometry> &_geom) : geom(_geom) {};
63 Constant(int a_ncomp) : m_ncomp(a_ncomp) {};
64 Constant(int a_ncomp, IO::ParmParse& pp, std::string name) : m_ncomp(a_ncomp)
65 {
66 pp_queryclass(name, *this);
67 };
68 Constant(int ncomp, amrex::Vector<std::string> bc_hi_str,
69 amrex::Vector<std::string> bc_lo_str,
70 AMREX_D_DECL(amrex::Vector<amrex::Real> _bc_lo_1,
71 amrex::Vector<amrex::Real> _bc_lo_2,
72 amrex::Vector<amrex::Real> _bc_lo_3),
73 AMREX_D_DECL(amrex::Vector<amrex::Real> _bc_hi_1,
74 amrex::Vector<amrex::Real> _bc_hi_2,
75 amrex::Vector<amrex::Real> _bc_hi_3));
76
77 static Constant ZeroNeumann(int ncomp = 1)
78 {
79 Constant ret = Constant(ncomp);
80
81 for (int d = 0; d < m_nfaces; d++)
82 {
83 ret.m_bc_type[d].clear();
84 for (int n = 0; n < ncomp; n++)
85 {
86 ret.m_bc_type[d].push_back((int)amrex::LinOpBCType::Neumann);
87 ret.m_bc_val[d].push_back (0.0);;
88 }
89 }
90
91 return ret;
92 }
93
94 static Constant ZeroDirichlet(int ncomp = 1)
95 {
96 Constant ret = Constant(ncomp);
97
98 for (int d = 0; d < m_nfaces; d++)
99 for (int n = 0; n < ncomp; n++)
100 {
101 ret.m_bc_type[n][d] = (int)amrex::LinOpBCType::Dirichlet;
102 ret.m_bc_val [n][d] = 0.0;
103 }
104
105 return ret;
106 }
107
108
109 virtual ~Constant() {};
110
111 virtual void FillBoundary(amrex::BaseFab<Set::Scalar>& in, const amrex::Box& box,
112 int ngrow, int dcomp, int ncomp, amrex::Real time,
114 const amrex::Mask* mask = nullptr) override;
115
116 using BC::FillBoundary;
117
118 amrex::BCRec GetBCRec() override;
119 virtual amrex::Array<int, AMREX_SPACEDIM> IsPeriodic() override;
120 virtual amrex::Periodicity Periodicity() const override;
121 virtual amrex::Periodicity Periodicity(const amrex::Box& b) override;
122
123
124
125 template<class T>
126 const amrex::Array<amrex::Array<T, AMREX_SPACEDIM>, 2> GetBCTypes()
127 {
128 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])},
129 {AMREX_D_DECL((T)m_bc_type[Face::XLO][0],(T)m_bc_type[Face::YLO][0],(T)m_bc_type[Face::ZLO][0])}} };
130 }
131
132
133private:
134#if AMREX_SPACEDIM==2
135 static const int m_nfaces = 4;
136#elif AMREX_SPACEDIM==3
137 static const int m_nfaces = 6;
138#endif
139
140 unsigned int m_ncomp = 0;
141
142 //int bc_lo[BL_SPACEDIM];
143 //int bc_hi[BL_SPACEDIM];
144 //amrex::Vector<amrex::Real> AMREX_D_DECL(bc_lo_1, bc_lo_2, bc_lo_3);
145 //amrex::Vector<amrex::Real> AMREX_D_DECL(bc_hi_1, bc_hi_2, bc_hi_3);
146
147 std::array<std::vector<int>, m_nfaces> m_bc_type;
148 std::array<std::vector<Numeric::Interpolator::Linear<Set::Scalar>>, m_nfaces> m_bc_val;
149
150public:
151 static void Parse(Constant& value, IO::ParmParse& pp)
152 {
153 std::map<std::string, int> bcmap;
154 bcmap["BOGUS_BC"] = amrex::BCType::mathematicalBndryTypes::bogus;
155 bcmap["INT_DIR"] = amrex::BCType::mathematicalBndryTypes::int_dir;
156 bcmap["REFLECT_ODD"] = amrex::BCType::mathematicalBndryTypes::reflect_odd;
157 bcmap["INT_DIR"] = amrex::BCType::mathematicalBndryTypes::int_dir;
158 bcmap["REFLECT_EVEN"] = amrex::BCType::mathematicalBndryTypes::reflect_even;
159 bcmap["FOEXTRAP"] = amrex::BCType::mathematicalBndryTypes::foextrap;
160 bcmap["EXT_DIR"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
161 bcmap["HOEXTRAP"] = amrex::BCType::mathematicalBndryTypes::hoextrap;
162 bcmap["Interior"] = amrex::BCType::mathematicalBndryTypes::int_dir;
163 bcmap["Inflow"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
164 bcmap["Outflow"] = amrex::BCType::mathematicalBndryTypes::foextrap;
165 bcmap["Symmetry"] = amrex::BCType::mathematicalBndryTypes::reflect_even;
166 bcmap["SlipWall"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
167 bcmap["NoSlipWall"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
168 // From <AMReX_LO_BCTYPES.H>
169 bcmap["interior"] = (int)amrex::LinOpBCType::interior;
170 bcmap["Dirichlet"] = (int)amrex::LinOpBCType::Dirichlet;
171 bcmap["dirichlet"] = (int)amrex::LinOpBCType::Dirichlet;
172 bcmap["Neumann"] = (int)amrex::LinOpBCType::Neumann;
173 bcmap["NEUMANN"] = (int)amrex::LinOpBCType::Neumann;
174 bcmap["neumann"] = (int)amrex::LinOpBCType::Neumann;
175 bcmap["reflect_odd"] = (int)amrex::LinOpBCType::reflect_odd;
176 bcmap["Marshak"] = (int)amrex::LinOpBCType::Marshak;
177 bcmap["SanchezPomraning"] = (int)amrex::LinOpBCType::SanchezPomraning;
178 bcmap["inflow"] = (int)amrex::LinOpBCType::inflow;
179 bcmap["Periodic"] = (int)amrex::LinOpBCType::Periodic;
180 bcmap["periodic"] = (int)amrex::LinOpBCType::Periodic;
181
182
183
184 value.m_bc_type[Face::XLO].clear(); value.m_bc_val[Face::XLO].clear();
185 value.m_bc_type[Face::XHI].clear(); value.m_bc_val[Face::XHI].clear();
186 value.m_bc_type[Face::YLO].clear(); value.m_bc_val[Face::YLO].clear();
187 value.m_bc_type[Face::YHI].clear(); value.m_bc_val[Face::YHI].clear();
188#if AMREX_SPACEDIM == 3
189 value.m_bc_type[Face::ZLO].clear(); value.m_bc_val[Face::ZLO].clear();
190 value.m_bc_type[Face::ZHI].clear(); value.m_bc_val[Face::ZHI].clear();
191#endif
192
193 // TYPES
194
195 std::vector<std::string> str;
196 pp_queryarr_default("type.xlo", str,"dirichlet"); // BC type on the lower x edge (2d) face (3d)
197 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
198 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]]);
199 else if (str.size() == 1) value.m_bc_type[Face::XLO].resize(value.m_ncomp, bcmap[str[0]]);
200 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
201 pp_queryarr_default("type.xhi", str,"dirichlet"); // BC type on the upper x edge (2d) face (3d)
202 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
203 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]]);
204 else if (str.size() == 1) value.m_bc_type[Face::XHI].resize(value.m_ncomp, bcmap[str[0]]);
205 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
206 pp_queryarr_default("type.ylo", str,"dirichlet"); // BC type on the lower y edge (2d) face (3d)
207 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
208 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]]);
209 else if (str.size() == 1) value.m_bc_type[Face::YLO].resize(value.m_ncomp, bcmap[str[0]]);
210 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
211 pp_queryarr_default("type.yhi", str,"dirichlet"); // BC type on the upper y edge (2d) face (3d)
212 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
213 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]]);
214 else if (str.size() == 1) value.m_bc_type[Face::YHI].resize(value.m_ncomp, bcmap[str[0]]);
215 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
216 pp_queryarr_default("type.zlo", str,"dirichlet"); // BC type on the lower z face (processed but ignored in 2d to prevent unused input errors)
217#if AMREX_SPACEDIM==3
218 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
219 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]]);
220 else if (str.size() == 1) value.m_bc_type[Face::ZLO].resize(value.m_ncomp, bcmap[str[0]]);
221 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
222#endif
223 pp_queryarr_default("type.zhi", str,"dirichlet"); // BC type on the upper z face (processed but ignored in 2d to prevent unused input errors)
224#if AMREX_SPACEDIM==3
225 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
226 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]]);
227 else if (str.size() == 1) value.m_bc_type[Face::ZHI].resize(value.m_ncomp, bcmap[str[0]]);
228 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
229#endif
230
231 // VALS
232 std::vector<std::string> val;
233 value.m_bc_val[Face::XLO].clear();
234 pp_queryarr_default("val.xlo", val,"0.0"); // BC value on the lower x edge (2d) face (3d)
235 if (val.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_val[Face::XLO].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i]));
236 else if (val.size() == 1) value.m_bc_val[Face::XLO].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
237 else if (val.size() == 0) value.m_bc_val[Face::XLO].resize(value.m_ncomp, 0.0);
238 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
239 value.m_bc_val[Face::XHI].clear();
240 pp_queryarr_default("val.xhi", val,"0.0"); // BC value on the upper x edge (2d) face (3d)
241 if (val.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_val[Face::XHI].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i]));
242 else if (val.size() == 1) value.m_bc_val[Face::XHI].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
243 else if (val.size() == 0) value.m_bc_val[Face::XHI].resize(value.m_ncomp, 0.0);
244 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
245 value.m_bc_val[Face::YLO].clear();
246 pp_queryarr_default("val.ylo", val,"0.0"); // BC value on the lower y edge (2d) face (3d)
247 if (val.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_val[Face::YLO].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i]));
248 else if (val.size() == 1) value.m_bc_val[Face::YLO].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
249 else if (val.size() == 0) value.m_bc_val[Face::YLO].resize(value.m_ncomp, 0.0);
250 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
251 value.m_bc_val[Face::YHI].clear();
252 pp_queryarr_default("val.yhi", val,"0.0"); // BC value on the upper y edge (2d) face (3d)
253 if (val.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_val[Face::YHI].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i]));
254 else if (val.size() == 1) value.m_bc_val[Face::YHI].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
255 else if (val.size() == 0) value.m_bc_val[Face::YHI].resize(value.m_ncomp, 0.0);
256 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
257 pp_queryarr_default("val.zlo", val,"0.0"); // BC value on the lower z face (processed but ignored in 2d to prevent unused input errors)
258#if AMREX_SPACEDIM==3
259 value.m_bc_val[Face::ZLO].clear();
260 if (val.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_val[Face::ZLO].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i]));
261 else if (val.size() == 1) value.m_bc_val[Face::ZLO].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
262 else if (val.size() == 0) value.m_bc_val[Face::ZLO].resize(value.m_ncomp, 0.0);
263 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
264#endif
265 pp_queryarr_default("val.zhi", val,"0.0"); // BC value on the upper z face (processed but ignored in 2d to prevent unused input errors)
266#if AMREX_SPACEDIM==3
267 value.m_bc_val[Face::ZHI].clear();
268 if (val.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_val[Face::ZHI].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i]));
269 else if (val.size() == 1) value.m_bc_val[Face::ZHI].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
270 else if (val.size() == 0) value.m_bc_val[Face::ZHI].resize(value.m_ncomp, 0.0);
271 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
272#endif
273 }
274
275};
276}
277#endif
#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 Constant.H:147
unsigned int m_ncomp
Definition Constant.H:140
amrex::BCRec GetBCRec() override
Definition Constant.cpp:188
Constant(int a_ncomp, IO::ParmParse &pp, std::string name)
Definition Constant.H:64
virtual amrex::Periodicity Periodicity() const override
Definition Constant.cpp:203
static Constant ZeroDirichlet(int ncomp=1)
Definition Constant.H:94
static constexpr const char * name
Definition Constant.H:60
Constant(int a_ncomp)
Definition Constant.H:63
static void Parse(Constant &value, IO::ParmParse &pp)
Definition Constant.H:151
virtual ~Constant()
Definition Constant.H:109
std::array< std::vector< Numeric::Interpolator::Linear< Set::Scalar > >, m_nfaces > m_bc_val
Definition Constant.H:148
const amrex::Array< amrex::Array< T, AMREX_SPACEDIM >, 2 > GetBCTypes()
Definition Constant.H:126
static Constant ZeroNeumann(int ncomp=1)
Definition Constant.H:77
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 Constant.cpp:59
virtual amrex::Array< int, AMREX_SPACEDIM > IsPeriodic() override
Definition Constant.cpp:197
std::string prefix()
Definition ParmParse.H:619
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
void Exception(std::string file, std::string func, int line, Args const &... args)
Definition Util.H:205