1#ifndef AMREX_FFT_CROSSPROJ_H_
2#define AMREX_FFT_CROSSPROJ_H_
27template <
typename MF = MultiFab>
30 static_assert(AMREX_SPACEDIM >= 2,
"FFT::CrossProj requires AMREX_SPACEDIM >= 2");
40 : m_domain_lo(geom.Domain().smallEnd()),
41 m_geom(detail::shift_geom(geom))
43 if (!m_geom.isAllPeriodic()) {
44 amrex::Abort(
"FFT::CrossProj: only supports periodic BC");
46 if (m_geom.Domain().shortside() < 2) {
47 amrex::Abort(
"FFT::CrossProj: domain must have at least 2 cells in each direction");
63 Array<std::pair<Boundary,Boundary>,AMREX_SPACEDIM>
const& bc)
67 for (
auto const& b : bc) {
69 amrex::Abort(
"FFT::CrossProj: only supports periodic BC");
83 void solve (MF& a_soln, MF
const& a_rhs);
88 std::unique_ptr<R2C<typename MF::value_type>> m_r2c;
97 a_soln.nComp() >= AMREX_SPACEDIM &&
98 a_rhs.nComp() >= AMREX_SPACEDIM);
101 MF
const* rhs = &a_rhs;
103 if (m_domain_lo != 0) {
104 detail::shift_mfs(m_domain_lo, a_soln, a_rhs, solntmp, rhstmp);
109 using T =
typename MF::value_type;
117 T(1)/T(m_geom.CellSize(1)),
118 T(1)/T(m_geom.CellSize(2)))};
119 auto scale = m_r2c->scalingFactor();
122 m_geom.Domain().length(1),
123 m_geom.Domain().length(2))};
132 AMREX_D_TERM(T ca = (2*i == len[0]) ? T(0) : std::cos(a);,
133 T cb = (2*j == len[1]) ? T(0) : std::cos(b);,
134 T cc = (2*k == len[2]) ? T(0) : std::cos(c));
138#if (AMREX_SPACEDIM == 2)
139 T
const sx = std::sin(a)*cb*dxfac[0];
140 T
const sy = ca*std::sin(b)*dxfac[1];
142 T
const s2 = sx*sx + sy*sy;
144 T
const s2d = (s2 != T(0)) ? s2 : T(1);
145 auto cdiv = (sx * spectral_data[0] + sy * spectral_data[1]) / s2d;
146 spectral_data[0] -= sx * cdiv;
147 spectral_data[1] -= sy * cdiv;
149 T
const sx = std::sin(a)*cb*cc*dxfac[0];
150 T
const sy = ca*std::sin(b)*cc*dxfac[1];
151 T
const sz = ca*cb*std::sin(c)*dxfac[2];
153 T
const s2 = sx*sx + sy*sy + sz*sz;
155 T
const s2d = (s2 != T(0)) ? s2 : T(1);
156 auto cdiv = (sx * spectral_data[0] + sy * spectral_data[1]
157 + sz * spectral_data[2]) / s2d;
158 spectral_data[0] -= sx * cdiv;
159 spectral_data[1] -= sy * cdiv;
160 spectral_data[2] -= sz * cdiv;
162 for (
int n = 0; n < AMREX_SPACEDIM; ++n) {
163 spectral_data[n] *=
scale;
169 m_r2c->forward(*rhs);
170 m_r2c->post_forward_doit_0(f);
171 m_r2c->backward_doit(*soln, ng, m_geom.periodicity());
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:593
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
Problem-domain geometry: maps between index space and physical space.
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_D_TERM(a, b, c)
Definition AMReX_SPACE.H:172
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
void solve(MF &a_soln, MF const &a_rhs)
Project the velocity in a_rhs and store the result in a_soln.
Definition AMReX_FFT_CrossProj.H:92
CrossProj(Geometry const &geom, Array< std::pair< Boundary, Boundary >, 3 > const &bc)
Construct a CrossProj solver with explicit boundary types.
Definition AMReX_FFT_CrossProj.H:62
CrossProj(Geometry const &geom)
Construct a periodic CrossProj solver.
Definition AMReX_FFT_CrossProj.H:38
Parallel Discrete Fourier Transform.
Definition AMReX_FFT_R2C.H:48
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:87
std::array< T, N > Array
Definition AMReX_Array.H:31
__host__ __device__ constexpr T elemwiseMin(T const &a, T const &b) noexcept
Definition AMReX_Algorithm.H:75
Definition AMReX_FFT_CrossProj.H:8
@ periodic
Definition AMReX_FFT_Helper.H:59
constexpr T pi()
Definition AMReX_Math.H:211
__host__ __device__ void ignore_unused(const Ts &...)
No-op helper that marks variables as intentionally unused.
Definition AMReX.H:273
constexpr bool IsFabArray_v
Definition AMReX_TypeTraits.H:34
__host__ __device__ constexpr IntVectND< dim > scale(const IntVectND< dim > &p, int s) noexcept
Returns a IntVectND obtained by multiplying each of the components of this IntVectND by s.
Definition AMReX_IntVect.H:1128
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:244
Lightweight accessor for data associated with a single cell.
Definition AMReX_Array4.H:47
Definition AMReX_FFT_Helper.H:83
Info & setBatchSize(int bsize)
Specify the batch size for FFT.
Definition AMReX_FFT_Helper.H:156
Fixed-size array that can be used on GPU.
Definition AMReX_Array.H:52