4 #include "Numeric/Stencil.H"
29 BL_PROFILE(
"Integrator::Flame::Flame()");
166 std::string phi_ic_type =
"packedspheres";
167 pp_query_validate(
"phi.ic.type", phi_ic_type, {
"psread",
"laminate",
"expression",
"constant",
"bmp",
"png"});
168 if (phi_ic_type ==
"psread") {
174 else if (phi_ic_type ==
"laminate") {
180 else if (phi_ic_type ==
"expression") {
186 else if (phi_ic_type ==
"constant") {
192 else if (phi_ic_type ==
"bmp") {
198 else if (phi_ic_type ==
"png") {
211 if (value.
m_type != Type::Disable)
226 BL_PROFILE(
"Integrator::Flame::Initialize");
237 rhs_mf[lev]->setVal(Set::Vector::Zero());
271 for (
int lev = 0; lev <= finest_level; ++lev)
273 amrex::Box domain = this->geom[lev].Domain();
274 domain.convert(amrex::IntVect::TheNodeVector());
278 phi_mf[lev]->FillBoundary();
280 eta_mf[lev]->FillBoundary();
283 for (MFIter mfi(*
model_mf[lev],
false); mfi.isValid(); ++mfi)
285 amrex::Box bx = mfi.grownnodaltilebox() & domain;
288 amrex::Array4<model_type>
const& model =
model_mf[lev]->array(mfi);
289 amrex::Array4<const Set::Scalar>
const& phi =
phi_mf[lev]->array(mfi);
290 amrex::Array4<const Set::Scalar>
const& eta =
eta_mf[lev]->array(mfi);
291 amrex::Array4<Set::Vector>
const& rhs =
rhs_mf[lev]->array(mfi);
296 amrex::Array4<const Set::Scalar>
const& temp =
temp_mf[lev]->array(mfi);
297 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
303 rhs(i, j, k) =
elastic.traction * grad_eta;
319 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
340 BL_PROFILE(
"Integrator::Flame::TimeStepBegin");
343 for (
int lev = 0; lev <= finest_level; ++lev)
350 BL_PROFILE(
"Integrator::Flame::TimeStepComplete");
362 BL_PROFILE(
"Integrador::Flame::Advance");
376 -5.0 *
pf.w1 + 16.0 *
pf.w12 - 11.0 *
pf.w0,
377 14.0 *
pf.w1 - 32.0 *
pf.w12 + 18.0 *
pf.w0,
378 -8.0 *
pf.w1 + 16.0 *
pf.w12 - 8.0 *
pf.w0);
381 for (amrex::MFIter mfi(*
eta_mf[lev],
true); mfi.isValid(); ++mfi)
383 const amrex::Box& bx = mfi.tilebox();
385 amrex::Array4<Set::Scalar>
const& etanew = (*
eta_mf[lev]).array(mfi);
386 amrex::Array4<const Set::Scalar>
const& eta = (*
eta_old_mf[lev]).array(mfi);
387 amrex::Array4<const Set::Scalar>
const& phi = (*
phi_mf[lev]).array(mfi);
390 amrex::Array4<Set::Scalar>
const& tempnew = (*
temp_mf[lev]).array(mfi);
391 amrex::Array4<const Set::Scalar>
const& temp = (*
temp_old_mf[lev]).array(mfi);
392 amrex::Array4<Set::Scalar>
const& alpha = (*
alpha_mf[lev]).array(mfi);
393 amrex::Array4<Set::Scalar>
const& tempsnew = (*
temps_mf[lev]).array(mfi);
394 amrex::Array4<Set::Scalar>
const& temps = (*
temps_old_mf[lev]).array(mfi);
395 amrex::Array4<Set::Scalar>
const& laser = (*
laser_mf[lev]).array(mfi);
397 amrex::Array4<Set::Scalar>
const& mob = (*
mob_mf[lev]).array(mfi);
398 amrex::Array4<Set::Scalar>
const& mdot = (*
mdot_mf[lev]).array(mfi);
399 amrex::Array4<Set::Scalar>
const& heatflux = (*
heatflux_mf[lev]).array(mfi);
415 if (
pressure.arrhenius.dependency == 1) zeta_1 = zeta_2;
423 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
440 Set::Scalar df_deta = ((
pf.lambda /
pf.eps) * dw(eta(i, j, k)) -
pf.eps *
pf.kappa * eta_lap);
441 etanew(i, j, k) = eta(i, j, k) - mob(i, j, k) *
dt * df_deta;
442 if (etanew(i, j, k) <=
small) etanew(i, j, k) =
small;
444 alpha(i, j, k) = K /
rho / cp;
445 mdot(i, j, k) =
rho * fabs(eta(i, j, k) - etanew(i, j, k)) /
dt;
447 if (isnan(etanew(i, j, k)) || isnan(alpha(i, j, k)) || isnan(mdot(i, j, k))) {
448 Util::Message(
INFO, etanew(i, j, k),
"etanew contains nan (i=", i,
" j= ", j,
")");
450 Util::Message(
INFO, alpha(i, j, k),
"alpha contains nan (i=", i,
" j= ", j,
")");
455 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
466 qflux = k4 * phi_avg;
468 mdota = fabs(mdot(i, j, k));
469 mbase = tanh(4.0 * mdota / (mlocal));
471 heatflux(i, j, k) = (laser(i, j, k) * phi_avg +
thermal.hc * mbase * qflux) / K;
474 qflux = k1 * phi_avg +
475 k2 * (1.0 - phi_avg) +
476 (zeta_1 /
zeta) * exp(k3 * phi_avg * (1.0 - phi_avg));
477 mlocal = (
thermal.mlocal_ap) * phi_avg + (
thermal.mlocal_htpb) * (1.0 - phi_avg) +
thermal.mlocal_comb * phi_avg * (1.0 - phi_avg);
478 mdota = fabs(mdot(i, j, k));
479 mbase = tanh(4.0 * mdota / (mlocal));
482 heatflux(i, j, k) = (
thermal.hc * mbase * qflux + laser(i, j, k)) / K;
485 if (isnan(heatflux(i, j, k))) {
486 Util::Message(
INFO, heatflux(i, j, k),
"heat contains nan (i=", i,
" j= ", j,
")");
491 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
500 dTdt += grad_eta.dot(grad_temp * alpha(i, j, k));
501 dTdt += grad_alpha.dot(eta(i, j, k) * grad_temp);
502 dTdt += eta(i, j, k) * alpha(i, j, k) * lap_temp;
503 dTdt += alpha(i, j, k) * heatflux(i, j, k) * grad_eta_mag;
505 Tsolid = dTdt + temps(i, j, k) * (etanew(i, j, k) - eta(i, j, k)) /
dt;
506 tempsnew(i, j, k) = temps(i, j, k) +
dt * Tsolid;
507 tempnew(i, j, k) = etanew(i, j, k) * tempsnew(i, j, k) + (1.0 - etanew(i, j, k)) *
thermal.T_fluid;
508 if (isnan(tempsnew(i, j, k)) || isnan(temps(i, j, k))) {
509 Util::Message(
INFO, tempsnew(i, j, k),
"tempsnew contains nan (i=", i,
" j= ", j,
")");
510 Util::Message(
INFO, temps(i, j, k),
"temps contains nan (i=", i,
" j= ", j,
")");
516 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
523 else L =
thermal.m_ap * exp(-
thermal.E_ap / tempnew(i, j, k)) * phi_avg;
524 L +=
thermal.m_htpb * exp(-
thermal.E_htpb / tempnew(i, j, k)) * (1.0 - phi_avg);
526 if (tempnew(i, j, k) <=
thermal.bound) mob(i, j, k) = 0;
527 else mob(i, j, k) = L;
529 if (isnan(mob(i, j, k))) {
542 -5.0 *
pf.w1 + 16.0 *
pf.w12 - 11.0 *
pf.w0,
543 14.0 *
pf.w1 - 32.0 *
pf.w12 + 18.0 *
pf.w0,
544 -8.0 *
pf.w1 + 16.0 *
pf.w12 - 8.0 *
pf.w0
548 for (amrex::MFIter mfi(*
eta_mf[lev],
true); mfi.isValid(); ++mfi)
550 const amrex::Box& bx = mfi.tilebox();
552 amrex::Array4<Set::Scalar>
const& etanew = (*
eta_mf[lev]).array(mfi);
553 amrex::Array4<Set::Scalar>
const& eta = (*
eta_old_mf[lev]).array(mfi);
554 amrex::Array4<Set::Scalar>
const& phi = (*
phi_mf[lev]).array(mfi);
565 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
571 Set::Scalar angle = acos(grad_eta[0] / grad_eta.lpNorm<2>()) * 180 / 3.1415;
572 if (angle > 90) angle = angle - 90.0;
573 if (angle > 180) angle = angle - 180.0;
574 if (angle > 270) angle = angle - 270.0;
579 fs_actual = fmod_ap * phi(i, j, k)
580 + fmod_htpb * (1.0 - phi(i, j, k))
581 + 4.0 * fmod_comb * phi(i, j, k) * (1.0 - phi(i, j, k));
582 L = fs_actual /
pf.gamma / (
pf.w1 -
pf.w0);
585 Set::Scalar df_deta = ((
pf.lambda /
pf.eps) * dw(eta(i, j, k)) -
pf.eps *
pf.kappa * eta_lap);
586 etanew(i, j, k) = eta(i, j, k) - L *
dt * df_deta;
588 if (etanew(i, j, k) > eta(i, j, k)) etanew(i, j, k) = eta(i, j, k);
598 BL_PROFILE(
"Integrator::Flame::TagCellsForRefinement");
602 Set::Scalar dr = sqrt(AMREX_D_TERM(DX[0] * DX[0], +DX[1] * DX[1], +DX[2] * DX[2]));
605 for (amrex::MFIter mfi(*
eta_mf[lev],
true); mfi.isValid(); ++mfi)
607 const amrex::Box& bx = mfi.tilebox();
608 amrex::Array4<char>
const& tags = a_tags.array(mfi);
609 amrex::Array4<const Set::Scalar>
const& eta = (*
eta_mf[lev]).array(mfi);
611 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
615 tags(i, j, k) = amrex::TagBox::SET;
621 for (amrex::MFIter mfi(*
eta_mf[lev],
true); mfi.isValid(); ++mfi)
623 const amrex::Box& bx = mfi.tilebox();
624 amrex::Array4<char>
const& tags = a_tags.array(mfi);
625 amrex::Array4<const Set::Scalar>
const& phi = (*
phi_mf[lev]).array(mfi);
627 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
631 tags(i, j, k) = amrex::TagBox::SET;
639 for (amrex::MFIter mfi(*
temp_mf[lev],
true); mfi.isValid(); ++mfi)
641 const amrex::Box& bx = mfi.tilebox();
642 amrex::Array4<char>
const& tags = a_tags.array(mfi);
643 amrex::Array4<const Set::Scalar>
const& temp = (*
temp_mf[lev]).array(mfi);
644 amrex::Array4<const Set::Scalar>
const& eta = (*
eta_mf[lev]).array(mfi);
645 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
649 tags(i, j, k) = amrex::TagBox::SET;
659 BL_PROFILE(
"Integrator::Flame::Regrid");
667 const amrex::MFIter& mfi,
const amrex::Box& box)
669 BL_PROFILE(
"Flame::Integrate");
671 Set::Scalar dv = AMREX_D_TERM(DX[0], *DX[1], *DX[2]);
672 amrex::Array4<amrex::Real>
const& eta = (*
eta_mf[amrlev]).array(mfi);
673 amrex::Array4<amrex::Real>
const& mdot = (*
mdot_mf[amrlev]).array(mfi);
675 amrex::ParallelFor(
box, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
677 volume += eta(i, j, k, 0) * dv;
691 amrex::ParallelFor(
box, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
693 volume += eta(i, j, k, 0) * dv;