Alamo
Constant.cpp
Go to the documentation of this file.
1#include "Constant.H"
2
3namespace BC
4{
5
6
7Constant::Constant (int a_ncomp,
8 amrex::Vector<std::string> bc_hi_str,
9 amrex::Vector<std::string> bc_lo_str,
10 AMREX_D_DECL(amrex::Vector<amrex::Real> _bc_lo_1,
11 amrex::Vector<amrex::Real> _bc_lo_2,
12 amrex::Vector<amrex::Real> _bc_lo_3),
13 AMREX_D_DECL(amrex::Vector<amrex::Real> _bc_hi_1,
14 amrex::Vector<amrex::Real> _bc_hi_2,
15 amrex::Vector<amrex::Real> _bc_hi_3))
16 //:
17 //AMREX_D_DECL(bc_lo_1(_bc_lo_1),bc_lo_2(_bc_lo_2),bc_lo_3(_bc_lo_3)),
18 //AMREX_D_DECL(bc_hi_1(_bc_hi_1),bc_hi_2(_bc_hi_2),bc_hi_3(_bc_hi_3))
19{
20 Util::Warning(INFO,"This method is going away. Please use pp.queryclass() instead.");
21
22 m_ncomp = a_ncomp;
23
24 m_bc_type[Face::XLO].resize(m_ncomp,BCUtil::ReadString(bc_lo_str[0]));
25 m_bc_type[Face::XHI].resize(m_ncomp,BCUtil::ReadString(bc_hi_str[0]));
26 m_bc_type[Face::YLO].resize(m_ncomp,BCUtil::ReadString(bc_lo_str[1]));
27 m_bc_type[Face::YHI].resize(m_ncomp,BCUtil::ReadString(bc_hi_str[1]));
28 #if AMREX_SPACEDIM == 3
29 m_bc_type[Face::ZLO].resize(m_ncomp,BCUtil::ReadString(bc_lo_str[2]));
30 m_bc_type[Face::ZHI].resize(m_ncomp,BCUtil::ReadString(bc_hi_str[2]));
31 #endif
32
33
34 m_bc_val[Face::XLO].resize(m_ncomp,NAN);
35 m_bc_val[Face::XHI].resize(m_ncomp,NAN);
36 m_bc_val[Face::YLO].resize(m_ncomp,NAN);
37 m_bc_val[Face::YHI].resize(m_ncomp,NAN);
38 #if AMREX_SPACEDIM == 3
39 m_bc_val[Face::ZLO].resize(m_ncomp,NAN);
40 m_bc_val[Face::ZHI].resize(m_ncomp,NAN);
41 #endif
42
43 for (unsigned int i=0;i<m_ncomp;i++)
44 {
45 if (_bc_lo_1.size() > 0) m_bc_val[Face::XLO][i] = _bc_lo_1[i];
46 if (_bc_hi_1.size() > 0) m_bc_val[Face::XHI][i] = _bc_hi_1[i];
47 if (_bc_lo_2.size() > 0) m_bc_val[Face::YLO][i] = _bc_lo_2[i];
48 if (_bc_hi_2.size() > 0) m_bc_val[Face::YHI][i] = _bc_hi_2[i];
49 #if AMREX_SPACEDIM == 3
50 if (_bc_lo_3.size() > 0) m_bc_val[Face::ZLO][i] = _bc_lo_3[i];
51 if (_bc_hi_3.size() > 0) m_bc_val[Face::ZHI][i] = _bc_hi_3[i];
52 #endif
53 }
54}
55
56
57//amrex::Mask& m
58void
59Constant::FillBoundary (amrex::BaseFab<Set::Scalar> &a_in,
60 const amrex::Box &a_box,
61 int ngrow, int /*dcomp*/, int /*ncomp*/, amrex::Real time,
62 Orientation face, const amrex::Mask * /*mask*/)
63{
64 const auto DX = m_geom.CellSizeArray();
65
66 Util::Assert(INFO,TEST(a_in.nComp() == (int)m_ncomp));
67
68 amrex::Box box = a_box;
69 box.grow(ngrow);
70 const amrex::Dim3 lo= amrex::lbound(m_geom.Domain()), hi = amrex::ubound(m_geom.Domain());
71
72 amrex::Array4<amrex::Real> const& in = a_in.array();
73
74 for (int n = 0; n < a_in.nComp(); n++)
75 {
76 const auto bc_type_xlo = m_bc_type[Face::XLO][n];
77 const auto bc_type_xhi = m_bc_type[Face::XHI][n];
78 const auto bc_type_ylo = m_bc_type[Face::YLO][n];
79 const auto bc_type_yhi = m_bc_type[Face::YHI][n];
80 const Set::Scalar bc_val_xlo =
81 m_bc_val[Face::XLO].empty() ? 0.0 : m_bc_val[Face::XLO][n](time);
82 const Set::Scalar bc_val_xhi =
83 m_bc_val[Face::XHI].empty() ? 0.0 : m_bc_val[Face::XHI][n](time);
84 const Set::Scalar bc_val_ylo =
85 m_bc_val[Face::YLO].empty() ? 0.0 : m_bc_val[Face::YLO][n](time);
86 const Set::Scalar bc_val_yhi =
87 m_bc_val[Face::YHI].empty() ? 0.0 : m_bc_val[Face::YHI][n](time);
88#if AMREX_SPACEDIM > 2
89 const auto bc_type_zlo = m_bc_type[Face::ZLO][n];
90 const auto bc_type_zhi = m_bc_type[Face::ZHI][n];
91 const Set::Scalar bc_val_zlo =
92 m_bc_val[Face::ZLO].empty() ? 0.0 : m_bc_val[Face::ZLO][n](time);
93 const Set::Scalar bc_val_zhi =
94 m_bc_val[Face::ZHI].empty() ? 0.0 : m_bc_val[Face::ZHI][n](time);
95#endif
96 amrex::ParallelFor (box,[=] AMREX_GPU_DEVICE(int i, int j, int k)
97 {
98 amrex::IntVect glevel;
99 AMREX_D_TERM( glevel[0] = std::max(std::min(0,i-lo.x),i-hi.x); ,
100 glevel[1] = std::max(std::min(0,j-lo.y),j-hi.y); ,
101 glevel[2] = std::max(std::min(0,k-lo.z),k-hi.z); );
102
103 if (glevel[0]<0 && (face == Orientation::xlo || face == Orientation::All)) // Left boundary
104 {
105 if (BCUtil::IsDirichlet(bc_type_xlo))
106 in(i,j,k,n) = bc_val_xlo;
107 else if(BCUtil::IsNeumann(bc_type_xlo))
108 in(i,j,k,n) = in(i-glevel[0],j,k,n) - bc_val_xlo*DX[0];
109 else if(BCUtil::IsReflectEven(bc_type_xlo))
110 in(i,j,k,n) = in(1-glevel[0],j,k,n);
111 else if(BCUtil::IsReflectOdd(bc_type_xlo))
112 in(i,j,k,n) = -in(1-glevel[0],j,k,n);
113 else if(BCUtil::IsPeriodic(bc_type_xlo)) {}
114 else
115 Util::Abort(INFO, "Incorrect boundary conditions");
116 }
117 else if (glevel[0]>0 && (face == Orientation::xhi || face == Orientation::All)) // Right boundary
118 {
119 if (BCUtil::IsDirichlet(bc_type_xhi))
120 in(i,j,k,n) = bc_val_xhi;
121 else if(BCUtil::IsNeumann(bc_type_xhi))
122 in(i,j,k,n) = in(i-glevel[0],j,k,n) - bc_val_xhi*DX[0];
123 else if(BCUtil::IsReflectEven(bc_type_xhi))
124 in(i,j,k,n) = in(hi.x-glevel[0],j,k,n);
125 else if(BCUtil::IsReflectOdd(bc_type_xhi))
126 in(i,j,k,n) = -in(hi.x-glevel[0],j,k,n);
127 else if(BCUtil::IsPeriodic(bc_type_xhi)) {}
128 else
129 Util::Abort(INFO, "Incorrect boundary conditions");
130 }
131
132 else if (glevel[1]<0 && (face == Orientation::ylo || face == Orientation::All)) // Bottom boundary
133 {
134 if (BCUtil::IsDirichlet(bc_type_ylo))
135 in(i,j,k,n) = bc_val_ylo;
136 else if (BCUtil::IsNeumann(bc_type_ylo))
137 in(i,j,k,n) = in(i,j-glevel[1],k,n) - bc_val_ylo*DX[1];
138 else if (BCUtil::IsReflectEven(bc_type_ylo))
139 in(i,j,k,n) = in(i,j-glevel[1],k,n);
140 else if (BCUtil::IsReflectOdd(bc_type_ylo))
141 in(i,j,k,n) = -in(i,j-glevel[1],k,n);
142 else if(BCUtil::IsPeriodic(bc_type_ylo)) {}
143 else
144 Util::Abort(INFO, "Incorrect boundary conditions");
145 }
146 else if (glevel[1]>0 && (face == Orientation::yhi || face == Orientation::All)) // Top boundary
147 {
148 if (BCUtil::IsDirichlet(bc_type_yhi))
149 in(i,j,k,n) = bc_val_yhi;
150 else if (BCUtil::IsNeumann(bc_type_yhi))
151 in(i,j,k,n) = in(i,j-glevel[1],k,n) - bc_val_yhi*DX[1];
152 else if (BCUtil::IsReflectEven(bc_type_yhi))
153 in(i,j,k,n) = in(i,hi.y-glevel[1],k,n);
154 else if (BCUtil::IsReflectOdd(bc_type_yhi))
155 in(i,j,k,n) = -in(i,hi.y-glevel[1],k,n);
156 else if(BCUtil::IsPeriodic(bc_type_yhi)) {}
157 else
158 Util::Abort(INFO, "Incorrect boundary conditions");
159 }
160
161#if AMREX_SPACEDIM>2
162 else if (glevel[2]<0 && (face == Orientation::zlo || face == Orientation::All))
163 {
164 if (BCUtil::IsDirichlet(bc_type_zlo))
165 in(i,j,k,n) = bc_val_zlo;
166 else if (BCUtil::IsNeumann(bc_type_zlo))
167 in(i,j,k,n) = in(i,j,k-glevel[2],n) - bc_val_zlo*DX[2];
168 else if (BCUtil::IsReflectEven(bc_type_zlo))
169 in(i,j,k,n) = in(i,j,1-glevel[2],n);
170 else if (BCUtil::IsReflectOdd(bc_type_zlo))
171 in(i,j,k,n) = -in(i,j,1-glevel[2],n);
172 else if(BCUtil::IsPeriodic(bc_type_zlo)) {}
173 else Util::Abort(INFO, "Incorrect boundary conditions");
174 }
175 else if (glevel[2]>0 && (face == Orientation::zhi || face == Orientation::All))
176 {
177 if (BCUtil::IsDirichlet(bc_type_zhi))
178 in(i,j,k,n) = bc_val_zhi;
179 else if(BCUtil::IsNeumann(bc_type_zhi))
180 in(i,j,k,n) = in(i,j,k-glevel[2],n) - bc_val_zhi*DX[2];
181 else if(BCUtil::IsReflectEven(bc_type_zhi))
182 in(i,j,k,n) = in(i,j,hi.z-glevel[2],n);
183 else if(BCUtil::IsReflectOdd(bc_type_zhi))
184 in(i,j,k,n) = -in(i,j,hi.z-glevel[2],n);
185 else if(BCUtil::IsPeriodic(bc_type_zhi)) {}
186 else Util::Abort(INFO, "Incorrect boundary conditions");
187 }
188#endif
189 });
190
191 // Average the value of corner cells based on the neighboring ghost cells.
192 // This fixes NAN issues that can arise from neumann conditions calculated in ghost cells
193 // Fixes this issue in 2D only for now.
194 //
195 // TODO: more general fix for 3D cell-based fields
196 amrex::ParallelFor (box,[=] AMREX_GPU_DEVICE(int i, int j, int k)
197 {
198 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) );
199 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) );
200 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) );
201 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) );
202 });
203
204 }
205}
206
207amrex::BCRec
209{
210 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])};
211 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])};
212
213 return amrex::BCRec(bc_lo,bc_hi);
214}
215
216amrex::Array<int,AMREX_SPACEDIM>
218{
219 return {AMREX_D_DECL(BCUtil::IsPeriodic(m_bc_type[Face::XLO][0]),
220 BCUtil::IsPeriodic(m_bc_type[Face::YLO][0]),
221 BCUtil::IsPeriodic(m_bc_type[Face::ZLO][0]))};
222}
223amrex::Periodicity Constant::Periodicity () const
224{
225 return amrex::Periodicity(amrex::IntVect(AMREX_D_DECL(m_geom.Domain().length(0) * BCUtil::IsPeriodic(m_bc_type[Face::XLO][0]),
226 m_geom.Domain().length(1) * BCUtil::IsPeriodic(m_bc_type[Face::YLO][0]),
227 m_geom.Domain().length(2) * BCUtil::IsPeriodic(m_bc_type[Face::ZLO][0]))));
228}
229amrex::Periodicity Constant::Periodicity (const amrex::Box& b) {
230 return amrex::Periodicity(amrex::IntVect(AMREX_D_DECL(b.length(0) * BCUtil::IsPeriodic(m_bc_type[Face::XLO][0]),
231 b.length(1) * BCUtil::IsPeriodic(m_bc_type[Face::YLO][0]),
232 b.length(2) * BCUtil::IsPeriodic(m_bc_type[Face::ZLO][0]))));
233
234}
235
236
237}
#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 Constant.H:124
unsigned int m_ncomp
Definition Constant.H:116
amrex::BCRec GetBCRec() override
Definition Constant.cpp:208
virtual amrex::Periodicity Periodicity() const override
Definition Constant.cpp:223
std::array< std::vector< Numeric::Interpolator::Linear< Set::Scalar > >, m_nfaces > m_bc_val
Definition Constant.H:125
Constant(int a_ncomp, Unit a_unit=Unit::Less())
Definition Constant.H:63
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
virtual amrex::Array< int, AMREX_SPACEDIM > IsPeriodic() override
Definition Constant.cpp:217
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
int ReadString(std::string bcstring)
Definition BC.cpp:8
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
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
void Warning(std::string file, std::string func, int line, Args const &... args)
Definition Util.H:213
AMREX_GPU_HOST_DEVICE void Abort(const char *msg)
Definition Util.cpp:406