Line data Source code
1 : #include <AMReX_MLPoisson.H>
2 :
3 : #ifdef ALAMO_FFT
4 : #include <AMReX_FFT.H>
5 : #endif
6 :
7 :
8 : #include "PFC.H"
9 : #include "BC/Constant.H"
10 : #include "IO/ParmParse.H"
11 : #include "IC/Random.H"
12 : #include "Set/Set.H"
13 : #include "Operator/Spectral/FFT.H"
14 :
15 : namespace Integrator
16 : {
17 0 : PFC::PFC() : Integrator()
18 : {
19 0 : }
20 0 : PFC::~PFC()
21 : {
22 0 : delete ic;
23 0 : delete bc;
24 0 : }
25 :
26 0 : void PFC::Parse(PFC &value, IO::ParmParse &pp)
27 : {
28 : // frequency term
29 0 : pp.query_required("q0",value.q0);
30 : // chemical potential width
31 0 : pp.query_required("eps", value.eps);
32 :
33 : // initial condition for :math:`\eta`
34 0 : pp.select_default<IC::Random>("eta.ic", value.ic, value.geom);
35 : // boundary condition for :math:`\eta`
36 0 : pp.select_default<BC::Constant>("eta.bc", value.bc, 1);
37 :
38 0 : value.RegisterNewFab(value.eta_mf, value.bc, 1, 1, "eta",true);
39 0 : value.RegisterNewFab(value.grad_chempot_mf, value.bc, 1, 1, "grad_chempot",true);
40 0 : }
41 :
42 :
43 : #ifdef ALAMO_FFT
44 : void
45 : PFC::Advance (int lev, Set::Scalar /*time*/, Set::Scalar dt)
46 : {
47 : //
48 : // FFT Boilerplate
49 : //
50 :
51 : Operator::Spectral::FFT fft(geom,refRatio(),lev);
52 :
53 : //
54 : // Compute the gradient of the chemical potential in realspace
55 : //
56 : for ( amrex::MFIter mfi(*eta_mf[lev],true); mfi.isValid(); ++mfi )
57 : {
58 : const amrex::Box& bx = mfi.tilebox();
59 : amrex::Array4<const amrex::Real> const& eta = eta_mf[lev]->array(mfi);
60 : amrex::Array4<amrex::Real> const& grad_chempot = grad_chempot_mf[lev]->array(mfi);
61 : amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k)
62 : {
63 : grad_chempot(i, j, k) = eta(i, j, k) * eta(i, j, k) * eta(i, j, k);
64 : });
65 : }
66 :
67 : grad_chempot_mf[lev]->FillBoundary();
68 :
69 : //
70 : // FFT of eta
71 : //
72 : amrex::FabArray<amrex::BaseFab<Set::Complex>> eta_hat_mf = fft.MakeSpectralFab();
73 : fft.Forward(*eta_mf[lev],eta_hat_mf);
74 :
75 : //
76 : // FFT of chemical potential gradient
77 : //
78 : amrex::FabArray<amrex::BaseFab<amrex::GpuComplex<Set::Scalar> > > chempot_hat_mf = fft.MakeSpectralFab();
79 : fft.Forward(*grad_chempot_mf[lev], chempot_hat_mf);
80 :
81 : //
82 : // Perform update in spectral coordinatees
83 : //
84 : for (amrex::MFIter mfi(eta_hat_mf, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
85 : {
86 : const amrex::Box &bx = mfi.tilebox();
87 :
88 : amrex::Array4<amrex::GpuComplex<Set::Scalar>> const & eta_hat = eta_hat_mf.array(mfi);
89 : amrex::Array4<amrex::GpuComplex<Set::Scalar>> const & N_hat = chempot_hat_mf.array(mfi);
90 :
91 : fft.ParallelFor(bx, [=] AMREX_GPU_DEVICE(int m, int n, int p, Set::Scalar omega2) {
92 :
93 : Set::Scalar omega4 = omega2*omega2;
94 : Set::Scalar omega6 = omega2*omega2*omega2;
95 :
96 : eta_hat(m, n, p) = eta_hat(m, n, p) - dt * omega2 * N_hat(m, n, p);
97 : eta_hat(m,n,p) /= 1.0 + dt * ((q0*q0*q0*q0 - eps)*omega2 - 2.0* q0*q0 * omega4 + omega6);
98 : });
99 : }
100 :
101 : //
102 : // Transform solution back to realspace
103 : //
104 : fft.Backward(eta_hat_mf, *eta_mf[lev]);
105 : }
106 : #else
107 : void
108 0 : PFC::Advance (int, Set::Scalar, Set::Scalar)
109 : {
110 0 : Util::Abort(INFO,"Alamo must be compiled with fft");
111 0 : }
112 : #endif
113 :
114 : void
115 0 : PFC::Initialize (int lev)
116 : {
117 0 : ic->Initialize(lev,eta_mf);
118 0 : grad_chempot_mf[lev]->setVal(0.0);
119 0 : }
120 :
121 :
122 : void
123 0 : PFC::TagCellsForRefinement (int /*lev*/, amrex::TagBoxArray& /*a_tags*/, Set::Scalar /*time*/, int /*ngrow*/)
124 : {
125 0 : }
126 :
127 :
128 : }
|