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 
41 namespace BC
42 {
43 class Constant
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 
59 public:
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 
133 private:
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 
150 public:
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("type.xlo", str); // 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("type.xhi", str); // 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("type.ylo", str); // 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("type.yhi", str); // 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("type.zlo", str); // 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("type.zhi", str); // 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("val.xlo", val); // 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("val.xhi", val); // 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("val.ylo", val); // 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("val.yhi", val); // 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("val.zlo", val); // 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("val.zhi", val); // 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
BC::Constant::ZeroDirichlet
static Constant ZeroDirichlet(int ncomp=1)
Definition: Constant.H:94
BC::Constant::m_bc_val
std::array< std::vector< Numeric::Interpolator::Linear< Set::Scalar > >, m_nfaces > m_bc_val
Definition: Constant.H:148
BC::AMREX_D_DECL
@ AMREX_D_DECL
Definition: BC.H:34
Linear.H
BC::Constant::~Constant
virtual ~Constant()
Definition: Constant.H:109
IO::ParmParse::prefix
std::string prefix()
Definition: ParmParse.H:441
BC::All
@ All
Definition: BC.H:33
BC::Constant::Constant
Constant(int a_ncomp, IO::ParmParse &pp, std::string name)
Definition: Constant.H:64
BC::Constant::ZeroNeumann
static Constant ZeroNeumann(int ncomp=1)
Definition: Constant.H:77
BC::Constant::m_bc_type
std::array< std::vector< int >, m_nfaces > m_bc_type
Definition: Constant.H:147
BC::Constant::IsPeriodic
virtual amrex::Array< int, AMREX_SPACEDIM > IsPeriodic() override
Definition: Constant.cpp:183
pp_queryclass
#define pp_queryclass(...)
Definition: ParmParse.H:106
BC::Constant::m_ncomp
unsigned int m_ncomp
Definition: Constant.H:140
BC::Constant::Constant
Constant(int a_ncomp)
Definition: Constant.H:63
BC::Constant::GetBCRec
amrex::BCRec GetBCRec() override
Definition: Constant.cpp:174
Set::Face
@ Face
Definition: Set.H:32
BC::Constant::Parse
static void Parse(Constant &value, IO::ParmParse &pp)
Definition: Constant.H:151
Util::Exception
void Exception(std::string file, std::string func, int line, Args const &... args)
Definition: Util.H:202
BC::BC::FillBoundary
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
Numeric::Interpolator::Linear< Set::Scalar >
BC::Constant::Periodicity
virtual amrex::Periodicity Periodicity() const override
Definition: Constant.cpp:189
BC::Constant::FillBoundary
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
BC::Orientation
Orientation
Definition: BC.H:32
BC
Collection of boundary condition (BC) objects.
Definition: BC.cpp:4
BC::Constant
Definition: Constant.H:43
Set.H
BC.H
IO::ParmParse
Definition: ParmParse.H:112
INFO
#define INFO
Definition: Util.H:20
BC::Constant::name
static constexpr const char * name
Definition: Constant.H:60
BC::Constant::GetBCTypes
const amrex::Array< amrex::Array< T, AMREX_SPACEDIM >, 2 > GetBCTypes()
Definition: Constant.H:126
pp_queryarr
#define pp_queryarr(...)
Definition: ParmParse.H:103