1 #ifndef BC_OPERATOR_ELASTIC_EXPRESSION_H
2 #define BC_OPERATOR_ELASTIC_EXPRESSION_H
9 #include "AMReX_Parser.H"
20 static constexpr
const char*
name =
"expression";
24 static const constexpr
char *
const facestr[] = {
25 "xlo",
"ylo",
"xhi",
"yhi",
"xloylo",
"xloyhi",
"xhiylo",
"xhiyhi",
"int"
27 #elif AMREX_SPACEDIM==3
28 static const constexpr
char *
const facestr[] = {
29 "xlo",
"ylo",
"zlo",
"xhi",
"yhi",
"zhi",
30 "ylozlo",
"ylozhi",
"yhizlo",
"yhizhi",
31 "zloxlo",
"zloxhi",
"zhixlo",
"zhixhi",
32 "xloylo",
"xloyhi",
"xhiylo",
"xhiyhi",
33 "xloylozlo",
"xloylozhi",
"xloyhizlo",
"xloyhizhi",
34 "xhiylozlo",
"xhiylozhi",
"xhiyhizlo",
"xhiyhizhi",
42 for (
int face = 0; face < m_nfaces; face++)
43 for (
int direction = 0; direction < AMREX_SPACEDIM; direction++)
45 m_bc_type[face][direction] = Type::Displacement;
54 Init(amrex::FabArray<amrex::BaseFab<Set::Vector>> *a_rhs,
55 const amrex::Geometry &a_geom,
56 bool a_homogeneous =
false)
const override
58 amrex::Box domain(a_geom.Domain());
59 domain.convert(amrex::IntVect::TheNodeVector());
60 const amrex::Dim3 lo= amrex::lbound(domain), hi = amrex::ubound(domain);
61 for (amrex::MFIter mfi(*a_rhs, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
63 amrex::Box bx = mfi.tilebox();
66 amrex::Array4<Set::Vector>
const& rhs = a_rhs->array(mfi);
67 amrex::ParallelFor (bx,[=] AMREX_GPU_DEVICE(
int i,
int j,
int k) {
69 for (
int dir = 0; dir < AMREX_SPACEDIM; dir++)
71 Face face = Face::INT;
73 #if AMREX_SPACEDIM == 2
75 if (i==lo.x && j==lo.y) face = Face::XLO_YLO;
76 else if (i==lo.x && j==hi.y) face = Face::XLO_YHI;
77 else if (i==hi.x && j==lo.y) face = Face::XHI_YLO;
78 else if (i==hi.x && j==hi.y) face = Face::XHI_YHI;
80 else if (i==lo.x) face = Face::XLO;
81 else if (i==hi.x) face = Face::XHI;
82 else if (j==lo.y) face = Face::YLO;
83 else if (j==hi.y) face = Face::YHI;
85 #elif AMREX_SPACEDIM == 3
87 if (i==lo.x && j==lo.y && k==lo.z) face = Face::XLO_YLO_ZLO;
88 else if (i==lo.x && j==lo.y && k==hi.z) face = Face::XLO_YLO_ZHI;
89 else if (i==lo.x && j==hi.y && k==lo.z) face = Face::XLO_YHI_ZLO;
90 else if (i==lo.x && j==hi.y && k==hi.z) face = Face::XLO_YHI_ZHI;
91 else if (i==hi.x && j==lo.y && k==lo.z) face = Face::XHI_YLO_ZLO;
92 else if (i==hi.x && j==lo.y && k==hi.z) face = Face::XHI_YLO_ZHI;
93 else if (i==hi.x && j==hi.y && k==lo.z) face = Face::XHI_YHI_ZLO;
94 else if (i==hi.x && j==hi.y && k==hi.z) face = Face::XHI_YHI_ZHI;
96 else if (j==lo.y && k==lo.z) face = Face::YLO_ZLO;
97 else if (j==lo.y && k==hi.z) face = Face::YLO_ZHI;
98 else if (j==hi.y && k==lo.z) face = Face::YHI_ZLO;
99 else if (j==hi.y && k==hi.z) face = Face::YHI_ZHI;
100 else if (k==lo.z && i==lo.x) face = Face::ZLO_XLO;
101 else if (k==lo.z && i==hi.x) face = Face::ZLO_XHI;
102 else if (k==hi.z && i==lo.x) face = Face::ZHI_XLO;
103 else if (k==hi.z && i==hi.x) face = Face::ZHI_XHI;
104 else if (i==lo.x && j==lo.y) face = Face::XLO_YLO;
105 else if (i==lo.x && j==hi.y) face = Face::XLO_YHI;
106 else if (i==hi.x && j==lo.y) face = Face::XHI_YLO;
107 else if (i==hi.x && j==hi.y) face = Face::XHI_YHI;
109 else if (i==lo.x) face = Face::XLO;
110 else if (i==hi.x) face = Face::XHI;
111 else if (j==lo.y) face = Face::YLO;
112 else if (j==hi.y) face = Face::YHI;
113 else if (k==lo.z) face = Face::ZLO;
114 else if (k==hi.z) face = Face::ZHI;
118 amrex::IndexType type = a_rhs->ixType();
119 if (!(face == Face::INT))
121 if (a_homogeneous &&
m_bc_type[face][dir] == Type::Displacement)
122 rhs(i,j,k)(dir) = 0.0;
126 #if AMREX_SPACEDIM==1
128 #elif AMREX_SPACEDIM==2
130 #elif AMREX_SPACEDIM==3
143 const amrex::Geometry &a_geom,
144 bool a_homogeneous =
false)
const override
146 amrex::Box domain(a_geom.Domain());
147 domain.convert(amrex::IntVect::TheNodeVector());
148 const amrex::Dim3 lo= amrex::lbound(domain), hi = amrex::ubound(domain);
149 for (amrex::MFIter mfi(*a_rhs, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
151 amrex::Box bx = mfi.tilebox();
154 amrex::Array4<amrex::Real>
const& rhs = a_rhs->array(mfi);
155 amrex::ParallelFor (bx,[=] AMREX_GPU_DEVICE(
int i,
int j,
int k) {
157 for (
int dir = 0; dir < AMREX_SPACEDIM; dir++)
159 Face face = Face::INT;
161 #if AMREX_SPACEDIM == 2
163 if (i==lo.x && j==lo.y) face = Face::XLO_YLO;
164 else if (i==lo.x && j==hi.y) face = Face::XLO_YHI;
165 else if (i==hi.x && j==lo.y) face = Face::XHI_YLO;
166 else if (i==hi.x && j==hi.y) face = Face::XHI_YHI;
168 else if (i==lo.x) face = Face::XLO;
169 else if (i==hi.x) face = Face::XHI;
170 else if (j==lo.y) face = Face::YLO;
171 else if (j==hi.y) face = Face::YHI;
173 #elif AMREX_SPACEDIM == 3
175 if (i==lo.x && j==lo.y && k==lo.z) face = Face::XLO_YLO_ZLO;
176 else if (i==lo.x && j==lo.y && k==hi.z) face = Face::XLO_YLO_ZHI;
177 else if (i==lo.x && j==hi.y && k==lo.z) face = Face::XLO_YHI_ZLO;
178 else if (i==lo.x && j==hi.y && k==hi.z) face = Face::XLO_YHI_ZHI;
179 else if (i==hi.x && j==lo.y && k==lo.z) face = Face::XHI_YLO_ZLO;
180 else if (i==hi.x && j==lo.y && k==hi.z) face = Face::XHI_YLO_ZHI;
181 else if (i==hi.x && j==hi.y && k==lo.z) face = Face::XHI_YHI_ZLO;
182 else if (i==hi.x && j==hi.y && k==hi.z) face = Face::XHI_YHI_ZHI;
184 else if (j==lo.y && k==lo.z) face = Face::YLO_ZLO;
185 else if (j==lo.y && k==hi.z) face = Face::YLO_ZHI;
186 else if (j==hi.y && k==lo.z) face = Face::YHI_ZLO;
187 else if (j==hi.y && k==hi.z) face = Face::YHI_ZHI;
188 else if (k==lo.z && i==lo.x) face = Face::ZLO_XLO;
189 else if (k==lo.z && i==hi.x) face = Face::ZLO_XHI;
190 else if (k==hi.z && i==lo.x) face = Face::ZHI_XLO;
191 else if (k==hi.z && i==hi.x) face = Face::ZHI_XHI;
192 else if (i==lo.x && j==lo.y) face = Face::XLO_YLO;
193 else if (i==lo.x && j==hi.y) face = Face::XLO_YHI;
194 else if (i==hi.x && j==lo.y) face = Face::XHI_YLO;
195 else if (i==hi.x && j==hi.y) face = Face::XHI_YHI;
197 else if (i==lo.x) face = Face::XLO;
198 else if (i==hi.x) face = Face::XHI;
199 else if (j==lo.y) face = Face::YLO;
200 else if (j==hi.y) face = Face::YHI;
201 else if (k==lo.z) face = Face::ZLO;
202 else if (k==hi.z) face = Face::ZHI;
206 amrex::IndexType type = a_rhs->ixType();
207 if (!(face == Face::INT))
209 if (a_homogeneous &&
m_bc_type[face][dir] == Type::Displacement)
210 rhs(i,j,k,dir) = 0.0;
214 #if AMREX_SPACEDIM==1
216 #elif AMREX_SPACEDIM==2
218 #elif AMREX_SPACEDIM==3
232 const int &i,
const int &j, [[maybe_unused]]
const int &k,
233 const amrex::Box &domain)
override
235 (void)i, (
void)j, (void)k;
237 const amrex::Dim3 lo = amrex::lbound(domain), hi = amrex::ubound(domain);
240 #if AMREX_SPACEDIM == 2
241 if (m[0] == lo.x && m[1] == lo.y)
return m_bc_type[Face::XLO_YLO];
242 if (m[0] == lo.x && m[1] == hi.y)
return m_bc_type[Face::XLO_YHI];
243 if (m[0] == hi.x && m[1] == lo.y)
return m_bc_type[Face::XHI_YLO];
244 if (m[0] == hi.x && m[1] == hi.y)
return m_bc_type[Face::XHI_YHI];
245 if (m[0] == lo.x)
return m_bc_type[Face::XLO];
246 if (m[0] == hi.x)
return m_bc_type[Face::XHI];
247 if (m[1] == lo.y)
return m_bc_type[Face::YLO];
248 if (m[1] == hi.y)
return m_bc_type[Face::YHI];
250 #elif AMREX_SPACEDIM == 3
252 if (m[0] == lo.x && m[1] == lo.y && m[2] == lo.z)
return m_bc_type[Face::XLO_YLO_ZLO];
253 if (m[0] == lo.x && m[1] == lo.y && m[2] == hi.z)
return m_bc_type[Face::XLO_YLO_ZHI];
254 if (m[0] == lo.x && m[1] == hi.y && m[2] == lo.z)
return m_bc_type[Face::XLO_YHI_ZLO];
255 if (m[0] == lo.x && m[1] == hi.y && m[2] == hi.z)
return m_bc_type[Face::XLO_YHI_ZHI];
256 if (m[0] == hi.x && m[1] == lo.y && m[2] == lo.z)
return m_bc_type[Face::XHI_YLO_ZLO];
257 if (m[0] == hi.x && m[1] == lo.y && m[2] == hi.z)
return m_bc_type[Face::XHI_YLO_ZHI];
258 if (m[0] == hi.x && m[1] == hi.y && m[2] == lo.z)
return m_bc_type[Face::XHI_YHI_ZLO];
259 if (m[0] == hi.x && m[1] == hi.y && m[2] == hi.z)
return m_bc_type[Face::XHI_YHI_ZHI];
261 if (m[1] == lo.y && m[2] == lo.z)
return m_bc_type[Face::YLO_ZLO];
262 if (m[1] == lo.y && m[2] == hi.z)
return m_bc_type[Face::YLO_ZHI];
263 if (m[1] == hi.y && m[2] == lo.z)
return m_bc_type[Face::YHI_ZLO];
264 if (m[1] == hi.y && m[2] == hi.z)
return m_bc_type[Face::YHI_ZHI];
265 if (m[2] == lo.z && m[0] == lo.x)
return m_bc_type[Face::ZLO_XLO];
266 if (m[2] == lo.z && m[0] == hi.x)
return m_bc_type[Face::ZLO_XHI];
267 if (m[2] == hi.z && m[0] == lo.x)
return m_bc_type[Face::ZHI_XLO];
268 if (m[2] == hi.z && m[0] == hi.x)
return m_bc_type[Face::ZHI_XHI];
269 if (m[0] == lo.x && m[1] == lo.y)
return m_bc_type[Face::XLO_YLO];
270 if (m[0] == lo.x && m[1] == hi.y)
return m_bc_type[Face::XLO_YHI];
271 if (m[0] == hi.x && m[1] == lo.y)
return m_bc_type[Face::XHI_YLO];
272 if (m[0] == hi.x && m[1] == hi.y)
return m_bc_type[Face::XHI_YHI];
274 if (m[0] == lo.x)
return m_bc_type[Face::XLO];
275 if (m[0] == hi.x)
return m_bc_type[Face::XHI];
276 if (m[1] == lo.y)
return m_bc_type[Face::YLO];
277 if (m[1] == hi.y)
return m_bc_type[Face::YHI];
278 if (m[2] == lo.z)
return m_bc_type[Face::ZLO];
279 if (m[2] == hi.z)
return m_bc_type[Face::ZHI];
291 const int &i,
const int &j,
const int &k,
292 const amrex::Box &domain)
override
294 (void)i; (void)j; (void)k;
297 const amrex::Dim3 lo= amrex::lbound(domain), hi = amrex::ubound(domain);
302 #if AMREX_SPACEDIM == 2
314 #elif AMREX_SPACEDIM == 3
348 return Set::Vector::Zero();
356 for (
int i = 0; i < AMREX_SPACEDIM; i++)
358 if (bc_type[i] == Type::Displacement)
360 else if (bc_type[i] == Type::Traction)
362 else if (bc_type[i] == Type::Neumann)
372 #if AMREX_SPACEDIM==2
373 static const int m_nfaces = 8;
374 #elif AMREX_SPACEDIM==3
375 static const int m_nfaces = 26;
378 std::array<std::array<Type, AMREX_SPACEDIM>, m_nfaces>
m_bc_type;
381 std::array<std::array<amrex::ParserExecutor<4>,AMREX_SPACEDIM>, m_nfaces>
m_bc_func;
393 std::map<std::string, Type> bcmap;
394 bcmap[
"displacement"] = Type::Displacement;
395 bcmap[
"disp"] = Type::Displacement;
396 bcmap[
"neumann"] = Type::Neumann;
397 bcmap[
"traction"] = Type::Traction;
398 bcmap[
"trac"] = Type::Traction;
399 bcmap[
"periodic"] = Type::Periodic;
401 std::vector<std::string> str;
405 #if AMREX_SPACEDIM==3
406 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]]; }
407 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]]; }
408 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]]; }
409 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]]; }
410 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]]; }
411 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]]; }
412 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]]; }
413 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]]; }
416 #if AMREX_SPACEDIM==3
417 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]]; }
418 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]]; }
419 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]]; }
420 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]]; }
421 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]]; }
422 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]]; }
423 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]]; }
424 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]]; }
426 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]]; }
427 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]]; }
428 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]]; }
429 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]]; }
431 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]]; }
432 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]]; }
433 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]]; }
434 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]]; }
435 #if AMREX_SPACEDIM==3
436 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]]; }
437 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]]; }
442 for (
int face = 0; face != Face::INT; face++)
444 std::vector<std::string> val(AMREX_SPACEDIM,
"0.0");
445 val.resize(AMREX_SPACEDIM,
"0.0");
446 std::string querystr = std::string(
"val.") + std::string(facestr[face]);
448 for (
int i = 0 ; i < AMREX_SPACEDIM; i++)
456 #if AMREX_SPACEDIM==2
459 std::vector<std::string> ignore_in_2d = {
461 "zhixlo",
"zloxlo",
"zhixhi",
"zloxhi",
"ylozlo",
"ylozhi",
"yhizlo",
"yhizhi",
462 "xloylozlo",
"xloylozhi",
"xloyhizlo",
"xloyhizhi",
"xhiylozlo",
"xhiylozhi",
"xhiyhizlo",
"xhiyhizhi"};
463 for (
unsigned int n = 0; n < ignore_in_2d.size(); n++)
465 std::string querystr = std::string(
"val.") + ignore_in_2d[n];
467 querystr = std::string(
"type.") + ignore_in_2d[n];