ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_SolverUtils.H
Go to the documentation of this file.
1 #ifndef ERF_SOLVER_UTILS_H_
2 #define ERF_SOLVER_UTILS_H_
3 
4 #include "AMReX_LO_BCTYPES.H"
5 
6 using namespace amrex;
7 
8 /**
9  * Define the domain boundary conditions for the (optional) Poisson solve
10  * if we want to enforce that the initial conditions satisfy the constraint
11  */
12 inline Array<LinOpBCType,AMREX_SPACEDIM>
13 get_lo_projection_bc (Geometry const& lev_geom,
14  Array<std::string,2*AMREX_SPACEDIM> l_domain_bc_type)
15 {
16  amrex::Array<amrex::LinOpBCType,AMREX_SPACEDIM> r;
17  for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
18  if ( lev_geom.isPeriodic(dir) )
19  {
20  r[dir] = LinOpBCType::Periodic;
21  } else {
22  auto bc_type = l_domain_bc_type[Orientation(dir,Orientation::low)];
23  if (bc_type == "Outflow" || bc_type == "Open") {
24  r[dir] = LinOpBCType::Dirichlet;
25  } else {
26  r[dir] = LinOpBCType::Neumann;
27  }
28  }
29  }
30  return r;
31 }
32 
33 inline Array<LinOpBCType,AMREX_SPACEDIM>
34 get_hi_projection_bc (Geometry const& lev_geom,
35  Array<std::string,2*AMREX_SPACEDIM> l_domain_bc_type)
36 {
37  amrex::Array<amrex::LinOpBCType,AMREX_SPACEDIM> r;
38  for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
39  if ( lev_geom.isPeriodic(dir) )
40  {
41  r[dir] = LinOpBCType::Periodic;
42  } else {
43  auto bc_type = l_domain_bc_type[Orientation(dir,Orientation::high)];
44  if (bc_type == "Outflow" || bc_type == "Open") {
45  r[dir] = LinOpBCType::Dirichlet;
46  } else {
47  r[dir] = LinOpBCType::Neumann;
48  }
49  }
50  }
51  return r;
52 }
53 
54 #ifdef ERF_USE_FFT
55 
56 inline Array<std::pair<FFT::Boundary,FFT::Boundary>,AMREX_SPACEDIM>
57 get_fft_bc (Geometry const& lev_geom,
58  Array<std::string,2*AMREX_SPACEDIM> l_domain_bc_type,
59  Box const& bounding_box, bool use_real_bcs) noexcept
60 {
61  Array<std::pair<FFT::Boundary,FFT::Boundary>,AMREX_SPACEDIM> r;
62 
63  FFT::Boundary first, second;
64 
65  for (int dir = 0; dir <= 2; dir++)
66  {
67  auto bc_type_lo = l_domain_bc_type[Orientation(dir,Orientation::low)];
68  if ( lev_geom.isPeriodic(dir) &&
69  (lev_geom.Domain().smallEnd(dir) == bounding_box.smallEnd(dir)) )
70  {
71  first = FFT::Boundary::periodic;
72  // amrex::Print() << "SETTING FIRST OF " << dir << " TO PERIODIC " << std::endl;
73  }
74 
75  else if ( (lev_geom.Domain().smallEnd(dir) == bounding_box.smallEnd(dir)) &&
76  (bc_type_lo == "Outflow" || bc_type_lo == "Open") && (dir == 2 || !use_real_bcs) )
77  {
78  first = FFT::Boundary::odd;
79  // amrex::Print() << "SETTING FIRST OF " << dir << " TO ODD " << std::endl;
80  }
81 
82  else
83  {
84  first = FFT::Boundary::even;
85  // amrex::Print() << "SETTING FIRST OF " << dir << " TO EVEN " << std::endl;
86  }
87 
88  auto bc_type_hi = l_domain_bc_type[Orientation(dir,Orientation::high)];
89  if ( lev_geom.isPeriodic(dir) &&
90  (lev_geom.Domain().bigEnd(dir) == bounding_box.bigEnd(dir)) )
91  {
92  second = FFT::Boundary::periodic;
93  // amrex::Print() << "SETTING SECOND OF " << dir << " TO PERIODIC " << std::endl;
94  }
95 
96  else if ( (lev_geom.Domain().bigEnd(dir) == bounding_box.bigEnd(dir)) &&
97  (bc_type_hi == "Outflow" || bc_type_hi == "Open") && (dir == 2 || !use_real_bcs) )
98  {
99  second = FFT::Boundary::odd;
100  // amrex::Print() << "SETTING SECOND OF " << dir << " TO ODD " << std::endl;
101  }
102 
103  else
104  {
105  second = FFT::Boundary::even;
106  // amrex::Print() << "SETTING SECOND OF " << dir << " TO EVEN " << std::endl;
107  }
108 
109  r[dir] = std::make_pair(first,second);
110 
111  } // dir
112 
113  return r;
114 }
115 #endif
116 #endif
Array< LinOpBCType, AMREX_SPACEDIM > get_lo_projection_bc(Geometry const &lev_geom, Array< std::string, 2 *AMREX_SPACEDIM > l_domain_bc_type)
Definition: ERF_SolverUtils.H:13
Array< LinOpBCType, AMREX_SPACEDIM > get_hi_projection_bc(Geometry const &lev_geom, Array< std::string, 2 *AMREX_SPACEDIM > l_domain_bc_type)
Definition: ERF_SolverUtils.H:34
Definition: ERF_ConsoleIO.cpp:12