Line data Source code
1 : //
2 : // Use expressions to define space and time varying boundary conditions
3 : // for elastic problems.
4 : //
5 :
6 : #ifndef BC_OPERATOR_ELASTIC_EXPRESSION_H
7 : #define BC_OPERATOR_ELASTIC_EXPRESSION_H
8 :
9 : #include "IO/ParmParse.H"
10 : #include "BC/Operator/Elastic/Elastic.H"
11 :
12 : #include "AMReX_Parser.H"
13 :
14 : namespace BC
15 : {
16 : namespace Operator
17 : {
18 : namespace Elastic
19 : {
20 : class Expression : public Elastic
21 : {
22 : public:
23 : static constexpr const char* name = "expression";
24 :
25 : //static constexpr const char* const Elastic::strings[];
26 : #if AMREX_SPACEDIM==2
27 : static const constexpr char * const facestr[] = {
28 : "xlo","ylo","xhi","yhi","xloylo","xloyhi","xhiylo","xhiyhi","int"
29 : };
30 : #elif AMREX_SPACEDIM==3
31 : static const constexpr char * const facestr[] = {
32 : "xlo","ylo","zlo","xhi","yhi","zhi",
33 : "ylozlo","ylozhi","yhizlo","yhizhi",
34 : "zloxlo","zloxhi","zhixlo","zhixhi",
35 : "xloylo","xloyhi","xhiylo","xhiyhi",
36 : "xloylozlo","xloylozhi","xloyhizlo","xloyhizhi",
37 : "xhiylozlo","xhiylozhi","xhiyhizlo","xhiyhizhi",
38 : "int"
39 : };
40 : #endif
41 :
42 2 : Expression()
43 2 : {
44 : // By default, all boundary conditions are displacement
45 18 : for (int face = 0; face < m_nfaces; face++)
46 48 : for (int direction = 0; direction < AMREX_SPACEDIM; direction++)
47 : {
48 32 : m_bc_type[face][direction] = Type::Displacement;
49 : }
50 2 : };
51 4 : ~Expression() {};
52 :
53 :
54 : using Elastic::Init;
55 :
56 : virtual void
57 4 : Init(amrex::FabArray<amrex::BaseFab<Set::Vector>> *a_rhs,
58 : const amrex::Geometry &a_geom,
59 : bool a_homogeneous = false) const override
60 : {
61 4 : amrex::Box domain(a_geom.Domain());
62 8 : domain.convert(amrex::IntVect::TheNodeVector());
63 4 : const amrex::Dim3 lo= amrex::lbound(domain), hi = amrex::ubound(domain);
64 8 : for (amrex::MFIter mfi(*a_rhs, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
65 : {
66 4 : amrex::Box bx = mfi.tilebox();
67 4 : bx.grow(2);
68 4 : bx = bx & domain;
69 4 : amrex::Array4<Set::Vector> const& rhs = a_rhs->array(mfi);
70 4 : amrex::ParallelFor (bx,[=] AMREX_GPU_DEVICE(int i, int j, int k) {
71 :
72 14604 : for (int dir = 0; dir < AMREX_SPACEDIM; dir++)
73 : {
74 9736 : Face face = Face::INT;
75 :
76 : #if AMREX_SPACEDIM == 2
77 :
78 9736 : if (i==lo.x && j==lo.y) face = Face::XLO_YLO;
79 9728 : else if (i==lo.x && j==hi.y) face = Face::XLO_YHI;
80 9720 : else if (i==hi.x && j==lo.y) face = Face::XHI_YLO;
81 9712 : else if (i==hi.x && j==hi.y) face = Face::XHI_YHI;
82 :
83 9704 : else if (i==lo.x) face = Face::XLO;
84 9520 : else if (i==hi.x) face = Face::XHI;
85 9336 : else if (j==lo.y) face = Face::YLO;
86 9024 : else if (j==hi.y) face = Face::YHI;
87 :
88 : #elif AMREX_SPACEDIM == 3
89 :
90 0 : if (i==lo.x && j==lo.y && k==lo.z) face = Face::XLO_YLO_ZLO;
91 0 : else if (i==lo.x && j==lo.y && k==hi.z) face = Face::XLO_YLO_ZHI;
92 0 : else if (i==lo.x && j==hi.y && k==lo.z) face = Face::XLO_YHI_ZLO;
93 0 : else if (i==lo.x && j==hi.y && k==hi.z) face = Face::XLO_YHI_ZHI;
94 0 : else if (i==hi.x && j==lo.y && k==lo.z) face = Face::XHI_YLO_ZLO;
95 0 : else if (i==hi.x && j==lo.y && k==hi.z) face = Face::XHI_YLO_ZHI;
96 0 : else if (i==hi.x && j==hi.y && k==lo.z) face = Face::XHI_YHI_ZLO;
97 0 : else if (i==hi.x && j==hi.y && k==hi.z) face = Face::XHI_YHI_ZHI;
98 :
99 0 : else if (j==lo.y && k==lo.z) face = Face::YLO_ZLO;
100 0 : else if (j==lo.y && k==hi.z) face = Face::YLO_ZHI;
101 0 : else if (j==hi.y && k==lo.z) face = Face::YHI_ZLO;
102 0 : else if (j==hi.y && k==hi.z) face = Face::YHI_ZHI;
103 0 : else if (k==lo.z && i==lo.x) face = Face::ZLO_XLO;
104 0 : else if (k==lo.z && i==hi.x) face = Face::ZLO_XHI;
105 0 : else if (k==hi.z && i==lo.x) face = Face::ZHI_XLO;
106 0 : else if (k==hi.z && i==hi.x) face = Face::ZHI_XHI;
107 0 : else if (i==lo.x && j==lo.y) face = Face::XLO_YLO;
108 0 : else if (i==lo.x && j==hi.y) face = Face::XLO_YHI;
109 0 : else if (i==hi.x && j==lo.y) face = Face::XHI_YLO;
110 0 : else if (i==hi.x && j==hi.y) face = Face::XHI_YHI;
111 :
112 0 : else if (i==lo.x) face = Face::XLO;
113 0 : else if (i==hi.x) face = Face::XHI;
114 0 : else if (j==lo.y) face = Face::YLO;
115 0 : else if (j==hi.y) face = Face::YHI;
116 0 : else if (k==lo.z) face = Face::ZLO;
117 0 : else if (k==hi.z) face = Face::ZHI;
118 :
119 : #endif
120 :
121 9736 : amrex::IndexType type = a_rhs->ixType();
122 9736 : if (!(face == Face::INT))
123 : {
124 1024 : if (a_homogeneous && m_bc_type[face][dir] == Type::Displacement)
125 0 : rhs(i,j,k)(dir) = 0.0;
126 : else
127 : {
128 1024 : Set::Vector x = Set::Position(i, j, k, a_geom, type);
129 : #if AMREX_SPACEDIM==1
130 : rhs(i,j,k)(dir) = m_bc_func[face][dir](x(0),0.0,0.0,m_time);
131 : #elif AMREX_SPACEDIM==2
132 3072 : rhs(i,j,k)(dir) = m_bc_func[face][dir](x(0),x(1),0.0,m_time);
133 : #elif AMREX_SPACEDIM==3
134 0 : rhs(i,j,k)(dir) = m_bc_func[face][dir](x(0),x(1),x(2),m_time);
135 : #endif
136 : }
137 : }
138 : }
139 4868 : });
140 4 : }
141 4 : }
142 :
143 :
144 : virtual void
145 0 : Init(amrex::MultiFab * a_rhs,
146 : const amrex::Geometry &a_geom,
147 : bool a_homogeneous = false) const override
148 : {
149 0 : amrex::Box domain(a_geom.Domain());
150 0 : domain.convert(amrex::IntVect::TheNodeVector());
151 0 : const amrex::Dim3 lo= amrex::lbound(domain), hi = amrex::ubound(domain);
152 0 : for (amrex::MFIter mfi(*a_rhs, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
153 : {
154 0 : amrex::Box bx = mfi.tilebox();
155 0 : bx.grow(2);
156 0 : bx = bx & domain;
157 0 : amrex::Array4<amrex::Real> const& rhs = a_rhs->array(mfi);
158 0 : amrex::ParallelFor (bx,[=] AMREX_GPU_DEVICE(int i, int j, int k) {
159 :
160 0 : for (int dir = 0; dir < AMREX_SPACEDIM; dir++)
161 : {
162 0 : Face face = Face::INT;
163 :
164 : #if AMREX_SPACEDIM == 2
165 :
166 0 : if (i==lo.x && j==lo.y) face = Face::XLO_YLO;
167 0 : else if (i==lo.x && j==hi.y) face = Face::XLO_YHI;
168 0 : else if (i==hi.x && j==lo.y) face = Face::XHI_YLO;
169 0 : else if (i==hi.x && j==hi.y) face = Face::XHI_YHI;
170 :
171 0 : else if (i==lo.x) face = Face::XLO;
172 0 : else if (i==hi.x) face = Face::XHI;
173 0 : else if (j==lo.y) face = Face::YLO;
174 0 : else if (j==hi.y) face = Face::YHI;
175 :
176 : #elif AMREX_SPACEDIM == 3
177 :
178 0 : if (i==lo.x && j==lo.y && k==lo.z) face = Face::XLO_YLO_ZLO;
179 0 : else if (i==lo.x && j==lo.y && k==hi.z) face = Face::XLO_YLO_ZHI;
180 0 : else if (i==lo.x && j==hi.y && k==lo.z) face = Face::XLO_YHI_ZLO;
181 0 : else if (i==lo.x && j==hi.y && k==hi.z) face = Face::XLO_YHI_ZHI;
182 0 : else if (i==hi.x && j==lo.y && k==lo.z) face = Face::XHI_YLO_ZLO;
183 0 : else if (i==hi.x && j==lo.y && k==hi.z) face = Face::XHI_YLO_ZHI;
184 0 : else if (i==hi.x && j==hi.y && k==lo.z) face = Face::XHI_YHI_ZLO;
185 0 : else if (i==hi.x && j==hi.y && k==hi.z) face = Face::XHI_YHI_ZHI;
186 :
187 0 : else if (j==lo.y && k==lo.z) face = Face::YLO_ZLO;
188 0 : else if (j==lo.y && k==hi.z) face = Face::YLO_ZHI;
189 0 : else if (j==hi.y && k==lo.z) face = Face::YHI_ZLO;
190 0 : else if (j==hi.y && k==hi.z) face = Face::YHI_ZHI;
191 0 : else if (k==lo.z && i==lo.x) face = Face::ZLO_XLO;
192 0 : else if (k==lo.z && i==hi.x) face = Face::ZLO_XHI;
193 0 : else if (k==hi.z && i==lo.x) face = Face::ZHI_XLO;
194 0 : else if (k==hi.z && i==hi.x) face = Face::ZHI_XHI;
195 0 : else if (i==lo.x && j==lo.y) face = Face::XLO_YLO;
196 0 : else if (i==lo.x && j==hi.y) face = Face::XLO_YHI;
197 0 : else if (i==hi.x && j==lo.y) face = Face::XHI_YLO;
198 0 : else if (i==hi.x && j==hi.y) face = Face::XHI_YHI;
199 :
200 0 : else if (i==lo.x) face = Face::XLO;
201 0 : else if (i==hi.x) face = Face::XHI;
202 0 : else if (j==lo.y) face = Face::YLO;
203 0 : else if (j==hi.y) face = Face::YHI;
204 0 : else if (k==lo.z) face = Face::ZLO;
205 0 : else if (k==hi.z) face = Face::ZHI;
206 :
207 : #endif
208 :
209 0 : amrex::IndexType type = a_rhs->ixType();
210 0 : if (!(face == Face::INT))
211 : {
212 0 : if (a_homogeneous && m_bc_type[face][dir] == Type::Displacement)
213 0 : rhs(i,j,k,dir) = 0.0;
214 : else
215 : {
216 0 : Set::Vector x = Set::Position(i, j, k, a_geom, type);
217 : #if AMREX_SPACEDIM==1
218 : rhs(i,j,k,dir) = (m_bc_func[face][dir])(x(0),0.0,0.0,m_time);
219 : #elif AMREX_SPACEDIM==2
220 0 : rhs(i,j,k,dir) = (m_bc_func[face][dir])(x(0),x(1),0.0,m_time);
221 : #elif AMREX_SPACEDIM==3
222 0 : rhs(i,j,k,dir) = (m_bc_func[face][dir])(x(0),x(1),x(2),m_time);
223 : #endif
224 : }
225 : }
226 : }
227 0 : });
228 0 : }
229 0 : }
230 :
231 :
232 :
233 : virtual
234 0 : std::array<Type,AMREX_SPACEDIM> getType (
235 : const int &i, const int &j, [[maybe_unused]] const int &k,
236 : const amrex::Box &domain) override
237 : {
238 : (void)i, (void)j, (void)k;
239 0 : amrex::IntVect m(AMREX_D_DECL(i,j,k));
240 : const amrex::Dim3 lo = amrex::lbound(domain), hi = amrex::ubound(domain);
241 :
242 : // Corners
243 : #if AMREX_SPACEDIM == 2
244 0 : if (m[0] == lo.x && m[1] == lo.y) return m_bc_type[Face::XLO_YLO];
245 0 : if (m[0] == lo.x && m[1] == hi.y) return m_bc_type[Face::XLO_YHI];
246 0 : if (m[0] == hi.x && m[1] == lo.y) return m_bc_type[Face::XHI_YLO];
247 0 : if (m[0] == hi.x && m[1] == hi.y) return m_bc_type[Face::XHI_YHI];
248 0 : if (m[0] == lo.x) return m_bc_type[Face::XLO];
249 0 : if (m[0] == hi.x) return m_bc_type[Face::XHI];
250 0 : if (m[1] == lo.y) return m_bc_type[Face::YLO];
251 0 : if (m[1] == hi.y) return m_bc_type[Face::YHI];
252 :
253 : #elif AMREX_SPACEDIM == 3
254 :
255 0 : if (m[0] == lo.x && m[1] == lo.y && m[2] == lo.z) return m_bc_type[Face::XLO_YLO_ZLO];
256 0 : if (m[0] == lo.x && m[1] == lo.y && m[2] == hi.z) return m_bc_type[Face::XLO_YLO_ZHI];
257 0 : if (m[0] == lo.x && m[1] == hi.y && m[2] == lo.z) return m_bc_type[Face::XLO_YHI_ZLO];
258 0 : if (m[0] == lo.x && m[1] == hi.y && m[2] == hi.z) return m_bc_type[Face::XLO_YHI_ZHI];
259 0 : if (m[0] == hi.x && m[1] == lo.y && m[2] == lo.z) return m_bc_type[Face::XHI_YLO_ZLO];
260 0 : if (m[0] == hi.x && m[1] == lo.y && m[2] == hi.z) return m_bc_type[Face::XHI_YLO_ZHI];
261 0 : if (m[0] == hi.x && m[1] == hi.y && m[2] == lo.z) return m_bc_type[Face::XHI_YHI_ZLO];
262 0 : if (m[0] == hi.x && m[1] == hi.y && m[2] == hi.z) return m_bc_type[Face::XHI_YHI_ZHI];
263 :
264 0 : if (m[1] == lo.y && m[2] == lo.z) return m_bc_type[Face::YLO_ZLO];
265 0 : if (m[1] == lo.y && m[2] == hi.z) return m_bc_type[Face::YLO_ZHI];
266 0 : if (m[1] == hi.y && m[2] == lo.z) return m_bc_type[Face::YHI_ZLO];
267 0 : if (m[1] == hi.y && m[2] == hi.z) return m_bc_type[Face::YHI_ZHI];
268 0 : if (m[2] == lo.z && m[0] == lo.x) return m_bc_type[Face::ZLO_XLO];
269 0 : if (m[2] == lo.z && m[0] == hi.x) return m_bc_type[Face::ZLO_XHI];
270 0 : if (m[2] == hi.z && m[0] == lo.x) return m_bc_type[Face::ZHI_XLO];
271 0 : if (m[2] == hi.z && m[0] == hi.x) return m_bc_type[Face::ZHI_XHI];
272 0 : if (m[0] == lo.x && m[1] == lo.y) return m_bc_type[Face::XLO_YLO];
273 0 : if (m[0] == lo.x && m[1] == hi.y) return m_bc_type[Face::XLO_YHI];
274 0 : if (m[0] == hi.x && m[1] == lo.y) return m_bc_type[Face::XHI_YLO];
275 0 : if (m[0] == hi.x && m[1] == hi.y) return m_bc_type[Face::XHI_YHI];
276 :
277 0 : if (m[0] == lo.x) return m_bc_type[Face::XLO];
278 0 : if (m[0] == hi.x) return m_bc_type[Face::XHI];
279 0 : if (m[1] == lo.y) return m_bc_type[Face::YLO];
280 0 : if (m[1] == hi.y) return m_bc_type[Face::YHI];
281 0 : if (m[2] == lo.z) return m_bc_type[Face::ZLO];
282 0 : if (m[2] == hi.z) return m_bc_type[Face::ZHI];
283 :
284 : #endif
285 :
286 0 : return {AMREX_D_DECL(Type::None,Type::None,Type::None)};
287 : }
288 :
289 :
290 : AMREX_FORCE_INLINE
291 215936 : Set::Vector operator () (const Set::Vector &u,
292 : const Set::Matrix &gradu,
293 : const Set::Matrix &sigma,
294 : const int &i, const int &j, const int &k,
295 : const amrex::Box &domain) override
296 : {
297 : (void)i; (void)j; (void)k; // Suppress "unused variable" warnings
298 : //Set::Vector f;
299 :
300 : const amrex::Dim3 lo= amrex::lbound(domain), hi = amrex::ubound(domain);
301 :
302 215936 : amrex::IntVect m(AMREX_D_DECL(i,j,k));
303 :
304 : // Corners
305 : #if AMREX_SPACEDIM == 2
306 :
307 268684 : if (m[0] == lo.x && m[1] == lo.y) return set(m_bc_type[Face::XLO_YLO], u, gradu, sigma, Set::Vector(-SQRT2INV, -SQRT2INV));
308 256780 : if (m[0] == lo.x && m[1] == hi.y) return set(m_bc_type[Face::XLO_YHI], u, gradu, sigma, Set::Vector(-SQRT2INV, +SQRT2INV));
309 256780 : if (m[0] == hi.x && m[1] == lo.y) return set(m_bc_type[Face::XHI_YLO], u, gradu, sigma, Set::Vector(+SQRT2INV, -SQRT2INV));
310 244876 : if (m[0] == hi.x && m[1] == hi.y) return set(m_bc_type[Face::XHI_YHI], u, gradu, sigma, Set::Vector(+SQRT2INV, +SQRT2INV));
311 :
312 227020 : if (m[0] == lo.x) return set(m_bc_type[Face::XLO], u, gradu, sigma, Set::Vector(-1, 0));
313 192128 : if (m[0] == hi.x) return set(m_bc_type[Face::XHI], u, gradu, sigma, Set::Vector(+1, 0));
314 183516 : if (m[1] == lo.y) return set(m_bc_type[Face::YLO], u, gradu, sigma, Set::Vector( 0,-1));
315 122344 : if (m[1] == hi.y) return set(m_bc_type[Face::YHI], u, gradu, sigma, Set::Vector( 0,+1));
316 :
317 : #elif AMREX_SPACEDIM == 3
318 :
319 0 : if (m[0] == lo.x && m[1] == lo.y && m[2] == lo.z) return set(m_bc_type[Face::XLO_YLO_ZLO], u, gradu, sigma, Set::Vector(-SQRT3INV,-SQRT3INV,-SQRT3INV));
320 0 : if (m[0] == lo.x && m[1] == lo.y && m[2] == hi.z) return set(m_bc_type[Face::XLO_YLO_ZHI], u, gradu, sigma, Set::Vector(-SQRT3INV,-SQRT3INV,+SQRT3INV));
321 0 : if (m[0] == lo.x && m[1] == hi.y && m[2] == lo.z) return set(m_bc_type[Face::XLO_YHI_ZLO], u, gradu, sigma, Set::Vector(-SQRT3INV,+SQRT3INV,-SQRT3INV));
322 0 : if (m[0] == lo.x && m[1] == hi.y && m[2] == hi.z) return set(m_bc_type[Face::XLO_YHI_ZHI], u, gradu, sigma, Set::Vector(-SQRT3INV,+SQRT3INV,+SQRT3INV));
323 0 : if (m[0] == hi.x && m[1] == lo.y && m[2] == lo.z) return set(m_bc_type[Face::XHI_YLO_ZLO], u, gradu, sigma, Set::Vector(+SQRT3INV,-SQRT3INV,-SQRT3INV));
324 0 : if (m[0] == hi.x && m[1] == lo.y && m[2] == hi.z) return set(m_bc_type[Face::XHI_YLO_ZHI], u, gradu, sigma, Set::Vector(+SQRT3INV,-SQRT3INV,+SQRT3INV));
325 0 : if (m[0] == hi.x && m[1] == hi.y && m[2] == lo.z) return set(m_bc_type[Face::XHI_YHI_ZLO], u, gradu, sigma, Set::Vector(+SQRT3INV,+SQRT3INV,-SQRT3INV));
326 0 : if (m[0] == hi.x && m[1] == hi.y && m[2] == hi.z) return set(m_bc_type[Face::XHI_YHI_ZHI], u, gradu, sigma, Set::Vector(+SQRT3INV,+SQRT3INV,+SQRT3INV));
327 :
328 0 : if (m[1] == lo.y && m[2] == lo.z) return set(m_bc_type[Face::YLO_ZLO], u, gradu, sigma, Set::Vector(0, -SQRT2INV,-SQRT2INV));
329 0 : if (m[1] == lo.y && m[2] == hi.z) return set(m_bc_type[Face::YLO_ZHI], u, gradu, sigma, Set::Vector(0, -SQRT2INV,+SQRT2INV));
330 0 : if (m[1] == hi.y && m[2] == lo.z) return set(m_bc_type[Face::YHI_ZLO], u, gradu, sigma, Set::Vector(0, +SQRT2INV,-SQRT2INV));
331 0 : if (m[1] == hi.y && m[2] == hi.z) return set(m_bc_type[Face::YHI_ZHI], u, gradu, sigma, Set::Vector(0, +SQRT2INV,+SQRT2INV));
332 0 : if (m[2] == lo.z && m[0] == lo.x) return set(m_bc_type[Face::ZLO_XLO], u, gradu, sigma, Set::Vector(-SQRT2INV, 0, -SQRT2INV));
333 0 : if (m[2] == lo.z && m[0] == hi.x) return set(m_bc_type[Face::ZLO_XHI], u, gradu, sigma, Set::Vector(+SQRT2INV, 0, -SQRT2INV));
334 0 : if (m[2] == hi.z && m[0] == lo.x) return set(m_bc_type[Face::ZHI_XLO], u, gradu, sigma, Set::Vector(-SQRT2INV, 0, +SQRT2INV));
335 0 : if (m[2] == hi.z && m[0] == hi.x) return set(m_bc_type[Face::ZHI_XHI], u, gradu, sigma, Set::Vector(+SQRT2INV, 0, +SQRT2INV));
336 0 : if (m[0] == lo.x && m[1] == lo.y) return set(m_bc_type[Face::XLO_YLO], u, gradu, sigma, Set::Vector(-SQRT2INV, -SQRT2INV,0 ));
337 0 : if (m[0] == lo.x && m[1] == hi.y) return set(m_bc_type[Face::XLO_YHI], u, gradu, sigma, Set::Vector(-SQRT2INV, +SQRT2INV,0 ));
338 0 : if (m[0] == hi.x && m[1] == lo.y) return set(m_bc_type[Face::XHI_YLO], u, gradu, sigma, Set::Vector(+SQRT2INV, -SQRT2INV,0 ));
339 0 : if (m[0] == hi.x && m[1] == hi.y) return set(m_bc_type[Face::XHI_YHI], u, gradu, sigma, Set::Vector(+SQRT2INV, +SQRT2INV,0 ));
340 :
341 0 : if (m[0] == lo.x) return set(m_bc_type[Face::XLO], u, gradu, sigma, Set::Vector(-1, 0, 0));
342 0 : if (m[0] == hi.x) return set(m_bc_type[Face::XHI], u, gradu, sigma, Set::Vector(+1, 0, 0));
343 0 : if (m[1] == lo.y) return set(m_bc_type[Face::YLO], u, gradu, sigma, Set::Vector( 0,-1, 0));
344 0 : if (m[1] == hi.y) return set(m_bc_type[Face::YHI], u, gradu, sigma, Set::Vector( 0,+1, 0));
345 0 : if (m[2] == lo.z) return set(m_bc_type[Face::ZLO], u, gradu, sigma, Set::Vector( 0, 0,-1));
346 0 : if (m[2] == hi.z) return set(m_bc_type[Face::ZHI], u, gradu, sigma, Set::Vector( 0, 0,+1));
347 :
348 : #endif
349 :
350 0 : Util::Abort(INFO,"Boundary condition error");
351 0 : return Set::Vector::Zero();
352 : }
353 :
354 : AMREX_FORCE_INLINE
355 : Set::Vector set(std::array<Type,AMREX_SPACEDIM> &bc_type,
356 : const Set::Vector &u, const Set::Matrix &gradu, const Set::Matrix &sigma, Set::Vector n) const
357 : {
358 215936 : Set::Vector f = Set::Vector::Zero();
359 647808 : for (int i = 0; i < AMREX_SPACEDIM; i++)
360 : {
361 431872 : if (bc_type[i] == Type::Displacement)
362 151848 : f(i) = u(i);
363 280024 : else if (bc_type[i] == Type::Traction)
364 280024 : f(i) = (sigma*n)(i);
365 0 : else if (bc_type[i] == Type::Neumann)
366 0 : f(i) = (gradu*n)(i);
367 0 : else if (bc_type[i] == Periodic)
368 0 : continue;
369 : }
370 215936 : return f;
371 : }
372 :
373 : protected:
374 :
375 : #if AMREX_SPACEDIM==2
376 : static const int m_nfaces = 8;
377 : #elif AMREX_SPACEDIM==3
378 : static const int m_nfaces = 26;
379 : #endif
380 :
381 : std::array<std::array<Type, AMREX_SPACEDIM>, m_nfaces> m_bc_type;
382 : //std::array<std::array<FunctionParserAD,AMREX_SPACEDIM>, m_nfaces> m_bc_func;
383 : std::array<std::array<amrex::Parser,AMREX_SPACEDIM>, m_nfaces> m_bc_func_parser;
384 : std::array<std::array<amrex::ParserExecutor<4>,AMREX_SPACEDIM>, m_nfaces> m_bc_func;
385 :
386 : public:
387 :
388 : //
389 : // This is basically the same as :ref:`BC::Operator::Elastic::Constant` except that
390 : // you can use dynamically compiled expressions in space and time to define values.
391 : //
392 : // Usage is exactly the same except that the "val" inputs can depend on x, y, z, and t.
393 : //
394 2 : static void Parse(Expression & value, IO::ParmParse & pp)
395 : {
396 2 : std::map<std::string, Type> bcmap;
397 4 : bcmap["displacement"] = Type::Displacement;
398 4 : bcmap["disp"] = Type::Displacement;
399 4 : bcmap["neumann"] = Type::Neumann;
400 4 : bcmap["traction"] = Type::Traction;
401 4 : bcmap["trac"] = Type::Traction;
402 2 : bcmap["periodic"] = Type::Periodic;
403 :
404 2 : std::vector<std::string> str;
405 :
406 : // TYPES
407 :
408 : #if AMREX_SPACEDIM==3
409 0 : if (pp.contains("type.xloylozlo")) { pp_queryarr("type.xloylozlo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XLO_YLO_ZLO][i] = bcmap[str[i]]; } // 3D Corner
410 0 : if (pp.contains("type.xloylozhi")) { pp_queryarr("type.xloylozhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XLO_YLO_ZHI][i] = bcmap[str[i]]; } // 3D Corner
411 0 : if (pp.contains("type.xloyhizlo")) { pp_queryarr("type.xloyhizlo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XLO_YHI_ZLO][i] = bcmap[str[i]]; } // 3D Corner
412 0 : if (pp.contains("type.xloyhizhi")) { pp_queryarr("type.xloyhizhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XLO_YHI_ZHI][i] = bcmap[str[i]]; } // 3D Corner
413 0 : if (pp.contains("type.xhiylozlo")) { pp_queryarr("type.xhiylozlo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XHI_YLO_ZLO][i] = bcmap[str[i]]; } // 3D Corner
414 0 : if (pp.contains("type.xhiylozhi")) { pp_queryarr("type.xhiylozhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XHI_YLO_ZHI][i] = bcmap[str[i]]; } // 3D Corner
415 0 : if (pp.contains("type.xhiyhizlo")) { pp_queryarr("type.xhiyhizlo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XHI_YHI_ZLO][i] = bcmap[str[i]]; } // 3D Corner
416 0 : if (pp.contains("type.xhiyhizhi")) { pp_queryarr("type.xhiyhizhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XHI_YHI_ZHI][i] = bcmap[str[i]]; } // 3D Corner
417 : #endif
418 :
419 : #if AMREX_SPACEDIM==3
420 0 : if (pp.contains("type.ylozlo")) { pp_queryarr("type.ylozlo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::YLO_ZLO][i] = bcmap[str[i]]; } // 3D Edge
421 0 : if (pp.contains("type.ylozhi")) { pp_queryarr("type.ylozhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::YLO_ZHI][i] = bcmap[str[i]]; } // 3D Edge
422 0 : if (pp.contains("type.yhizlo")) { pp_queryarr("type.yhizlo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::YHI_ZLO][i] = bcmap[str[i]]; } // 3D Edge
423 0 : if (pp.contains("type.yhizhi")) { pp_queryarr("type.yhizhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::YHI_ZHI][i] = bcmap[str[i]]; } // 3D Edge
424 0 : if (pp.contains("type.zloxlo")) { pp_queryarr("type.zloxlo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::ZLO_XLO][i] = bcmap[str[i]]; } // 3D Edge
425 0 : if (pp.contains("type.zloxhi")) { pp_queryarr("type.zloxhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::ZLO_XHI][i] = bcmap[str[i]]; } // 3D Edge
426 0 : if (pp.contains("type.zhixlo")) { pp_queryarr("type.zhixlo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::ZHI_XLO][i] = bcmap[str[i]]; } // 3D Edge
427 0 : if (pp.contains("type.zhixhi")) { pp_queryarr("type.zhixhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::ZHI_XHI][i] = bcmap[str[i]]; } // 3D Edge
428 : #endif
429 12 : if (pp.contains("type.xloylo")) { pp_queryarr("type.xloylo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XLO_YLO][i] = bcmap[str[i]]; } // 3D Edge / 2D Corner
430 12 : if (pp.contains("type.xloyhi")) { pp_queryarr("type.xloyhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XLO_YHI][i] = bcmap[str[i]]; } // 3D Edge / 2D Corner
431 12 : if (pp.contains("type.xhiylo")) { pp_queryarr("type.xhiylo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XHI_YLO][i] = bcmap[str[i]]; } // 3D Edge / 2D Corner
432 12 : if (pp.contains("type.xhiyhi")) { pp_queryarr("type.xhiyhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XHI_YHI][i] = bcmap[str[i]]; } // 3D Edge / 2D Corner
433 :
434 12 : if (pp.contains("type.xlo")) { pp_queryarr("type.xlo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XLO][i] = bcmap[str[i]]; } // 3D Face 2D Edge
435 12 : if (pp.contains("type.xhi")) { pp_queryarr("type.xhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::XHI][i] = bcmap[str[i]]; } // 3D Face 2D Edge
436 12 : if (pp.contains("type.ylo")) { pp_queryarr("type.ylo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::YLO][i] = bcmap[str[i]]; } // 3D Face 2D Edge
437 20 : if (pp.contains("type.yhi")) { pp_queryarr("type.yhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::YHI][i] = bcmap[str[i]]; } // 3D Face 2D Edge
438 : #if AMREX_SPACEDIM==3
439 0 : if (pp.contains("type.zlo")) { pp_queryarr("type.zlo",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::ZLO][i] = bcmap[str[i]]; } // 3D Face
440 0 : if (pp.contains("type.zhi")) { pp_queryarr("type.zhi",str); for (int i = 0; i < AMREX_SPACEDIM; i++) value.m_bc_type[Face::ZHI][i] = bcmap[str[i]]; } // 3D Face
441 : #endif
442 :
443 : // VALS
444 :
445 18 : for (int face = 0; face != Face::INT; face++)
446 : {
447 32 : std::vector<std::string> val(AMREX_SPACEDIM,"0.0");
448 32 : val.resize(AMREX_SPACEDIM,"0.0");
449 64 : std::string querystr = std::string("val.") + std::string(facestr[face]);
450 80 : pp_queryarr(querystr.c_str(),val);
451 48 : for (int i = 0 ; i < AMREX_SPACEDIM; i++)
452 : {
453 32 : value.m_bc_func_parser[face][i] = amrex::Parser(val[i].c_str());
454 224 : value.m_bc_func_parser[face][i].registerVariables({"x","y","z","t"});
455 32 : value.m_bc_func[face][i] = value.m_bc_func_parser[face][i].compile<4>();
456 : }
457 16 : }
458 :
459 : #if AMREX_SPACEDIM==2
460 : // We may wish to use an input file that has 3D BC inputs
461 : // This will prevent the parser from complaining that there are unused inputs.
462 : std::vector<std::string> ignore_in_2d = {
463 : "zlo","zhi",
464 : "zhixlo","zloxlo","zhixhi","zloxhi","ylozlo","ylozhi","yhizlo","yhizhi",
465 4 : "xloylozlo","xloylozhi","xloyhizlo","xloyhizhi","xhiylozlo","xhiylozhi","xhiyhizlo","xhiyhizhi"};
466 38 : for (unsigned int n = 0; n < ignore_in_2d.size(); n++)
467 : {
468 72 : std::string querystr = std::string("val.") + ignore_in_2d[n];
469 36 : pp.ignore(querystr);
470 72 : querystr = std::string("type.") + ignore_in_2d[n];
471 36 : pp.ignore(querystr);
472 36 : }
473 : #endif
474 :
475 :
476 98 : }
477 2 : Expression(IO::ParmParse &pp, std::string name): Expression()
478 8 : {pp_queryclass(name,*this);}
479 : };
480 : }
481 : }
482 : }
483 : #endif
|