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