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, Unit a_unit = Unit::Less()) : m_ncomp(a_ncomp), unit(a_unit) {};
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 a_ncomp, Unit a_unit, IO::ParmParse& pp, std::string name) :
69 m_ncomp(a_ncomp), unit(a_unit)
70 {
71 pp.queryclass(name, *this);
72 };
73 Constant(int ncomp, amrex::Vector<std::string> bc_hi_str,
74 amrex::Vector<std::string> bc_lo_str,
75 AMREX_D_DECL(amrex::Vector<amrex::Real> _bc_lo_1,
76 amrex::Vector<amrex::Real> _bc_lo_2,
77 amrex::Vector<amrex::Real> _bc_lo_3),
78 AMREX_D_DECL(amrex::Vector<amrex::Real> _bc_hi_1,
79 amrex::Vector<amrex::Real> _bc_hi_2,
80 amrex::Vector<amrex::Real> _bc_hi_3));
81
82 class ZeroNeumann;
83 class ZeroDirichlet;
84
85 virtual ~Constant() {};
86
87 virtual void FillBoundary(amrex::BaseFab<Set::Scalar>& in, const amrex::Box& box,
88 int ngrow, int dcomp, int ncomp, amrex::Real time,
90 const amrex::Mask* mask = nullptr) override;
91
92 using BC::FillBoundary;
93
94 amrex::BCRec GetBCRec() override;
95 virtual amrex::Array<int, AMREX_SPACEDIM> IsPeriodic() override;
96 virtual amrex::Periodicity Periodicity() const override;
97 virtual amrex::Periodicity Periodicity(const amrex::Box& b) override;
98
99
100
101 template<class T>
102 const amrex::Array<amrex::Array<T, AMREX_SPACEDIM>, 2> GetBCTypes()
103 {
104 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])},
105 {AMREX_D_DECL((T)m_bc_type[Face::XLO][0],(T)m_bc_type[Face::YLO][0],(T)m_bc_type[Face::ZLO][0])}} };
106 }
107
108
109protected:
110#if AMREX_SPACEDIM==2
111 static const int m_nfaces = 4;
112#elif AMREX_SPACEDIM==3
113 static const int m_nfaces = 6;
114#endif
115
116 unsigned int m_ncomp = 0;
118
119 //int bc_lo[BL_SPACEDIM];
120 //int bc_hi[BL_SPACEDIM];
121 //amrex::Vector<amrex::Real> AMREX_D_DECL(bc_lo_1, bc_lo_2, bc_lo_3);
122 //amrex::Vector<amrex::Real> AMREX_D_DECL(bc_hi_1, bc_hi_2, bc_hi_3);
123
124 std::array<std::vector<int>, m_nfaces> m_bc_type;
125 std::array<std::vector<Numeric::Interpolator::Linear<Set::Scalar>>, m_nfaces> m_bc_val;
126
127public:
128 static void Parse(Constant& value, IO::ParmParse& pp)
129 {
130 std::map<std::string, int> bcmap;
131 bcmap["BOGUS_BC"] = amrex::BCType::mathematicalBndryTypes::bogus;
132 bcmap["INT_DIR"] = amrex::BCType::mathematicalBndryTypes::int_dir;
133 bcmap["REFLECT_ODD"] = amrex::BCType::mathematicalBndryTypes::reflect_odd;
134 bcmap["INT_DIR"] = amrex::BCType::mathematicalBndryTypes::int_dir;
135 bcmap["REFLECT_EVEN"] = amrex::BCType::mathematicalBndryTypes::reflect_even;
136 bcmap["FOEXTRAP"] = amrex::BCType::mathematicalBndryTypes::foextrap;
137 bcmap["EXT_DIR"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
138 bcmap["HOEXTRAP"] = amrex::BCType::mathematicalBndryTypes::hoextrap;
139 bcmap["Interior"] = amrex::BCType::mathematicalBndryTypes::int_dir;
140 bcmap["Inflow"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
141 bcmap["Outflow"] = amrex::BCType::mathematicalBndryTypes::foextrap;
142 bcmap["Symmetry"] = amrex::BCType::mathematicalBndryTypes::reflect_even;
143 bcmap["SlipWall"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
144 bcmap["NoSlipWall"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
145 // From <AMReX_LO_BCTYPES.H>
146 bcmap["interior"] = (int)amrex::LinOpBCType::interior;
147 bcmap["Dirichlet"] = (int)amrex::LinOpBCType::Dirichlet;
148 bcmap["dirichlet"] = (int)amrex::LinOpBCType::Dirichlet;
149 bcmap["Neumann"] = (int)amrex::LinOpBCType::Neumann;
150 bcmap["NEUMANN"] = (int)amrex::LinOpBCType::Neumann;
151 bcmap["neumann"] = (int)amrex::LinOpBCType::Neumann;
152 bcmap["reflect_odd"] = (int)amrex::LinOpBCType::reflect_odd;
153 bcmap["Marshak"] = (int)amrex::LinOpBCType::Marshak;
154 bcmap["SanchezPomraning"] = (int)amrex::LinOpBCType::SanchezPomraning;
155 bcmap["inflow"] = (int)amrex::LinOpBCType::inflow;
156 bcmap["Periodic"] = (int)amrex::LinOpBCType::Periodic;
157 bcmap["periodic"] = (int)amrex::LinOpBCType::Periodic;
158
159
160
161 value.m_bc_type[Face::XLO].clear(); value.m_bc_val[Face::XLO].clear();
162 value.m_bc_type[Face::XHI].clear(); value.m_bc_val[Face::XHI].clear();
163 value.m_bc_type[Face::YLO].clear(); value.m_bc_val[Face::YLO].clear();
164 value.m_bc_type[Face::YHI].clear(); value.m_bc_val[Face::YHI].clear();
165#if AMREX_SPACEDIM == 3
166 value.m_bc_type[Face::ZLO].clear(); value.m_bc_val[Face::ZLO].clear();
167 value.m_bc_type[Face::ZHI].clear(); value.m_bc_val[Face::ZHI].clear();
168#endif
169
170 // TYPES
171
172 std::vector<std::string> str;
173 pp.queryarr_default("type.xlo", str,{"dirichlet"}); // BC type on the lower x edge (2d) face (3d)
174 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
175 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]]);
176 else if (str.size() == 1) value.m_bc_type[Face::XLO].resize(value.m_ncomp, bcmap[str[0]]);
177 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
178 pp.queryarr_default("type.xhi", str,{"dirichlet"}); // BC type on the upper x edge (2d) face (3d)
179 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
180 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]]);
181 else if (str.size() == 1) value.m_bc_type[Face::XHI].resize(value.m_ncomp, bcmap[str[0]]);
182 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
183 pp.queryarr_default("type.ylo", str,{"dirichlet"}); // BC type on the lower y edge (2d) face (3d)
184 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
185 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]]);
186 else if (str.size() == 1) value.m_bc_type[Face::YLO].resize(value.m_ncomp, bcmap[str[0]]);
187 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
188 pp.queryarr_default("type.yhi", str,{"dirichlet"}); // BC type on the upper y edge (2d) face (3d)
189 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
190 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]]);
191 else if (str.size() == 1) value.m_bc_type[Face::YHI].resize(value.m_ncomp, bcmap[str[0]]);
192 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
193 pp.queryarr_default("type.zlo", str,{"dirichlet"}); // BC type on the lower z face (processed but ignored in 2d to prevent unused input errors)
194#if AMREX_SPACEDIM==3
195 for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
196 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]]);
197 else if (str.size() == 1) value.m_bc_type[Face::ZLO].resize(value.m_ncomp, bcmap[str[0]]);
198 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
199#endif
200 pp.queryarr_default("type.zhi", str,{"dirichlet"}); // BC type on the upper z face (processed but ignored in 2d to prevent unused input errors)
201#if AMREX_SPACEDIM==3
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::ZHI].push_back(bcmap[str[i]]);
204 else if (str.size() == 1) value.m_bc_type[Face::ZHI].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#endif
207
208 // VALS
209 std::vector<std::string> val;
210 value.m_bc_val[Face::XLO].clear();
211 pp.queryarr_default("val.xlo", val,{"0.0"}); // BC value on the lower x edge (2d) face (3d)
212 if (val.size() == value.m_ncomp)
213 for (unsigned int i = 0; i < value.m_ncomp; i++)
214 value.m_bc_val[Face::XLO].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i],Unit::Time(),value.unit));
215 else if (val.size() == 1)
216 value.m_bc_val[Face::XLO].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
217 else if (val.size() == 0)
218 value.m_bc_val[Face::XLO].resize(value.m_ncomp, 0.0);
219 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
220 value.m_bc_val[Face::XHI].clear();
221 pp.queryarr_default("val.xhi", val,{"0.0"}); // BC value on the upper x edge (2d) face (3d)
222 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],Unit::Time(),value.unit));
223 else if (val.size() == 1) value.m_bc_val[Face::XHI].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
224 else if (val.size() == 0) value.m_bc_val[Face::XHI].resize(value.m_ncomp, 0.0);
225 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
226 value.m_bc_val[Face::YLO].clear();
227 pp.queryarr_default("val.ylo", val,{"0.0"}); // BC value on the lower y edge (2d) face (3d)
228 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],Unit::Time(),value.unit));
229 else if (val.size() == 1) value.m_bc_val[Face::YLO].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
230 else if (val.size() == 0) value.m_bc_val[Face::YLO].resize(value.m_ncomp, 0.0);
231 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
232 value.m_bc_val[Face::YHI].clear();
233 pp.queryarr_default("val.yhi", val,{"0.0"}); // BC value on the upper y edge (2d) face (3d)
234 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],Unit::Time(),value.unit));
235 else if (val.size() == 1) value.m_bc_val[Face::YHI].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
236 else if (val.size() == 0) value.m_bc_val[Face::YHI].resize(value.m_ncomp, 0.0);
237 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
238 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)
239#if AMREX_SPACEDIM==3
240 value.m_bc_val[Face::ZLO].clear();
241 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],Unit::Time(),value.unit));
242 else if (val.size() == 1) value.m_bc_val[Face::ZLO].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
243 else if (val.size() == 0) value.m_bc_val[Face::ZLO].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#endif
246 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)
247#if AMREX_SPACEDIM==3
248 value.m_bc_val[Face::ZHI].clear();
249 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],Unit::Time(),value.unit));
250 else if (val.size() == 1) value.m_bc_val[Face::ZHI].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
251 else if (val.size() == 0) value.m_bc_val[Face::ZHI].resize(value.m_ncomp, 0.0);
252 else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
253#endif
254 }
255
256};
257
259{
260public:
261 ZeroNeumann(int ncomp = 1, Unit unit = Unit::Less()) :
262 Constant(ncomp, unit)
263 {
264 for (int d = 0; d < m_nfaces; d++)
265 {
266 m_bc_type[d].resize(ncomp, (int)amrex::LinOpBCType::Neumann);
267 m_bc_val[d].resize(ncomp, 0.0);
268 }
269 }
270};
271
273{
274public:
275 ZeroDirichlet(int ncomp=1, Unit unit = Unit::Less()) :
276 Constant(ncomp,unit)
277 {
278 for (int d = 0; d < m_nfaces; d++)
279 {
280 m_bc_type[d].resize(ncomp, (int)amrex::LinOpBCType::Dirichlet);
281 m_bc_val[d].resize(ncomp, 0.0);
282 }
283 }
284};
285}
286#endif
#define INFO
Definition Util.H:24
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
ZeroDirichlet(int ncomp=1, Unit unit=Unit::Less())
Definition Constant.H:275
ZeroNeumann(int ncomp=1, Unit unit=Unit::Less())
Definition Constant.H:261
std::array< std::vector< int >, m_nfaces > m_bc_type
Definition Constant.H:124
unsigned int m_ncomp
Definition Constant.H:116
amrex::BCRec GetBCRec() override
Definition Constant.cpp:208
Constant(int a_ncomp, IO::ParmParse &pp, std::string name)
Definition Constant.H:64
virtual amrex::Periodicity Periodicity() const override
Definition Constant.cpp:223
static constexpr const char * name
Definition Constant.H:60
static void Parse(Constant &value, IO::ParmParse &pp)
Definition Constant.H:128
virtual ~Constant()
Definition Constant.H:85
std::array< std::vector< Numeric::Interpolator::Linear< Set::Scalar > >, m_nfaces > m_bc_val
Definition Constant.H:125
const amrex::Array< amrex::Array< T, AMREX_SPACEDIM >, 2 > GetBCTypes()
Definition Constant.H:102
Constant(int a_ncomp, Unit a_unit=Unit::Less())
Definition Constant.H:63
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
Constant(int a_ncomp, Unit a_unit, IO::ParmParse &pp, std::string name)
Definition Constant.H:68
virtual amrex::Array< int, AMREX_SPACEDIM > IsPeriodic() override
Definition Constant.cpp:217
void queryclass(std::string name, T *value, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:1767
std::string prefix()
Definition ParmParse.H:1754
int queryarr_default(std::string name, std::vector< std::string > &value, std::vector< std::string > defaultvalue, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:1303
Collection of boundary condition (BC) objects.
Definition BC.cpp:5
Orientation
Definition BC.H:31
@ All
Definition BC.H:32
@ AMREX_D_DECL
Definition BC.H:33
void Exception(std::string file, std::string func, int line, Args const &... args)
Definition Util.H:237
Definition Unit.H:21
static Unit Time()
Definition Unit.H:199
static Unit Less()
Definition Unit.H:197