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 amrex::Real* DX = m_geom.CellSize();
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 amrex::ParallelFor (box,[=] AMREX_GPU_DEVICE(int i, int j, int k)
77 {
78 amrex::IntVect glevel;
79 AMREX_D_TERM( glevel[0] = std::max(std::min(0,i-lo.x),i-hi.x); ,
80 glevel[1] = std::max(std::min(0,j-lo.y),j-hi.y); ,
81 glevel[2] = std::max(std::min(0,k-lo.z),k-hi.z); );
82
83 if (glevel[0]<0 && (face == Orientation::xlo || face == Orientation::All)) // Left boundary
84 {
85 if (BCUtil::IsDirichlet(m_bc_type[Face::XLO][n]))
86 in(i,j,k,n) = m_bc_val[Face::XLO][n](time);
87 else if(BCUtil::IsNeumann(m_bc_type[Face::XLO][n]))
88 in(i,j,k,n) = in(i-glevel[0],j,k,n) - (m_bc_val[Face::XLO].size() > 0 ? m_bc_val[Face::XLO][n](time)*DX[0] : 0);
89 else if(BCUtil::IsReflectEven(m_bc_type[Face::XLO][n]))
90 in(i,j,k,n) = in(1-glevel[0],j,k,n);
91 else if(BCUtil::IsReflectOdd(m_bc_type[Face::XLO][n]))
92 in(i,j,k,n) = -in(1-glevel[0],j,k,n);
93 else if(BCUtil::IsPeriodic(m_bc_type[Face::XLO][n])) {}
94 else
95 Util::Abort(INFO, "Incorrect boundary conditions");
96 }
97 else if (glevel[0]>0 && (face == Orientation::xhi || face == Orientation::All)) // Right boundary
98 {
99 if (BCUtil::IsDirichlet(m_bc_type[Face::XHI][n]))
100 in(i,j,k,n) = m_bc_val[Face::XHI][n](time);
101 else if(BCUtil::IsNeumann(m_bc_type[Face::XHI][n]))
102 in(i,j,k,n) = in(i-glevel[0],j,k,n) - (m_bc_val[Face::XHI].size() > 0 ? m_bc_val[Face::XHI][n](time)*DX[0] : 0);
103 else if(BCUtil::IsReflectEven(m_bc_type[Face::XHI][n]))
104 in(i,j,k,n) = in(hi.x-glevel[0],j,k,n);
105 else if(BCUtil::IsReflectOdd(m_bc_type[Face::XHI][n]))
106 in(i,j,k,n) = -in(hi.x-glevel[0],j,k,n);
107 else if(BCUtil::IsPeriodic(m_bc_type[Face::XHI][n])) {}
108 else
109 Util::Abort(INFO, "Incorrect boundary conditions");
110 }
111
112 else if (glevel[1]<0 && (face == Orientation::ylo || face == Orientation::All)) // Bottom boundary
113 {
114 if (BCUtil::IsDirichlet(m_bc_type[Face::YLO][n]))
115 in(i,j,k,n) = m_bc_val[Face::YLO][n](time);
116 else if (BCUtil::IsNeumann(m_bc_type[Face::YLO][n]))
117 in(i,j,k,n) = in(i,j-glevel[1],k,n) - (m_bc_val[Face::YLO].size() > 0 ? m_bc_val[Face::YLO][n](time)*DX[1] : 0);
118 else if (BCUtil::IsReflectEven(m_bc_type[Face::YLO][n]))
119 in(i,j,k,n) = in(i,j-glevel[1],k,n);
120 else if (BCUtil::IsReflectOdd(m_bc_type[Face::YLO][n]))
121 in(i,j,k,n) = -in(i,j-glevel[1],k,n);
122 else if(BCUtil::IsPeriodic(m_bc_type[Face::YLO][n])) {}
123 else
124 Util::Abort(INFO, "Incorrect boundary conditions");
125 }
126 else if (glevel[1]>0 && (face == Orientation::yhi || face == Orientation::All)) // Top boundary
127 {
128 if (BCUtil::IsDirichlet(m_bc_type[Face::YHI][n]))
129 in(i,j,k,n) = m_bc_val[Face::YHI][n](time);
130 else if (BCUtil::IsNeumann(m_bc_type[Face::YHI][n]))
131 in(i,j,k,n) = in(i,j-glevel[1],k,n) - (m_bc_val[Face::YHI].size() > 0 ? m_bc_val[Face::YHI][n](time)*DX[1] : 0);
132 else if (BCUtil::IsReflectEven(m_bc_type[Face::YHI][n]))
133 in(i,j,k,n) = in(i,hi.y-glevel[1],k,n);
134 else if (BCUtil::IsReflectOdd(m_bc_type[Face::YHI][n]))
135 in(i,j,k,n) = -in(i,hi.y-glevel[1],k,n);
136 else if(BCUtil::IsPeriodic(m_bc_type[Face::YHI][n])) {}
137 else
138 Util::Abort(INFO, "Incorrect boundary conditions");
139 }
140
141#if AMREX_SPACEDIM>2
142 else if (glevel[2]<0 && (face == Orientation::zlo || face == Orientation::All))
143 {
144 if (BCUtil::IsDirichlet(m_bc_type[Face::ZLO][n]))
145 in(i,j,k,n) = m_bc_val[Face::ZLO][n](time);
146 else if (BCUtil::IsNeumann(m_bc_type[Face::ZLO][n]))
147 in(i,j,k,n) = in(i,j,k-glevel[2],n) - (m_bc_val[Face::ZLO].size() > 0 ? m_bc_val[Face::ZLO][n](time)*DX[2] : 0);
148 else if (BCUtil::IsReflectEven(m_bc_type[Face::ZLO][n]))
149 in(i,j,k,n) = in(i,j,1-glevel[2],n);
150 else if (BCUtil::IsReflectOdd(m_bc_type[Face::ZLO][n]))
151 in(i,j,k,n) = -in(i,j,1-glevel[2],n);
152 else if(BCUtil::IsPeriodic(m_bc_type[Face::ZLO][n])) {}
153 else Util::Abort(INFO, "Incorrect boundary conditions");
154 }
155 else if (glevel[2]>0 && (face == Orientation::zhi || face == Orientation::All))
156 {
157 if (BCUtil::IsDirichlet(m_bc_type[Face::ZHI][n]))
158 in(i,j,k,n) = m_bc_val[Face::ZHI][n](time);
159 else if(BCUtil::IsNeumann(m_bc_type[Face::ZHI][n]))
160 in(i,j,k,n) = in(i,j,k-glevel[2],n) - (m_bc_val[Face::ZHI].size() > 0 ? m_bc_val[Face::ZHI][n](time)*DX[2] : 0);
161 else if(BCUtil::IsReflectEven(m_bc_type[Face::ZHI][n]))
162 in(i,j,k,n) = in(i,j,hi.z-glevel[2],n);
163 else if(BCUtil::IsReflectOdd(m_bc_type[Face::ZHI][n]))
164 in(i,j,k,n) = -in(i,j,hi.z-glevel[2],n);
165 else if(BCUtil::IsPeriodic(m_bc_type[Face::ZHI][n])) {}
166 else Util::Abort(INFO, "Incorrect boundary conditions");
167 }
168#endif
169 });
170
171 // Average the value of corner cells based on the neighboring ghost cells.
172 // This fixes NAN issues that can arise from neumann conditions calculated in ghost cells
173 // Fixes this issue in 2D only for now.
174 //
175 // TODO: more general fix for 3D cell-based fields
176 amrex::ParallelFor (box,[=] AMREX_GPU_DEVICE(int i, int j, int k)
177 {
178 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) );
179 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) );
180 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) );
181 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) );
182 });
183
184 }
185}
186
187amrex::BCRec
189{
190 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])};
191 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])};
192
193 return amrex::BCRec(bc_lo,bc_hi);
194}
195
196amrex::Array<int,AMREX_SPACEDIM>
198{
199 return {AMREX_D_DECL(BCUtil::IsPeriodic(m_bc_type[Face::XLO][0]),
200 BCUtil::IsPeriodic(m_bc_type[Face::YLO][0]),
201 BCUtil::IsPeriodic(m_bc_type[Face::ZLO][0]))};
202}
203amrex::Periodicity Constant::Periodicity () const
204{
205 return amrex::Periodicity(amrex::IntVect(AMREX_D_DECL(m_geom.Domain().length(0) * BCUtil::IsPeriodic(m_bc_type[Face::XLO][0]),
206 m_geom.Domain().length(1) * BCUtil::IsPeriodic(m_bc_type[Face::YLO][0]),
207 m_geom.Domain().length(2) * BCUtil::IsPeriodic(m_bc_type[Face::ZLO][0]))));
208}
209amrex::Periodicity Constant::Periodicity (const amrex::Box& b) {
210 return amrex::Periodicity(amrex::IntVect(AMREX_D_DECL(b.length(0) * BCUtil::IsPeriodic(m_bc_type[Face::XLO][0]),
211 b.length(1) * BCUtil::IsPeriodic(m_bc_type[Face::YLO][0]),
212 b.length(2) * BCUtil::IsPeriodic(m_bc_type[Face::ZLO][0]))));
213
214}
215
216
217}
#define TEST(x)
Definition Util.H:21
#define INFO
Definition Util.H:20
amrex::Geometry m_geom
Definition BC.H:127
std::array< std::vector< int >, m_nfaces > m_bc_type
Definition Constant.H:147
unsigned int m_ncomp
Definition Constant.H:140
amrex::BCRec GetBCRec() override
Definition Constant.cpp:188
virtual amrex::Periodicity Periodicity() const override
Definition Constant.cpp:203
Constant(int a_ncomp)
Definition Constant.H:63
std::array< std::vector< Numeric::Interpolator::Linear< Set::Scalar > >, m_nfaces > m_bc_val
Definition Constant.H:148
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:197
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
int ReadString(std::string bcstring)
Definition BC.cpp:8
Collection of boundary condition (BC) objects.
Definition BC.cpp:5
Orientation
Definition BC.H:30
@ All
Definition BC.H:31
@ AMREX_D_DECL
Definition BC.H:32
void Abort(const char *msg)
Definition Util.cpp:170
AMREX_FORCE_INLINE void Assert(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
Definition Util.H:70
void Warning(std::string file, std::string func, int line, Args const &... args)
Definition Util.H:181