15#ifndef INTEGRATOR_HEATCONDUCTION_H
16#define INTEGRATOR_HEATCONDUCTION_H
19#include "AMReX_Array4.H"
20#include "AMReX_GpuComplex.H"
21#include "AMReX_MFIter.H"
23#include <AMReX_ParallelDescriptor.H>
24#include <AMReX_ParmParse.H>
25#include <AMReX_TimeIntegrator.H>
41#include "Numeric/Stencil.H"
48 static constexpr const char*
name =
"heatconduction";
103 value.RegisterNewFab( value.temp_mf, value.bc, value.number_of_components,
104 value.number_of_ghost_cells,
"Temp",
true);
105 if (value.method ==
"realspace")
107 value.RegisterNewFab( value.temp_old_mf, value.bc, value.number_of_components,
108 value.number_of_ghost_cells,
"Temp_old",
false);
117 ic->Initialize(lev, temp_mf);
118 if (method ==
"realspace") ic->Initialize(lev, temp_old_mf);
125 if (method ==
"spectral")
127 AdvanceSpectral(lev,time,dt);
133 std::swap(*temp_mf[lev], *temp_old_mf[lev]);
136 amrex::TimeIntegrator timeintegrator(*temp_old_mf[lev], time);
141 timeintegrator.set_rhs([&](amrex::MultiFab & rhs_mf, amrex::MultiFab & temp_mf,
const Set::Scalar )
147 for (amrex::MFIter mfi(temp_mf, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
150 const amrex::Box &bx = mfi.tilebox();
157 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
168 timeintegrator.set_post_stage_action([&](amrex::MultiFab & stage_mf,
Set::Scalar time)
170 bc->FillBoundary(stage_mf,0,1,time,0);
171 stage_mf.FillBoundary(
true);
175 timeintegrator.advance(*temp_old_mf[lev], *temp_mf[lev], time, dt);
185 amrex::Box
const & domain = this->geom[lev].Domain();
187 amrex::FFT::R2C my_fft(this->geom[lev].Domain());
188 auto const& [cba, cdm] = my_fft.getSpectralDataLayout();
189 amrex::FabArray<amrex::BaseFab<amrex::GpuComplex<Set::Scalar> > > Temp_hat(cba, cdm, 1, 0);
190 my_fft.forward(*temp_mf[lev], Temp_hat);
200 Set::Scalar scaling = 1.0 / geom[lev].Domain().d_numPts();
202 for (amrex::MFIter mfi(Temp_hat, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
204 const amrex::Box &bx = mfi.tilebox();
205 amrex::Array4<amrex::GpuComplex<Set::Scalar>>
const & T_hat = Temp_hat.array(mfi);
206 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int m,
int n,
int p) {
210 Set::Scalar k2 = (n < domain.length(1)/2 ? n * pi_Ly : (n - domain.length(1)) * pi_Ly);,
211 Set::Scalar k3 = (p < domain.length(2)/2 ? p * pi_Lz : (p - domain.length(2)) * pi_Lz););
213 Set::Scalar lap = AMREX_D_TERM(k1 * k1, + k2 * k2, + k3*k3);
216 T_hat(m,n,p) *= factor*scaling;
220 my_fft.backward(Temp_hat, *temp_mf[lev]);
234 if (method==
"spectral")
return;
239 Set::Scalar dr = sqrt(AMREX_D_TERM(DX[0] * DX[0], +DX[1] * DX[1], +DX[2] * DX[2]));
242 for (amrex::MFIter mfi(*temp_mf[lev], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
245 const amrex::Box& bx = mfi.tilebox();
246 amrex::Array4<char>
const& tags = a_tags.array(mfi);
247 amrex::Array4<Set::Scalar>
const& temp = (*temp_mf[lev]).array(mfi);
250 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
257 if (grad.lpNorm<2>() * dr > refinement_threshold)
258 tags(i, j, k) = amrex::TagBox::SET;
275 const int number_of_components = 1;
276 const int number_of_ghost_cells = 2;
Pure abstract IC object from which all other IC objects inherit.
int query_required(std::string name, T &value)
void select_default(std::string name, PTRTYPE *&ic_eta, Args &&... args)
int query_default(std::string name, T &value, T defaultvalue)
int query_validate(std::string name, int &value, std::vector< int > possibleintvals)
const int number_of_ghost_cells
Set::Field< Set::Scalar > temp_mf
static void Parse(HeatConduction &value, IO::ParmParse &pp)
BC::BC< Set::Scalar > * bc
HeatConduction(int a_nghost=2)
void Advance(int lev, Set::Scalar time, Set::Scalar dt)
IC::IC< Set::Scalar > * ic
HeatConduction(IO::ParmParse &pp)
void AdvanceSpectral(int, Set::Scalar, Set::Scalar)
virtual ~HeatConduction()
Set::Scalar refinement_threshold
Set::Field< Set::Scalar > temp_old_mf
void TagCellsForRefinement(int lev, amrex::TagBoxArray &a_tags, Set::Scalar, int)
static constexpr const char * name
Collection of numerical integrator objects.
AMREX_FORCE_INLINE Set::Scalar Laplacian(const amrex::Array4< const Set::Scalar > &f, const int &i, const int &j, const int &k, const int &m, const Set::Scalar dx[AMREX_SPACEDIM], std::array< StencilType, AMREX_SPACEDIM > &stencil=DefaultType)
AMREX_FORCE_INLINE Set::Vector Gradient(const amrex::Array4< const Set::Scalar > &f, const int &i, const int &j, const int &k, const int &m, const Set::Scalar dx[AMREX_SPACEDIM], std::array< StencilType, AMREX_SPACEDIM > stencil=DefaultType)
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
void Abort(const char *msg)
AMREX_FORCE_INLINE void Assert(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
static Unit ThermalDiffusivity()
static Unit Temperature()