1 #ifndef INTEGRATOR_BASE_MECHANICS_H
2 #define INTEGRATOR_BASE_MECHANICS_H
10 #include "Numeric/Stencil.H"
14 #include "Operator/Operator.H"
36 BL_PROFILE(
"Integrator::Base::Mechanics::Parse");
45 if (type_str ==
"static") value.
m_type = Type::Static;
46 else if (type_str ==
"dynamic") value.
m_type = Type::Dynamic;
47 else if (type_str ==
"disable") value.
m_type = Type::Disable;
50 if (value.
m_type == Type::Disable)
return;
68 if (value.
m_type == Type::Static)
73 if (value.
m_type == Type::Dynamic)
79 pp_forbid(
"viscous.mu",
"replaced with viscous.mu_dashpot");
81 pp_forbid(
"viscous.mu2",
"replaced with viscous.mu_newton");
84 std::string velocity_ic_str;
99 if (rhstype ==
"trig") value.
ic_rhs =
new IC::Trig(value.geom, pp,
"rhs.trig");
100 else if (rhstype ==
"constant") value.
ic_rhs =
new IC::Constant(value.geom, pp,
"rhs.constant");
136 BL_PROFILE(
"Integrator::Base::Mechanics::Initialize");
139 disp_mf[lev]->setVal(Set::Vector::Zero());
142 if (
m_type == Type::Dynamic)
149 else rhs_mf[lev]->setVal(Set::Vector::Zero());
156 BL_PROFILE(
"Integrator::Base::Mechanics::TimeStepBegin");
159 for (
int lev = 0; lev <= finest_level; ++lev)
162 rhs_mf[lev]->setVal(Set::Vector::Zero());
172 if (a_time <
tstart)
return;
195 amrex::Box domain = geom[lev].Domain();
196 domain.convert(amrex::IntVect::TheNodeVector());
198 const amrex::Real* DX = geom[lev].CellSize();
199 for (MFIter mfi(*
disp_mf[lev],
false); mfi.isValid(); ++mfi)
201 amrex::Box bx = mfi.nodaltilebox();
204 amrex::Array4<MODEL>
const& model =
model_mf[lev]->array(mfi);
205 amrex::Array4<Set::Matrix>
const& stress =
stress_mf[lev]->array(mfi);
206 amrex::Array4<Set::Matrix>
const& strain =
strain_mf[lev]->array(mfi);
207 amrex::Array4<const Set::Vector>
const& disp =
disp_mf[lev]->array(mfi);
210 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
216 stress(i, j, k) = model(i, j, k).DW(
F);
222 stress(i, j, k) = model(i, j, k).DW(
gradu);
223 strain(i, j, k) = 0.5 * (
gradu +
gradu.transpose());
234 BL_PROFILE(
"Integrator::Base::Mechanics::Advance");
236 const amrex::Real* DX = geom[lev].CellSize();
238 amrex::Box domain = geom[lev].Domain();
239 domain.convert(amrex::IntVect::TheNodeVector());
240 const amrex::Dim3 lo = amrex::lbound(domain), hi = amrex::ubound(domain);
242 if (
m_type == Type::Dynamic)
249 for (amrex::MFIter mfi(*
disp_mf[lev], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
262 amrex::Box bx = mfi.grownnodaltilebox() & domain;
263 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
267 sig(i, j, k) = model(i, j, k).DW(eps(i, j, k));
271 bx = mfi.nodaltilebox() & domain;
272 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
275 bool AMREX_D_DECL(xmin = (i == lo.x), ymin = (j == lo.y), zmin = (k == lo.z));
276 bool AMREX_D_DECL(xmax = (i == hi.x), ymax = (j == hi.y), zmax = (k == hi.z));
278 if (AMREX_D_TERM(xmax || xmin, || ymax || ymin, || zmax || zmin))
284 for (
int d = 0; d < AMREX_SPACEDIM; d++)
286 if (bctype[d] == BC::Operator::Elastic::Elastic::Type::Displacement)
288 unew(i,j,k)(d) = b(i,j,k)(d);
290 else if (bctype[d] == BC::Operator::Elastic::Elastic::Type::Traction)
300 Set::Matrix DW_F0 = model(i,j,k).DW(Set::Matrix::Zero());
301 MATRIX4 ddw = model(i,j,k).DDW(eps(i,j,k));
304 for (
int p = 0; p < AMREX_SPACEDIM; p++)
305 for (
int q = 0; q < AMREX_SPACEDIM; q++)
307 for (
int r = 0; r < AMREX_SPACEDIM; r++)
308 for (
int s = 0; s < AMREX_SPACEDIM; s++)
310 A(p,r) += ddw(p,q,r,s) * phi(s) * N(q);
312 rhs(p) -= ddw(p,q,r,s) * eps(i,j,k)(r,s) * N(q);
315 rhs(p) -= DW_F0(p,q)*N(q);
319 unew(i,j,k)(d) = u(i,j,k)(d) + delta_u(d);
320 vnew(i,j,k)(d) = (unew(i,j,k)(d) - u(i,j,k)(d))/
dt;
349 vnew(i, j, k) = v(i, j, k) +
dt * udotdot;
350 unew(i, j, k) = u(i, j, k) +
dt * v(i, j, k);
356 for (amrex::MFIter mfi(*
disp_mf[lev],
false); mfi.isValid(); ++mfi)
358 amrex::Box bx = mfi.grownnodaltilebox() & domain;
359 amrex::Array4<Set::Matrix>
const& eps = (*
strain_mf[lev]).array(mfi);
360 amrex::Array4<Set::Matrix>
const& sig = (*
stress_mf[lev]).array(mfi);
361 amrex::Array4<MODEL>
const& model = (*
model_mf[lev]).array(mfi);
362 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
364 model(i, j, k).Advance(
dt, eps(i, j, k), sig(i, j, k),time);
372 const amrex::MFIter& mfi,
const amrex::Box& a_box)
override
374 BL_PROFILE(
"Integrator::Base::Mechanics::Integrate");
375 if (
m_type == Type::Disable)
return;
377 if (amrex::ParallelDescriptor::NProcs() > 1)
379 Util::Warning(
INFO,
"There is a known bug when calculating trac/disp in Base::Mechanics in parallel.");
380 Util::Warning(
INFO,
"The thermo.dat values likely will not be correct; use the boxlib output instead.");
383 const amrex::Real* DX = geom[amrlev].CellSize();
384 amrex::Box domain = geom[amrlev].Domain();
385 domain.convert(amrex::IntVect::TheNodeVector());
387 amrex::Box
box = a_box;
388 box.convert(amrex::IntVect::TheNodeVector());
392 #if AMREX_SPACEDIM == 2
395 #elif AMREX_SPACEDIM == 3
399 const Dim3 hi = amrex::ubound(domain);
400 const Dim3 boxhi = amrex::ubound(
box);
402 amrex::Array4<const Set::Matrix>
const& stress = (*
stress_mf[amrlev]).array(mfi);
403 amrex::Array4<const Set::Vector>
const& disp = (*
disp_mf[amrlev]).array(mfi);
404 amrex::ParallelFor(
box, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
406 #if AMREX_SPACEDIM == 2
407 if (i == hi.x && j < boxhi.y)
409 trac_hi[0] += (0.5 * (stress(i, j, k) + stress(i, j + 1, k)) * da0);
410 disp_hi[0] = disp(i, j, k);
412 if (j == hi.y && i < boxhi.x)
414 trac_hi[1] += (0.5 * (stress(i, j, k) + stress(i + 1, j, k)) * da1);
415 disp_hi[1] = disp(i, j, k);
417 #elif AMREX_SPACEDIM == 3
418 if (i == hi.x && (j < boxhi.y && k < boxhi.z))
420 trac_hi[0] += (0.25 * (stress(i, j, k) + stress(i, j + 1, k)
421 + stress(i, j, k + 1) + stress(i, j + 1, k + 1)) * da);
422 disp_hi[0] = disp(i, j, k);
431 BL_PROFILE(
"Integrator::Base::Mechanics::TagCellsForRefinement");
432 if (
m_type == Type::Disable)
return;
436 for (amrex::MFIter mfi(*
strain_mf[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi)
438 amrex::Box bx = mfi.tilebox();
439 bx.convert(amrex::IntVect::TheCellVector());
440 amrex::Array4<char>
const& tags = a_tags.array(mfi);
441 amrex::Array4<Set::Matrix>
const& eps =
strain_mf[lev]->array(mfi);
442 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
446 tags(i, j, k) = amrex::TagBox::SET;