Alamo
Expression.cpp
Go to the documentation of this file.
1#include "Expression.H"
2
3namespace BC
4{
5
6void
7Expression::FillBoundary (amrex::BaseFab<Set::Scalar> &a_in,
8 const amrex::Box &a_box,
9 int ngrow, int /*dcomp*/, int /*ncomp*/, Set::Scalar time,
10 Orientation face, const amrex::Mask * /*mask*/)
11{
12 const auto DX = m_geom.CellSizeArray();
13 const auto prob_lo = m_geom.ProbLoArray();
14
15 Util::Assert(INFO,TEST(a_in.nComp() == (int)m_ncomp));
16
17 amrex::Box box = a_box;
18 box.grow(ngrow);
19 const amrex::Dim3 lo= amrex::lbound(m_geom.Domain()), hi = amrex::ubound(m_geom.Domain());
20
21 amrex::Array4<amrex::Real> const& in = a_in.array();
22
23 amrex::IndexType type = amrex::IndexType::TheCellType();
24
25 for (int n = 0; n < a_in.nComp(); n++)
26 {
27 const auto bc_type_xlo = m_bc_type[Face::XLO][n];
28 const auto bc_type_xhi = m_bc_type[Face::XHI][n];
29 const auto bc_type_ylo = m_bc_type[Face::YLO][n];
30 const auto bc_type_yhi = m_bc_type[Face::YHI][n];
31 const auto bc_func_xlo = m_bc_func[Face::XLO][n];
32 const auto bc_func_xhi = m_bc_func[Face::XHI][n];
33 const auto bc_func_ylo = m_bc_func[Face::YLO][n];
34 const auto bc_func_yhi = m_bc_func[Face::YHI][n];
35#if AMREX_SPACEDIM > 2
36 const auto bc_type_zlo = m_bc_type[Face::ZLO][n];
37 const auto bc_type_zhi = m_bc_type[Face::ZHI][n];
38 const auto bc_func_zlo = m_bc_func[Face::ZLO][n];
39 const auto bc_func_zhi = m_bc_func[Face::ZHI][n];
40#endif
41 amrex::ParallelFor (box,[=] AMREX_GPU_DEVICE(int i, int j, int k)
42 {
43 Set::Vector pos = Set::Position(i, j, k, prob_lo, DX, type);
44 Set::Scalar x = 0.0, y=0.0, z=0.0, t=time;
45 x = pos(0);
46 #if AMREX_SPACEDIM > 1
47 y = pos(1);
48 #if AMREX_SPACEDIM > 2
49 z = pos(2);
50 #endif
51 #endif
52
53
54 amrex::IntVect glevel;
55 AMREX_D_TERM(glevel[0] = std::max(std::min(0,i-lo.x),i-hi.x); ,
56 glevel[1] = std::max(std::min(0,j-lo.y),j-hi.y); ,
57 glevel[2] = std::max(std::min(0,k-lo.z),k-hi.z); );
58
59 if (glevel[0]<0 && (face == Orientation::xlo || face == Orientation::All)) // Left boundary
60 {
61 if (BCUtil::IsDirichlet(bc_type_xlo))
62 in(i,j,k,n) = bc_func_xlo(x,y,z,t);
63 else if(BCUtil::IsNeumann(bc_type_xlo))
64 in(i,j,k,n) = in(i-glevel[0],j,k,n) - bc_func_xlo(x,y,z,t)*DX[0];
65 else if(BCUtil::IsReflectEven(bc_type_xlo))
66 in(i,j,k,n) = in(1-glevel[0],j,k,n);
67 else if(BCUtil::IsReflectOdd(bc_type_xlo))
68 in(i,j,k,n) = -in(1-glevel[0],j,k,n);
69 else if(BCUtil::IsPeriodic(bc_type_xlo)) {}
70 else
71 Util::Abort(INFO, "Incorrect boundary conditions");
72 }
73 else if (glevel[0]>0 && (face == Orientation::xhi || face == Orientation::All)) // Right boundary
74 {
75 if (BCUtil::IsDirichlet(bc_type_xhi))
76 in(i,j,k,n) = bc_func_xhi(x,y,z,t);
77 else if(BCUtil::IsNeumann(bc_type_xhi))
78 in(i,j,k,n) = in(i-glevel[0],j,k,n) - bc_func_xhi(x,y,z,t)*DX[0];
79 else if(BCUtil::IsReflectEven(bc_type_xhi))
80 in(i,j,k,n) = in(hi.x-glevel[0],j,k,n);
81 else if(BCUtil::IsReflectOdd(bc_type_xhi))
82 in(i,j,k,n) = -in(hi.x-glevel[0],j,k,n);
83 else if(BCUtil::IsPeriodic(bc_type_xhi)) {}
84 else
85 Util::Abort(INFO, "Incorrect boundary conditions");
86 }
87 else if (glevel[1]<0 && (face == Orientation::ylo || face == Orientation::All)) // Bottom boundary
88 {
89 if (BCUtil::IsDirichlet(bc_type_ylo))
90 in(i,j,k,n) = bc_func_ylo(x,y,z,t);
91 else if (BCUtil::IsNeumann(bc_type_ylo))
92 in(i,j,k,n) = in(i,j-glevel[1],k,n) - bc_func_ylo(x,y,z,t)*DX[1];
93 else if (BCUtil::IsReflectEven(bc_type_ylo))
94 in(i,j,k,n) = in(i,j-glevel[1],k,n);
95 else if (BCUtil::IsReflectOdd(bc_type_ylo))
96 in(i,j,k,n) = -in(i,j-glevel[1],k,n);
97 else if(BCUtil::IsPeriodic(bc_type_ylo)) {}
98 else
99 Util::Abort(INFO, "Incorrect boundary conditions");
100 }
101 else if (glevel[1]>0 && (face == Orientation::yhi || face == Orientation::All)) // Top boundary
102 {
103 if (BCUtil::IsDirichlet(bc_type_yhi))
104 in(i,j,k,n) = bc_func_yhi(x,y,z,t);
105 else if (BCUtil::IsNeumann(bc_type_yhi))
106 in(i,j,k,n) = in(i,j-glevel[1],k,n) - bc_func_yhi(x,y,z,t)*DX[1];
107 else if (BCUtil::IsReflectEven(bc_type_yhi))
108 in(i,j,k,n) = in(i,hi.y-glevel[1],k,n);
109 else if (BCUtil::IsReflectOdd(bc_type_yhi))
110 in(i,j,k,n) = -in(i,hi.y-glevel[1],k,n);
111 else if(BCUtil::IsPeriodic(bc_type_yhi)) {}
112 else
113 Util::Abort(INFO, "Incorrect boundary conditions");
114 }
115#if AMREX_SPACEDIM>2
116 else if (glevel[2]<0 && (face == Orientation::zlo || face == Orientation::All))
117 {
118 if (BCUtil::IsDirichlet(bc_type_zlo))
119 in(i,j,k,n) = bc_func_zlo(x,y,z,t);
120 else if (BCUtil::IsNeumann(bc_type_zlo))
121 in(i,j,k,n) = in(i,j,k-glevel[2],n) - bc_func_zlo(x,y,z,t)*DX[2];
122 else if (BCUtil::IsReflectEven(bc_type_zlo))
123 in(i,j,k,n) = in(i,j,1-glevel[2],n);
124 else if (BCUtil::IsReflectOdd(bc_type_zlo))
125 in(i,j,k,n) = -in(i,j,1-glevel[2],n);
126 else if(BCUtil::IsPeriodic(bc_type_zlo)) {}
127 else Util::Abort(INFO, "Incorrect boundary conditions");
128 }
129 else if (glevel[2]>0 && (face == Orientation::zhi || face == Orientation::All))
130 {
131 if (BCUtil::IsDirichlet(bc_type_zhi))
132 in(i,j,k,n) = bc_func_zhi(x,y,z,t);
133 else if(BCUtil::IsNeumann(bc_type_zhi))
134 in(i,j,k,n) = in(i,j,k-glevel[2],n) - bc_func_zhi(x,y,z,t)*DX[2];
135 else if(BCUtil::IsReflectEven(bc_type_zhi))
136 in(i,j,k,n) = in(i,j,hi.z-glevel[2],n);
137 else if(BCUtil::IsReflectOdd(bc_type_zhi))
138 in(i,j,k,n) = -in(i,j,hi.z-glevel[2],n);
139 else if(BCUtil::IsPeriodic(bc_type_zhi)) {}
140 else Util::Abort(INFO, "Incorrect boundary conditions");
141 }
142#endif
143
144 });
145
146 // Average physical corner ghost cells from the face ghosts, matching
147 // Constant BC behavior and avoiding undefined corner values in centered stencils.
148 amrex::ParallelFor (box,[=] AMREX_GPU_DEVICE(int i, int j, int k)
149 {
150 if (i < lo.x && j < lo.y) in(i,j,k,n) = 0.5*( in(i+1,j,k,n) + in(i,j+1,k,n) );
151 if (i < lo.x && j > hi.y) in(i,j,k,n) = 0.5*( in(i+1,j,k,n) + in(i,j-1,k,n) );
152 if (i > hi.x && j < lo.y) in(i,j,k,n) = 0.5*( in(i-1,j,k,n) + in(i,j+1,k,n) );
153 if (i > hi.x && j > hi.y) in(i,j,k,n) = 0.5*( in(i-1,j,k,n) + in(i,j-1,k,n) );
154 });
155 }
156}
157
158amrex::BCRec
160{
161 int bc_lo[BL_SPACEDIM] = {AMREX_D_DECL(m_bc_type[Face::XLO][0],m_bc_type[Face::YLO][0],m_bc_type[Face::XLO][0])};
162 int bc_hi[BL_SPACEDIM] = {AMREX_D_DECL(m_bc_type[Face::XHI][0],m_bc_type[Face::YHI][0],m_bc_type[Face::XHI][0])};
163
164 return amrex::BCRec(bc_lo,bc_hi);
165}
166
167amrex::Array<int,AMREX_SPACEDIM>
169{
170 return {AMREX_D_DECL(BCUtil::IsPeriodic(m_bc_type[Face::XLO][0]),
171 BCUtil::IsPeriodic(m_bc_type[Face::YLO][0]),
172 BCUtil::IsPeriodic(m_bc_type[Face::ZLO][0]))};
173}
174amrex::Periodicity Expression::Periodicity () const
175{
176 return amrex::Periodicity(amrex::IntVect(AMREX_D_DECL(m_geom.Domain().length(0) * BCUtil::IsPeriodic(m_bc_type[Face::XLO][0]),
177 m_geom.Domain().length(1) * BCUtil::IsPeriodic(m_bc_type[Face::YLO][0]),
178 m_geom.Domain().length(2) * BCUtil::IsPeriodic(m_bc_type[Face::ZLO][0]))));
179}
180amrex::Periodicity Expression::Periodicity (const amrex::Box& b) {
181 return amrex::Periodicity(amrex::IntVect(AMREX_D_DECL(b.length(0) * BCUtil::IsPeriodic(m_bc_type[Face::XLO][0]),
182 b.length(1) * BCUtil::IsPeriodic(m_bc_type[Face::YLO][0]),
183 b.length(2) * BCUtil::IsPeriodic(m_bc_type[Face::ZLO][0]))));
184
185}
186
187
188}
std::time_t t
#define TEST(x)
Definition Util.H:25
#define INFO
Definition Util.H:24
amrex::Geometry m_geom
Definition BC.H:129
std::array< std::vector< int >, m_nfaces > m_bc_type
Definition Expression.H:95
amrex::BCRec GetBCRec() override
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 Expression.cpp:7
virtual amrex::Array< int, AMREX_SPACEDIM > IsPeriodic() override
std::array< std::vector< amrex::ParserExecutor< 4 > >, m_nfaces > m_bc_func
Definition Expression.H:97
unsigned int m_ncomp
Definition Expression.H:93
virtual amrex::Periodicity Periodicity() const override
AMREX_GPU_HOST_DEVICE bool IsPeriodic(int bctype)
Definition BC.cpp:33
AMREX_GPU_HOST_DEVICE bool IsDirichlet(int bctype)
Definition BC.cpp:48
AMREX_GPU_HOST_DEVICE bool IsReflectEven(int bctype)
Definition BC.cpp:54
AMREX_GPU_HOST_DEVICE bool IsNeumann(int bctype)
Definition BC.cpp:41
AMREX_GPU_HOST_DEVICE bool IsReflectOdd(int bctype)
Definition BC.cpp:59
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
amrex::Real Scalar
Definition Base.H:19
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
Definition Base.H:21
AMREX_FORCE_INLINE Vector Position(const int &i, const int &j, const int &k, const amrex::Geometry &geom, const amrex::IndexType &ixType)
Definition Base.H:122
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE void Assert(const char *file, const char *func, int line, const char *smt, bool pass, Args const &... args)
Definition Util.H:60
AMREX_GPU_HOST_DEVICE void Abort(const char *msg)
Definition Util.cpp:406