Alamo
WENO5.H
Go to the documentation of this file.
1//
2// This header defines :code:`Numeric::Advect::WENO5`, a fifth-order finite-volume
3// advection operator using Jiang-Shu weighted essentially non-oscillatory
4// reconstruction.
5//
6// The operator is written as a GPU-safe functor:
7//
8// .. code-block:: c++
9//
10// rhs = weno5(phi, velocity, i, j, k, comp, DX, options, stencil);
11//
12// It computes face velocities by averaging neighboring cell-centered velocity
13// values, reconstructs left and right states of :math:`\phi` at each face using
14// WENO5, selects the upwind state, and returns either
15// :math:`-\nabla\cdot(\phi\mathbf{u})` or
16// :math:`-\nabla\cdot(\phi\mathbf{u}) + \phi\nabla\cdot\mathbf{u}` depending on
17// :code:`Numeric::Advect::Options::form`.
18//
19// This implementation assumes collocated cell-centered data:
20// :code:`phi_location = Set::HC::Cell` and
21// :code:`velocity_location = Set::HC::Cell`. It requires three ghost cells in each
22// coordinate direction.
23//
24
25#ifndef NUMERIC_ADVECT_WENO5_H
26#define NUMERIC_ADVECT_WENO5_H
27
28#include "Advect.H"
29
30namespace Numeric
31{
32namespace Advect
33{
34class WENO5
35{
36public:
37 static constexpr const char* name = "weno5";
40
41 Set::Scalar eps = 1.0e-12;
42
43 static void Parse(WENO5& value, IO::ParmParse& pp)
44 {
45 // small nonnegative value to prevent division by zero
46 pp.query_default("eps", value.eps, 1.0e-12);
47 }
48
49 AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE
50 int NGhost() const
51 {
52 return 3;
53 }
54
55 AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE
57 Set::Scalar fm1,
58 Set::Scalar f0,
59 Set::Scalar fp1,
60 Set::Scalar fp2) const
61 {
62 Set::Scalar p0 = (2.0 * fm2 - 7.0 * fm1 + 11.0 * f0) / 6.0;
63 Set::Scalar p1 = (-fm1 + 5.0 * f0 + 2.0 * fp1) / 6.0;
64 Set::Scalar p2 = (2.0 * f0 + 5.0 * fp1 - fp2) / 6.0;
65
66 Set::Scalar b0 = (13.0 / 12.0) * (fm2 - 2.0 * fm1 + f0) * (fm2 - 2.0 * fm1 + f0) +
67 0.25 * (fm2 - 4.0 * fm1 + 3.0 * f0) * (fm2 - 4.0 * fm1 + 3.0 * f0);
68 Set::Scalar b1 = (13.0 / 12.0) * (fm1 - 2.0 * f0 + fp1) * (fm1 - 2.0 * f0 + fp1) +
69 0.25 * (fm1 - fp1) * (fm1 - fp1);
70 Set::Scalar b2 = (13.0 / 12.0) * (f0 - 2.0 * fp1 + fp2) * (f0 - 2.0 * fp1 + fp2) +
71 0.25 * (3.0 * f0 - 4.0 * fp1 + fp2) * (3.0 * f0 - 4.0 * fp1 + fp2);
72
73 Set::Scalar a0 = 0.1 / ((eps + b0) * (eps + b0));
74 Set::Scalar a1 = 0.6 / ((eps + b1) * (eps + b1));
75 Set::Scalar a2 = 0.3 / ((eps + b2) * (eps + b2));
76 Set::Scalar asum = a0 + a1 + a2;
77 return (a0 * p0 + a1 * p1 + a2 * p2) / asum;
78 }
79
80 AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE
82 Set::Scalar f0,
83 Set::Scalar fp1,
84 Set::Scalar fp2,
85 Set::Scalar fp3) const
86 {
87 Set::Scalar p0 = (2.0 * fp3 - 7.0 * fp2 + 11.0 * fp1) / 6.0;
88 Set::Scalar p1 = (-fp2 + 5.0 * fp1 + 2.0 * f0) / 6.0;
89 Set::Scalar p2 = (2.0 * fp1 + 5.0 * f0 - fm1) / 6.0;
90
91 Set::Scalar b0 = (13.0 / 12.0) * (fp3 - 2.0 * fp2 + fp1) * (fp3 - 2.0 * fp2 + fp1) +
92 0.25 * (fp3 - 4.0 * fp2 + 3.0 * fp1) * (fp3 - 4.0 * fp2 + 3.0 * fp1);
93 Set::Scalar b1 = (13.0 / 12.0) * (fp2 - 2.0 * fp1 + f0) * (fp2 - 2.0 * fp1 + f0) +
94 0.25 * (fp2 - f0) * (fp2 - f0);
95 Set::Scalar b2 = (13.0 / 12.0) * (fp1 - 2.0 * f0 + fm1) * (fp1 - 2.0 * f0 + fm1) +
96 0.25 * (3.0 * fp1 - 4.0 * f0 + fm1) * (3.0 * fp1 - 4.0 * f0 + fm1);
97
98 Set::Scalar a0 = 0.1 / ((eps + b0) * (eps + b0));
99 Set::Scalar a1 = 0.6 / ((eps + b1) * (eps + b1));
100 Set::Scalar a2 = 0.3 / ((eps + b2) * (eps + b2));
101 Set::Scalar asum = a0 + a1 + a2;
102 return (a0 * p0 + a1 * p1 + a2 * p2) / asum;
103 }
104
105 template<class Phi, class Velocity>
106 AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE
107 Set::Scalar operator()( Phi const& phi,
108 Velocity const& velocity,
109 int i, int j, int k,
110 int comp,
111 const Set::Scalar* DX,
112 Options options = {},
113 std::array<Numeric::StencilType, AMREX_SPACEDIM> stencil = Numeric::DefaultType) const
114 {
115 (void)stencil;
116
117 const Set::Scalar phi_c = phi(i,j,k,comp);
118 Set::Scalar div_phi_u = 0.0;
119 Set::Scalar div_u = 0.0;
120
121 Set::Scalar ux_xlo = 0.5 * (velocity(i-1,j,k,0) + velocity(i,j,k,0));
122 Set::Scalar ux_xhi = 0.5 * (velocity(i,j,k,0) + velocity(i+1,j,k,0));
123 Set::Scalar phi_xlo_l = ReconstructLeft(phi(i-3,j,k,comp), phi(i-2,j,k,comp), phi(i-1,j,k,comp), phi_c, phi(i+1,j,k,comp));
124 Set::Scalar phi_xlo_r = ReconstructRight(phi(i-2,j,k,comp), phi(i-1,j,k,comp), phi_c, phi(i+1,j,k,comp), phi(i+2,j,k,comp));
125 Set::Scalar phi_xhi_l = ReconstructLeft(phi(i-2,j,k,comp), phi(i-1,j,k,comp), phi_c, phi(i+1,j,k,comp), phi(i+2,j,k,comp));
126 Set::Scalar phi_xhi_r = ReconstructRight(phi(i-1,j,k,comp), phi_c, phi(i+1,j,k,comp), phi(i+2,j,k,comp), phi(i+3,j,k,comp));
127 Set::Scalar flux_xlo = ux_xlo * (ux_xlo >= 0.0 ? phi_xlo_l : phi_xlo_r);
128 Set::Scalar flux_xhi = ux_xhi * (ux_xhi >= 0.0 ? phi_xhi_l : phi_xhi_r);
129 div_phi_u += (flux_xhi - flux_xlo) / DX[0];
130 div_u += (ux_xhi - ux_xlo) / DX[0];
131
132#if AMREX_SPACEDIM >= 2
133 Set::Scalar uy_ylo = 0.5 * (velocity(i,j-1,k,1) + velocity(i,j,k,1));
134 Set::Scalar uy_yhi = 0.5 * (velocity(i,j,k,1) + velocity(i,j+1,k,1));
135 Set::Scalar phi_ylo_l = ReconstructLeft(phi(i,j-3,k,comp), phi(i,j-2,k,comp), phi(i,j-1,k,comp), phi_c, phi(i,j+1,k,comp));
136 Set::Scalar phi_ylo_r = ReconstructRight(phi(i,j-2,k,comp), phi(i,j-1,k,comp), phi_c, phi(i,j+1,k,comp), phi(i,j+2,k,comp));
137 Set::Scalar phi_yhi_l = ReconstructLeft(phi(i,j-2,k,comp), phi(i,j-1,k,comp), phi_c, phi(i,j+1,k,comp), phi(i,j+2,k,comp));
138 Set::Scalar phi_yhi_r = ReconstructRight(phi(i,j-1,k,comp), phi_c, phi(i,j+1,k,comp), phi(i,j+2,k,comp), phi(i,j+3,k,comp));
139 Set::Scalar flux_ylo = uy_ylo * (uy_ylo >= 0.0 ? phi_ylo_l : phi_ylo_r);
140 Set::Scalar flux_yhi = uy_yhi * (uy_yhi >= 0.0 ? phi_yhi_l : phi_yhi_r);
141 div_phi_u += (flux_yhi - flux_ylo) / DX[1];
142 div_u += (uy_yhi - uy_ylo) / DX[1];
143#endif
144
145#if AMREX_SPACEDIM == 3
146 Set::Scalar uz_zlo = 0.5 * (velocity(i,j,k-1,2) + velocity(i,j,k,2));
147 Set::Scalar uz_zhi = 0.5 * (velocity(i,j,k,2) + velocity(i,j,k+1,2));
148 Set::Scalar phi_zlo_l = ReconstructLeft(phi(i,j,k-3,comp), phi(i,j,k-2,comp), phi(i,j,k-1,comp), phi_c, phi(i,j,k+1,comp));
149 Set::Scalar phi_zlo_r = ReconstructRight(phi(i,j,k-2,comp), phi(i,j,k-1,comp), phi_c, phi(i,j,k+1,comp), phi(i,j,k+2,comp));
150 Set::Scalar phi_zhi_l = ReconstructLeft(phi(i,j,k-2,comp), phi(i,j,k-1,comp), phi_c, phi(i,j,k+1,comp), phi(i,j,k+2,comp));
151 Set::Scalar phi_zhi_r = ReconstructRight(phi(i,j,k-1,comp), phi_c, phi(i,j,k+1,comp), phi(i,j,k+2,comp), phi(i,j,k+3,comp));
152 Set::Scalar flux_zlo = uz_zlo * (uz_zlo >= 0.0 ? phi_zlo_l : phi_zlo_r);
153 Set::Scalar flux_zhi = uz_zhi * (uz_zhi >= 0.0 ? phi_zhi_l : phi_zhi_r);
154 div_phi_u += (flux_zhi - flux_zlo) / DX[2];
155 div_u += (uz_zhi - uz_zlo) / DX[2];
156#endif
157
158 if (options.form == Form::Conservative) return -div_phi_u;
159 return -div_phi_u + phi_c * div_u;
160 }
161
162 template<class Phi, class Velocity>
163 AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE
164 Set::Scalar Scalar( Phi const& phi,
165 Velocity const& velocity,
166 int i, int j, int k,
167 int comp,
168 const Set::Scalar* DX,
169 Options options = {},
170 std::array<Numeric::StencilType, AMREX_SPACEDIM> stencil = Numeric::DefaultType) const
171 {
172 return (*this)(phi, velocity, i, j, k, comp, DX, options, stencil);
173 }
174};
175}
176}
177
178#endif
int query_default(std::string name, T &value, T defaultvalue)
Definition ParmParse.H:293
Set::Scalar eps
Definition WENO5.H:41
static constexpr Set::HC velocity_location
Definition WENO5.H:39
static constexpr Set::HC phi_location
Definition WENO5.H:38
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Set::Scalar ReconstructLeft(Set::Scalar fm2, Set::Scalar fm1, Set::Scalar f0, Set::Scalar fp1, Set::Scalar fp2) const
Definition WENO5.H:56
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Set::Scalar ReconstructRight(Set::Scalar fm1, Set::Scalar f0, Set::Scalar fp1, Set::Scalar fp2, Set::Scalar fp3) const
Definition WENO5.H:81
static constexpr const char * name
Definition WENO5.H:37
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE int NGhost() const
Definition WENO5.H:50
static void Parse(WENO5 &value, IO::ParmParse &pp)
Definition WENO5.H:43
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Set::Scalar Scalar(Phi const &phi, Velocity const &velocity, int i, int j, int k, int comp, const Set::Scalar *DX, Options options={}, std::array< Numeric::StencilType, AMREX_SPACEDIM > stencil=Numeric::DefaultType) const
Definition WENO5.H:164
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Set::Scalar operator()(Phi const &phi, Velocity const &velocity, int i, int j, int k, int comp, const Set::Scalar *DX, Options options={}, std::array< Numeric::StencilType, AMREX_SPACEDIM > stencil=Numeric::DefaultType) const
Definition WENO5.H:107
This namespace contains some numerical tools.
Definition Advect.H:14
static std::array< StencilType, AMREX_SPACEDIM > DefaultType
Definition Stencil.H:23
amrex::Real Scalar
Definition Base.H:19
Hypercube
Definition Set.H:31
@ Cell
Definition Set.H:32