4 #include "Numeric/Stencil.H"
29 BL_PROFILE(
"Integrator::Flame::Flame()");
51 std::string eta_bc_str =
"constant";
53 if (eta_bc_str ==
"constant") value.
ic_eta =
new IC::Constant(value.geom, pp,
"pf.eta.ic.constant");
54 else if (eta_bc_str ==
"expression") value.
ic_eta =
new IC::Expression(value.geom, pp,
"pf.eta.ic.expression");
56 std::string eta_ic_type =
"constant";
57 pp_query_validate(
"eta.ic.type", eta_ic_type, {
"laminate",
"constant",
"expression"});
58 if (eta_ic_type ==
"laminate") value.
ic_eta =
new IC::Laminate(value.geom, pp,
"eta.ic.laminate");
59 else if (eta_ic_type ==
"constant") value.
ic_eta =
new IC::Constant(value.geom, pp,
"eta.ic.constant");
60 else if (eta_ic_type ==
"expression") value.
ic_eta =
new IC::Expression(value.geom, pp,
"eta.ic.expression");
61 else if (eta_ic_type ==
"bmp") value.
ic_eta =
new IC::BMP(value.geom, pp,
"eta.ic.bmp");
62 else if (eta_ic_type ==
"png") value.
ic_eta =
new IC::PNG(value.geom, pp,
"eta.ic.png");
126 std::string laser_ic_type =
"constant";
128 if (laser_ic_type ==
"expression") value.
ic_laser =
new IC::Expression(value.geom, pp,
"laser.ic.expression");
129 else if (laser_ic_type ==
"constant") value.
ic_laser =
new IC::Constant(value.geom, pp,
"laser.ic.constant");
132 std::string temp_ic_type;
133 pp_query_validate(
"temp.ic.type", temp_ic_type,{
"default",
"constant",
"expression",
"bmp",
"png"});
138 else if (temp_ic_type ==
"default") value.
thermal.
ic_temp =
nullptr;
182 std::string phi_ic_type =
"packedspheres";
183 pp_query_validate(
"phi.ic.type", phi_ic_type, {
"psread",
"laminate",
"expression",
"constant",
"bmp",
"png"});
184 if (phi_ic_type ==
"psread") {
190 else if (phi_ic_type ==
"laminate") {
196 else if (phi_ic_type ==
"expression") {
202 else if (phi_ic_type ==
"constant") {
208 else if (phi_ic_type ==
"bmp") {
214 else if (phi_ic_type ==
"png") {
227 if (value.
m_type != Type::Disable)
242 BL_PROFILE(
"Integrator::Flame::Initialize");
253 rhs_mf[lev]->setVal(Set::Vector::Zero());
287 for (
int lev = 0; lev <= finest_level; ++lev)
289 amrex::Box domain = this->geom[lev].Domain();
290 domain.convert(amrex::IntVect::TheNodeVector());
294 phi_mf[lev]->FillBoundary();
296 eta_mf[lev]->FillBoundary();
299 for (MFIter mfi(*
model_mf[lev],
false); mfi.isValid(); ++mfi)
301 amrex::Box bx = mfi.grownnodaltilebox() & domain;
304 amrex::Array4<model_type>
const& model =
model_mf[lev]->array(mfi);
305 amrex::Array4<const Set::Scalar>
const& phi =
phi_mf[lev]->array(mfi);
306 amrex::Array4<const Set::Scalar>
const& eta =
eta_mf[lev]->array(mfi);
307 amrex::Array4<Set::Vector>
const& rhs =
rhs_mf[lev]->array(mfi);
312 amrex::Array4<const Set::Scalar>
const& temp =
temp_mf[lev]->array(mfi);
313 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
319 rhs(i, j, k) =
elastic.traction * grad_eta;
335 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
356 BL_PROFILE(
"Integrator::Flame::TimeStepBegin");
359 for (
int lev = 0; lev <= finest_level; ++lev)
366 BL_PROFILE(
"Integrator::Flame::TimeStepComplete");
378 BL_PROFILE(
"Integrador::Flame::Advance");
392 -5.0 *
pf.w1 + 16.0 *
pf.w12 - 11.0 *
pf.w0,
393 14.0 *
pf.w1 - 32.0 *
pf.w12 + 18.0 *
pf.w0,
394 -8.0 *
pf.w1 + 16.0 *
pf.w12 - 8.0 *
pf.w0);
397 for (amrex::MFIter mfi(*
eta_mf[lev],
true); mfi.isValid(); ++mfi)
399 const amrex::Box& bx = mfi.tilebox();
401 amrex::Array4<Set::Scalar>
const& etanew = (*
eta_mf[lev]).array(mfi);
402 amrex::Array4<const Set::Scalar>
const& eta = (*
eta_old_mf[lev]).array(mfi);
403 amrex::Array4<const Set::Scalar>
const& phi = (*
phi_mf[lev]).array(mfi);
406 amrex::Array4<Set::Scalar>
const& tempnew = (*
temp_mf[lev]).array(mfi);
407 amrex::Array4<const Set::Scalar>
const& temp = (*
temp_old_mf[lev]).array(mfi);
408 amrex::Array4<Set::Scalar>
const& alpha = (*
alpha_mf[lev]).array(mfi);
409 amrex::Array4<Set::Scalar>
const& tempsnew = (*
temps_mf[lev]).array(mfi);
410 amrex::Array4<Set::Scalar>
const& temps = (*
temps_old_mf[lev]).array(mfi);
411 amrex::Array4<Set::Scalar>
const& laser = (*
laser_mf[lev]).array(mfi);
413 amrex::Array4<Set::Scalar>
const& mob = (*
mob_mf[lev]).array(mfi);
414 amrex::Array4<Set::Scalar>
const& mdot = (*
mdot_mf[lev]).array(mfi);
415 amrex::Array4<Set::Scalar>
const& heatflux = (*
heatflux_mf[lev]).array(mfi);
431 if (
pressure.arrhenius.dependency == 1) zeta_1 = zeta_2;
439 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
456 Set::Scalar df_deta = ((
pf.lambda /
pf.eps) * dw(eta(i, j, k)) -
pf.eps *
pf.kappa * eta_lap);
457 etanew(i, j, k) = eta(i, j, k) - mob(i, j, k) *
dt * df_deta;
458 if (etanew(i, j, k) <=
small) etanew(i, j, k) =
small;
460 alpha(i, j, k) = K /
rho / cp;
461 mdot(i, j, k) =
rho * fabs(eta(i, j, k) - etanew(i, j, k)) /
dt;
463 if (isnan(etanew(i, j, k)) || isnan(alpha(i, j, k)) || isnan(mdot(i, j, k))) {
464 Util::Message(
INFO, etanew(i, j, k),
"etanew contains nan (i=", i,
" j= ", j,
")");
466 Util::Message(
INFO, alpha(i, j, k),
"alpha contains nan (i=", i,
" j= ", j,
")");
471 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
482 qflux = k4 * phi_avg;
484 mdota = fabs(mdot(i, j, k));
485 mbase = tanh(4.0 * mdota / (mlocal));
487 heatflux(i, j, k) = (laser(i, j, k) * phi_avg +
thermal.hc * mbase * qflux) / K;
490 qflux = k1 * phi_avg +
491 k2 * (1.0 - phi_avg) +
492 (zeta_1 /
zeta) * exp(k3 * phi_avg * (1.0 - phi_avg));
493 mlocal = (
thermal.mlocal_ap) * phi_avg + (
thermal.mlocal_htpb) * (1.0 - phi_avg) +
thermal.mlocal_comb * phi_avg * (1.0 - phi_avg);
494 mdota = fabs(mdot(i, j, k));
495 mbase = tanh(4.0 * mdota / (mlocal));
498 heatflux(i, j, k) = (
thermal.hc * mbase * qflux + laser(i, j, k)) / K;
501 if (isnan(heatflux(i, j, k))) {
502 Util::Message(
INFO, heatflux(i, j, k),
"heat contains nan (i=", i,
" j= ", j,
")");
507 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
516 dTdt += grad_eta.dot(grad_temp * alpha(i, j, k));
517 dTdt += grad_alpha.dot(eta(i, j, k) * grad_temp);
518 dTdt += eta(i, j, k) * alpha(i, j, k) * lap_temp;
519 dTdt += alpha(i, j, k) * heatflux(i, j, k) * grad_eta_mag;
521 Tsolid = dTdt + temps(i, j, k) * (etanew(i, j, k) - eta(i, j, k)) /
dt;
522 tempsnew(i, j, k) = temps(i, j, k) +
dt * Tsolid;
523 tempnew(i, j, k) = etanew(i, j, k) * tempsnew(i, j, k) + (1.0 - etanew(i, j, k)) *
thermal.T_fluid;
524 if (isnan(tempsnew(i, j, k)) || isnan(temps(i, j, k))) {
525 Util::Message(
INFO, tempsnew(i, j, k),
"tempsnew contains nan (i=", i,
" j= ", j,
")");
526 Util::Message(
INFO, temps(i, j, k),
"temps contains nan (i=", i,
" j= ", j,
")");
532 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
539 else L =
thermal.m_ap * exp(-
thermal.E_ap / tempnew(i, j, k)) * phi_avg;
540 L +=
thermal.m_htpb * exp(-
thermal.E_htpb / tempnew(i, j, k)) * (1.0 - phi_avg);
542 if (tempnew(i, j, k) <=
thermal.bound) mob(i, j, k) = 0;
543 else mob(i, j, k) = L;
545 if (isnan(mob(i, j, k))) {
558 -5.0 *
pf.w1 + 16.0 *
pf.w12 - 11.0 *
pf.w0,
559 14.0 *
pf.w1 - 32.0 *
pf.w12 + 18.0 *
pf.w0,
560 -8.0 *
pf.w1 + 16.0 *
pf.w12 - 8.0 *
pf.w0
564 for (amrex::MFIter mfi(*
eta_mf[lev],
true); mfi.isValid(); ++mfi)
566 const amrex::Box& bx = mfi.tilebox();
568 amrex::Array4<Set::Scalar>
const& etanew = (*
eta_mf[lev]).array(mfi);
569 amrex::Array4<Set::Scalar>
const& eta = (*
eta_old_mf[lev]).array(mfi);
570 amrex::Array4<Set::Scalar>
const& phi = (*
phi_mf[lev]).array(mfi);
581 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
587 Set::Scalar angle = acos(grad_eta[0] / grad_eta.lpNorm<2>()) * 180 / 3.1415;
588 if (angle > 90) angle = angle - 90.0;
589 if (angle > 180) angle = angle - 180.0;
590 if (angle > 270) angle = angle - 270.0;
595 fs_actual = fmod_ap * phi(i, j, k)
596 + fmod_htpb * (1.0 - phi(i, j, k))
597 + 4.0 * fmod_comb * phi(i, j, k) * (1.0 - phi(i, j, k));
598 L = fs_actual /
pf.gamma / (
pf.w1 -
pf.w0);
601 Set::Scalar df_deta = ((
pf.lambda /
pf.eps) * dw(eta(i, j, k)) -
pf.eps *
pf.kappa * eta_lap);
602 etanew(i, j, k) = eta(i, j, k) - L *
dt * df_deta;
604 if (etanew(i, j, k) > eta(i, j, k)) etanew(i, j, k) = eta(i, j, k);
614 BL_PROFILE(
"Integrator::Flame::TagCellsForRefinement");
618 Set::Scalar dr = sqrt(AMREX_D_TERM(DX[0] * DX[0], +DX[1] * DX[1], +DX[2] * DX[2]));
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& eta = (*
eta_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;
637 for (amrex::MFIter mfi(*
eta_mf[lev],
true); mfi.isValid(); ++mfi)
639 const amrex::Box& bx = mfi.tilebox();
640 amrex::Array4<char>
const& tags = a_tags.array(mfi);
641 amrex::Array4<const Set::Scalar>
const& phi = (*
phi_mf[lev]).array(mfi);
643 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
647 tags(i, j, k) = amrex::TagBox::SET;
655 for (amrex::MFIter mfi(*
temp_mf[lev],
true); mfi.isValid(); ++mfi)
657 const amrex::Box& bx = mfi.tilebox();
658 amrex::Array4<char>
const& tags = a_tags.array(mfi);
659 amrex::Array4<const Set::Scalar>
const& temp = (*
temp_mf[lev]).array(mfi);
660 amrex::Array4<const Set::Scalar>
const& eta = (*
eta_mf[lev]).array(mfi);
661 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
665 tags(i, j, k) = amrex::TagBox::SET;
675 BL_PROFILE(
"Integrator::Flame::Regrid");
683 const amrex::MFIter& mfi,
const amrex::Box& box)
685 BL_PROFILE(
"Flame::Integrate");
687 Set::Scalar dv = AMREX_D_TERM(DX[0], *DX[1], *DX[2]);
688 amrex::Array4<amrex::Real>
const& eta = (*
eta_mf[amrlev]).array(mfi);
689 amrex::Array4<amrex::Real>
const& mdot = (*
mdot_mf[amrlev]).array(mfi);
691 amrex::ParallelFor(
box, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
693 volume += eta(i, j, k, 0) * dv;
707 amrex::ParallelFor(
box, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
709 volume += eta(i, j, k, 0) * dv;