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 amrex::Real* DX = m_geom.CellSize();
13
14 Util::Assert(INFO,TEST(a_in.nComp() == (int)m_ncomp));
15
16 amrex::Box box = a_box;
17 box.grow(ngrow);
18 const amrex::Dim3 lo= amrex::lbound(m_geom.Domain()), hi = amrex::ubound(m_geom.Domain());
19
20 amrex::Array4<amrex::Real> const& in = a_in.array();
21
22 amrex::IndexType type = amrex::IndexType::TheCellType();
23
24 for (int n = 0; n < a_in.nComp(); n++)
25 {
26 amrex::ParallelFor (box,[=] AMREX_GPU_DEVICE(int i, int j, int k)
27 {
28 Set::Vector pos = Set::Position(i, j, k, m_geom, type);
29 Set::Scalar x = 0.0, y=0.0, z=0.0, t=time;
30 x = pos(0);
31 #if AMREX_SPACEDIM > 1
32 y = pos(1);
33 #if AMREX_SPACEDIM > 2
34 z = pos(2);
35 #endif
36 #endif
37
38
39 amrex::IntVect glevel;
40 AMREX_D_TERM(glevel[0] = std::max(std::min(0,i-lo.x),i-hi.x); ,
41 glevel[1] = std::max(std::min(0,j-lo.y),j-hi.y); ,
42 glevel[2] = std::max(std::min(0,k-lo.z),k-hi.z); );
43
44 if (glevel[0]<0 && (face == Orientation::xlo || face == Orientation::All)) // Left boundary
45 {
46 if (BCUtil::IsDirichlet(m_bc_type[Face::XLO][n]))
47 in(i,j,k,n) = m_bc_func[Face::XLO][n](x,y,z,t);
48 else if(BCUtil::IsNeumann(m_bc_type[Face::XLO][n]))
49 in(i,j,k,n) = in(i-glevel[0],j,k,n) - (m_bc_func[Face::XLO].size() > 0 ? m_bc_func[Face::XLO][n](x,y,z,t)*DX[0] : 0);
50 else if(BCUtil::IsReflectEven(m_bc_type[Face::XLO][n]))
51 in(i,j,k,n) = in(1-glevel[0],j,k,n);
52 else if(BCUtil::IsReflectOdd(m_bc_type[Face::XLO][n]))
53 in(i,j,k,n) = -in(1-glevel[0],j,k,n);
54 else if(BCUtil::IsPeriodic(m_bc_type[Face::XLO][n])) {}
55 else
56 Util::Abort(INFO, "Incorrect boundary conditions");
57 }
58 else if (glevel[0]>0 && (face == Orientation::xhi || face == Orientation::All)) // Right boundary
59 {
60 if (BCUtil::IsDirichlet(m_bc_type[Face::XHI][n]))
61 in(i,j,k,n) = m_bc_func[Face::XHI][n](x,y,z,t);
62 else if(BCUtil::IsNeumann(m_bc_type[Face::XHI][n]))
63 in(i,j,k,n) = in(i-glevel[0],j,k,n) - (m_bc_func[Face::XHI].size() > 0 ? m_bc_func[Face::XHI][n](x,y,z,t)*DX[0] : 0);
64 else if(BCUtil::IsReflectEven(m_bc_type[Face::XHI][n]))
65 in(i,j,k,n) = in(hi.x-glevel[0],j,k,n);
66 else if(BCUtil::IsReflectOdd(m_bc_type[Face::XHI][n]))
67 in(i,j,k,n) = -in(hi.x-glevel[0],j,k,n);
68 else if(BCUtil::IsPeriodic(m_bc_type[Face::XHI][n])) {}
69 else
70 Util::Abort(INFO, "Incorrect boundary conditions");
71 }
72 else if (glevel[1]<0 && (face == Orientation::ylo || face == Orientation::All)) // Bottom boundary
73 {
74 if (BCUtil::IsDirichlet(m_bc_type[Face::YLO][n]))
75 in(i,j,k,n) = m_bc_func[Face::YLO][n](x,y,z,t);
76 else if (BCUtil::IsNeumann(m_bc_type[Face::YLO][n]))
77 in(i,j,k,n) = in(i,j-glevel[1],k,n) - (m_bc_func[Face::YLO].size() > 0 ? m_bc_func[Face::YLO][n](x,y,z,t)*DX[1] : 0);
78 else if (BCUtil::IsReflectEven(m_bc_type[Face::YLO][n]))
79 in(i,j,k,n) = in(i,j-glevel[1],k,n);
80 else if (BCUtil::IsReflectOdd(m_bc_type[Face::YLO][n]))
81 in(i,j,k,n) = -in(i,j-glevel[1],k,n);
82 else if(BCUtil::IsPeriodic(m_bc_type[Face::YLO][n])) {}
83 else
84 Util::Abort(INFO, "Incorrect boundary conditions");
85 }
86 else if (glevel[1]>0 && (face == Orientation::yhi || face == Orientation::All)) // Top boundary
87 {
88 if (BCUtil::IsDirichlet(m_bc_type[Face::YHI][n]))
89 in(i,j,k,n) = m_bc_func[Face::YHI][n](x,y,z,t);
90 else if (BCUtil::IsNeumann(m_bc_type[Face::YHI][n]))
91 in(i,j,k,n) = in(i,j-glevel[1],k,n) - (m_bc_func[Face::YHI].size() > 0 ? m_bc_func[Face::YHI][n](x,y,z,t)*DX[1] : 0);
92 else if (BCUtil::IsReflectEven(m_bc_type[Face::YHI][n]))
93 in(i,j,k,n) = in(i,hi.y-glevel[1],k,n);
94 else if (BCUtil::IsReflectOdd(m_bc_type[Face::YHI][n]))
95 in(i,j,k,n) = -in(i,hi.y-glevel[1],k,n);
96 else if(BCUtil::IsPeriodic(m_bc_type[Face::YHI][n])) {}
97 else
98 Util::Abort(INFO, "Incorrect boundary conditions");
99 }
100#if AMREX_SPACEDIM>2
101 else if (glevel[2]<0 && (face == Orientation::zlo || face == Orientation::All))
102 {
103 if (BCUtil::IsDirichlet(m_bc_type[Face::ZLO][n]))
104 in(i,j,k,n) = m_bc_func[Face::ZLO][n](x,y,z,t);
105 else if (BCUtil::IsNeumann(m_bc_type[Face::ZLO][n]))
106 in(i,j,k,n) = in(i,j,k-glevel[2],n) - (m_bc_func[Face::ZLO].size() > 0 ? m_bc_func[Face::ZLO][n](x,y,z,t)*DX[2] : 0);
107 else if (BCUtil::IsReflectEven(m_bc_type[Face::ZLO][n]))
108 in(i,j,k,n) = in(i,j,1-glevel[2],n);
109 else if (BCUtil::IsReflectOdd(m_bc_type[Face::ZLO][n]))
110 in(i,j,k,n) = -in(i,j,1-glevel[2],n);
111 else if(BCUtil::IsPeriodic(m_bc_type[Face::ZLO][n])) {}
112 else Util::Abort(INFO, "Incorrect boundary conditions");
113 }
114 else if (glevel[2]>0 && (face == Orientation::zhi || face == Orientation::All))
115 {
116 if (BCUtil::IsDirichlet(m_bc_type[Face::ZHI][n]))
117 in(i,j,k,n) = m_bc_func[Face::ZHI][n](x,y,z,t);
118 else if(BCUtil::IsNeumann(m_bc_type[Face::ZHI][n]))
119 in(i,j,k,n) = in(i,j,k-glevel[2],n) - (m_bc_func[Face::ZHI].size() > 0 ? m_bc_func[Face::ZHI][n](x,y,z,t)*DX[2] : 0);
120 else if(BCUtil::IsReflectEven(m_bc_type[Face::ZHI][n]))
121 in(i,j,k,n) = in(i,j,hi.z-glevel[2],n);
122 else if(BCUtil::IsReflectOdd(m_bc_type[Face::ZHI][n]))
123 in(i,j,k,n) = -in(i,j,hi.z-glevel[2],n);
124 else if(BCUtil::IsPeriodic(m_bc_type[Face::ZHI][n])) {}
125 else Util::Abort(INFO, "Incorrect boundary conditions");
126 }
127#endif
128
129 });
130
131 // Average physical corner ghost cells from the face ghosts, matching
132 // Constant BC behavior and avoiding undefined corner values in centered stencils.
133 amrex::ParallelFor (box,[=] AMREX_GPU_DEVICE(int i, int j, int k)
134 {
135 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) );
136 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) );
137 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) );
138 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) );
139 });
140 }
141}
142
143amrex::BCRec
145{
146 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])};
147 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])};
148
149 return amrex::BCRec(bc_lo,bc_hi);
150}
151
152amrex::Array<int,AMREX_SPACEDIM>
154{
155 return {AMREX_D_DECL(BCUtil::IsPeriodic(m_bc_type[Face::XLO][0]),
156 BCUtil::IsPeriodic(m_bc_type[Face::YLO][0]),
157 BCUtil::IsPeriodic(m_bc_type[Face::ZLO][0]))};
158}
159amrex::Periodicity Expression::Periodicity () const
160{
161 return amrex::Periodicity(amrex::IntVect(AMREX_D_DECL(m_geom.Domain().length(0) * BCUtil::IsPeriodic(m_bc_type[Face::XLO][0]),
162 m_geom.Domain().length(1) * BCUtil::IsPeriodic(m_bc_type[Face::YLO][0]),
163 m_geom.Domain().length(2) * BCUtil::IsPeriodic(m_bc_type[Face::ZLO][0]))));
164}
165amrex::Periodicity Expression::Periodicity (const amrex::Box& b) {
166 return amrex::Periodicity(amrex::IntVect(AMREX_D_DECL(b.length(0) * BCUtil::IsPeriodic(m_bc_type[Face::XLO][0]),
167 b.length(1) * BCUtil::IsPeriodic(m_bc_type[Face::YLO][0]),
168 b.length(2) * BCUtil::IsPeriodic(m_bc_type[Face::ZLO][0]))));
169
170}
171
172
173}
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
bool IsDirichlet(int bctype)
Definition BC.cpp:48
bool IsPeriodic(int bctype)
Definition BC.cpp:33
bool IsNeumann(int bctype)
Definition BC.cpp:41
bool IsReflectOdd(int bctype)
Definition BC.cpp:59
bool IsReflectEven(int bctype)
Definition BC.cpp:54
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
void Abort(const char *msg)
Definition Util.cpp:268
AMREX_FORCE_INLINE void Assert(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
Definition Util.H:58