1#include <AMReX_MLPoisson.H>
11#include "Numeric/Stencil.H"
42 value.RegisterNewFab(value.etanew_mf, value.bc, 1, 1,
"eta",
true);
43 value.RegisterNewFab(value.intermediate, value.bc, 1, 1,
"int",
true);
45 if (value.method ==
"realspace")
46 value.RegisterNewFab(value.etaold_mf, value.bc, 1, 1,
"eta_old",
false);
52 if (method ==
"realspace")
53 AdvanceReal(lev, time, dt);
54 else if (method ==
"spectral")
55 AdvanceSpectral(lev, time, dt);
64 std::swap(etaold_mf[lev], etanew_mf[lev]);
66 for ( amrex::MFIter mfi(*etanew_mf[lev],
true); mfi.isValid(); ++mfi )
68 const amrex::Box& bx = mfi.tilebox();
69 amrex::Array4<const amrex::Real>
const& eta = etaold_mf[lev]->array(mfi);
70 amrex::Array4<amrex::Real>
const& inter = intermediate[lev]->array(mfi);
71 amrex::Array4<amrex::Real>
const& etanew = etanew_mf[lev]->array(mfi);
73 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
79 eta(i,j,k)*eta(i,j,k)*eta(i,j,k)
84 etanew(i,j,k) = eta(i,j,k) - dt*inter(i,j,k);
87 amrex::ParallelFor (bx,[=] AMREX_GPU_DEVICE(
int i,
int j,
int k){
90 etanew(i,j,k) = eta(i,j,k) + dt*lap_inter;
102 amrex::FFT::R2C my_fft(this->geom[lev].Domain());
103 auto const &[cba, cdm] = my_fft.getSpectralDataLayout();
105 amrex::Box
const & domain = this->geom[lev].Domain();
111 Set::Scalar scaling = 1.0 / geom[lev].Domain().d_numPts();
117 for ( amrex::MFIter mfi(*etanew_mf[lev],
true); mfi.isValid(); ++mfi )
119 const amrex::Box& bx = mfi.tilebox();
120 amrex::Array4<const amrex::Real>
const& eta = etanew_mf[lev]->array(mfi);
121 amrex::Array4<amrex::Real>
const& inter = intermediate[lev]->array(mfi);
122 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
124 inter(i,j,k) = eta(i,j,k)*eta(i,j,k)*eta(i,j,k) - eta(i,j,k);
128 intermediate[lev]->FillBoundary();
133 amrex::FabArray<amrex::BaseFab<amrex::GpuComplex<Set::Scalar> > > eta_hat_mf(cba, cdm, 1, 0);
134 my_fft.forward(*etanew_mf[lev], eta_hat_mf);
139 amrex::FabArray<amrex::BaseFab<amrex::GpuComplex<Set::Scalar> > > chempot_hat_mf(cba, cdm, 1, 0);
140 my_fft.forward(*intermediate[lev], chempot_hat_mf);
146 for (amrex::MFIter mfi(eta_hat_mf,
false); mfi.isValid(); ++mfi)
148 const amrex::Box &bx = mfi.tilebox();
152 amrex::Array4<amrex::GpuComplex<Set::Scalar>>
const & eta_hat = eta_hat_mf.array(mfi);
153 amrex::Array4<amrex::GpuComplex<Set::Scalar>>
const & chempot_hat = chempot_hat_mf.array(mfi);
155 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int m,
int n,
int p) {
161 Set::Scalar k2 = (n < domain.length(1)/2 ? n * pi_Ly : (n - domain.length(1)) * pi_Ly);,
162 Set::Scalar k3 = (p < domain.length(2)/2 ? p * pi_Lz : (p - domain.length(2)) * pi_Lz););
165 Set::Scalar lap = AMREX_D_TERM(k1 * k1, + k2 * k2, + k3*k3);
170 (eta_hat(m, n, p) - L * lap * chempot_hat(m, n, p) * dt) /
171 (1.0 + L * gamma * bilap * dt);
174 eta_hat(m,n,p) *= scaling;
181 my_fft.backward(eta_hat_mf, *etanew_mf[lev]);
194CahnHilliard::Initialize (
int lev)
196 intermediate[lev]->setVal(0.0);
197 ic->Initialize(lev,etanew_mf);
198 if (method ==
"realspace")
199 ic->Initialize(lev,etaold_mf);
204CahnHilliard::TagCellsForRefinement (
int lev, amrex::TagBoxArray& a_tags,
Set::Scalar ,
int )
206 if (method ==
"spectral")
return;
209 Set::Scalar dr = sqrt(AMREX_D_TERM(DX[0] * DX[0], +DX[1] * DX[1], +DX[2] * DX[2]));
211 for (amrex::MFIter mfi(*etanew_mf[lev], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
213 const amrex::Box& bx = mfi.tilebox();
214 amrex::Array4<char>
const& tags = a_tags.array(mfi);
217 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
220 if (grad.lpNorm<2>() * dr > refinement_threshold)
221 tags(i, j, k) = amrex::TagBox::SET;
Set each point to a random value.
void select_default(std::string name, PTRTYPE *&ic_eta, Args &&... args)
int query_default(std::string name, T &value, T defaultvalue, std::string="", std::string="", int=-1)
int query_validate(std::string name, int &value, std::vector< int > possibleintvals, std::string file="", std::string func="", int line=-1)
CahnHilliard()
Basic constructor (don't use)
IC::IC< Set::Scalar > * ic
eta's bc object
Set::Scalar gamma
eta's ic object
Set::Scalar refinement_threshold
BC::BC< Set::Scalar > * bc
Intermediate field used for CH kinetics.
~CahnHilliard()
Destroy pointers defined in Parse.
static void Parse(CahnHilliard &value, IO::ParmParse &pp)
Scan input values and initialize fields.
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)
static const Set::Scalar Pi
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
void Abort(const char *msg)
void Message(std::string file, std::string func, int line, Args const &... args)