34 const amrex::Real tol,
38 const amrex::Real omega = 2.0_rt * std::numbers::pi_v<amrex::Real> / T;
39 const amrex::Real depsdk = H / 2.0_rt;
44 amrex::Real k = (omega * omega) / g;
46 amrex::Real f = tol + 1.0_rt;
47 while (std::abs(f) > tol && iter < iter_max) {
51 const amrex::Real S = 2.0_rt * std::exp(2.0_rt * k * d) /
52 (std::exp(4.0_rt * k * d) + 1.0_rt);
53 const amrex::Real C = 1.0_rt - S;
54 const amrex::Real eps = k * H / 2.0_rt;
55 const amrex::Real C0 = std::sqrt(std::tanh(k * d));
56 const amrex::Real C2 =
57 C0 * (2.0_rt + (7.0_rt * S * S)) / (4.0_rt * C * C);
58 const amrex::Real numterm_C4 =
59 (4.0_rt + (32.0_rt * S) - (116.0_rt *
utils::powi(S, 2)) -
62 const amrex::Real C4 = C0 * numterm_C4 / (32.0_rt *
utils::powi(C, 5));
64 const amrex::Real dSdk = -2.0_rt * d * std::sinh(2.0_rt * k * d) /
66 const amrex::Real dCdk = -dSdk;
67 const amrex::Real dC0dk =
68 d / (2.0_rt * C0 *
utils::powi(std::cosh(k * d), 2));
70 const amrex::Real dC2dk =
72 ((dC0dk * (2.0_rt + (7.0_rt *
utils::powi(S, 2)))) +
73 (C0 * 14.0_rt * S * dSdk))) -
74 (C0 * (2.0_rt + (7.0_rt *
utils::powi(S, 2))) * 8.0_rt * C *
77 const amrex::Real dC4dk =
79 ((dC0dk * numterm_C4) +
80 (C0 * ((32.0_rt * dSdk) - (232.0_rt * S * dSdk) -
84 (C0 * numterm_C4 * 160.0_rt *
utils::powi(C, 4) * dCdk)) /
89 (g *
utils::powi(C0, 2)) + (g * k * 2.0_rt * C0 * dC0dk);
98 ((2.0_rt * eps * depsdk * C2) +
109 ((8.0_rt *
utils::powi(eps, 3) * depsdk * C0 * C4) +
111 ((C0 * dC4dk) + (C4 * dC0dk))) +
112 (12.0_rt *
utils::powi(eps, 5) * depsdk * C2 * C4) +
114 ((C2 * dC4dk) + (C4 * dC2dk))) +
145 if (iter == iter_max) {
149 return 2.0_rt * std::numbers::pi_v<amrex::Real> / k;
154 amrex::Real wavenumber,
155 amrex::Real water_depth,
176 amrex::Real kd = wavenumber * water_depth;
177 kd = amrex::min<amrex::Real>(kd, 50.0_rt * std::numbers::pi_v<amrex::Real>);
181 2.0_rt * std::exp(2.0_rt * kd) / (std::exp(4.0_rt * kd) + 1.0_rt);
182 amrex::Real C = 1.0_rt - S;
183 amrex::Real Sh = std::sinh(kd);
184 amrex::Real Th = std::tanh(kd);
187 (1.0_rt + std::exp(-2.0_rt * kd)) / (1.0_rt - std::exp(-2 * kd));
190 a11 = 1.0_rt / std::sinh(kd);
193 b22 = CTh * (1.0_rt + (2.0_rt * S)) / (2.0_rt * C);
194 c2 = std::sqrt(Th) * (2.0_rt + (7.0_rt *
utils::powi(S, 2))) /
196 if (stokes_order == 2) {
201 a31 = (-4.0_rt - (20.0_rt * S) + (10.0_rt *
utils::powi(S, 2)) -
207 (1.0_rt + (3.0_rt * S) + (3.0_rt *
utils::powi(S, 2)) +
210 if (stokes_order == 3) {
215 a42 = ((12.0_rt * S) - (14.0_rt *
utils::powi(S, 2)) -
221 (48.0_rt * (3.0_rt + (2.0_rt * S)) *
utils::powi(C, 5));
223 (6.0_rt - (26.0_rt * S) - (182.0_rt *
utils::powi(S, 2)) -
226 (6.0_rt * (3.0_rt + (2.0_rt * S)) *
utils::powi(C, 4));
228 (24.0_rt + (92.0_rt * S) + (122.0_rt *
utils::powi(S, 2)) +
231 (24.0_rt * (3.0_rt + (2.0_rt * S)) *
utils::powi(C, 4));
233 (4.0_rt + (32.0_rt * S) - (116.0_rt *
utils::powi(S, 2)) -
237 if (stokes_order == 4) {
242 a51 = (-1184.0_rt + (32.0_rt * S) + (13232.0_rt *
utils::powi(S, 2)) +
246 (64.0_rt * Sh * (3.0_rt + (2.0_rt * S)) * (4.0_rt + S) *
248 a53 = ((4.0_rt * S) + (105.0_rt *
utils::powi(S, 2)) +
252 (32.0_rt * Sh * (3.0_rt + (2.0_rt * S)) *
utils::powi(C, 6));
256 (64.0_rt * Sh * (3.0_rt + (2.0_rt * S)) * (4.0_rt + S) *
260 (132.0_rt + (17.0_rt * S) - (2216.0_rt *
utils::powi(S, 2)) -
264 (128.0_rt * (3.0_rt + (2.0_rt * S)) * (4.0_rt + S) *
utils::powi(C, 6));
267 (300.0_rt + (1579.0_rt * S) + (3176.0_rt *
utils::powi(S, 2)) +
271 (384.0_rt * (3.0_rt + (2.0_rt * S)) * (4.0_rt + S) *
utils::powi(C, 6));
272 if (stokes_order == 5) {
276 if (stokes_order > 5 || stokes_order < 2) {
278 "invalid stokes order specified. It should be between 2,3,4 or 5 ");
285 amrex::Real wavelength,
286 amrex::Real water_depth,
287 amrex::Real wave_height,
293 amrex::Real phase_offset,
294 amrex::Real hyp_lo_limit,
295 amrex::Real hyp_hi_limit,
301 const amrex::Real wavenumber =
302 2.0_rt * std::numbers::pi_v<amrex::Real> / wavelength;
305 amrex::Real c0{0.0_rt};
306 amrex::Real a11{0.0_rt}, a22{0.0_rt}, b22{0.0_rt}, c2{0.0_rt};
307 amrex::Real a31{0.0_rt}, a33{0.0_rt}, b31{0.0_rt}, a42{0.0_rt}, a44{0.0_rt};
308 amrex::Real b42{0.0_rt}, b44{0.0_rt}, c4{0.0_rt};
309 amrex::Real a51{0.0_rt}, a53{0.0_rt}, a55{0.0_rt}, b53{0.0_rt}, b55{0.0_rt};
312 stokes_order, wavenumber, water_depth, c0, a11, a22, b22, c2, a31, a33,
313 b31, a42, a44, b42, b44, c4, a51, a53, a55, b53, b55);
315 const amrex::Real eps = wavenumber * wave_height / 2.0_rt;
316 const amrex::Real c =
318 std::sqrt(g / wavenumber);
320 const amrex::Real omega = c * wavenumber;
321 const amrex::Real
phase = (wavenumber * x) - (omega * time) - phase_offset;
323 eta = (((eps * std::cos(
phase))
325 std::cos(2.0_rt *
phase))
327 (std::cos(
phase) - std::cos(3.0_rt *
phase))) +
329 (b44 * std::cos(4.0_rt *
phase)))) +
331 (b53 * std::cos(3.0_rt *
phase)) +
332 (b55 * std::cos(5.0_rt *
phase))))) /
340 const int MAX_ORDER = 5;
341 amrex::GpuArray<amrex::Real, MAX_ORDER> a;
342 if (stokes_order == 2) {
346 if (stokes_order == 3) {
347 a[0] = a11 + ((eps * eps) * a31);
351 if (stokes_order == 4) {
352 a[0] = a11 + ((eps * eps) * a31);
353 a[1] = a22 + ((eps * eps) * a42);
357 if (stokes_order == 5) {
358 a[0] = a11 + ((eps * eps) * a31) + (
utils::powi(eps, 4) * a51);
359 a[1] = a22 + ((eps * eps) * a42);
360 a[2] = a33 + ((eps * eps) * a53);
368 for (
int n = 1; n <= stokes_order; ++n) {
370 const amrex::Real nkdz = n * wavenumber * (water_depth + (z - zsl));
371 amrex::Real cosh_nkdz = std::cosh(nkdz);
372 amrex::Real sinh_nkdz = std::sinh(nkdz);
373 cosh_nkdz = amrex::min<amrex::Real>(
374 hyp_hi_limit, amrex::max<amrex::Real>(hyp_lo_limit, cosh_nkdz));
375 sinh_nkdz = amrex::min<amrex::Real>(
376 hyp_hi_limit, amrex::max<amrex::Real>(hyp_lo_limit, sinh_nkdz));
378 u_w +=
utils::powi(eps, n) *
static_cast<amrex::Real
>(n) * a[n - 1] *
379 cosh_nkdz * std::cos(
static_cast<amrex::Real
>(n) *
phase);
380 w_w +=
utils::powi(eps, n) *
static_cast<amrex::Real
>(n) * a[n - 1] *
381 sinh_nkdz * std::sin(
static_cast<amrex::Real
>(n) *
phase);
383 u_w *= (c0 * std::sqrt(g / wavenumber));
384 w_w *= (c0 * std::sqrt(g / wavenumber));
AMREX_FORCE_INLINE amrex::Real stokes_wave_length(const amrex::Real T, const amrex::Real d, const amrex::Real H, const int order, const amrex::Real g, const amrex::Real tol, const int iter_max)
Definition stokes_waves_K.H:28
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void stokes_coefficients(int stokes_order, amrex::Real wavenumber, amrex::Real water_depth, amrex::Real &c0, amrex::Real &a11, amrex::Real &a22, amrex::Real &b22, amrex::Real &c2, amrex::Real &a31, amrex::Real &a33, amrex::Real &b31, amrex::Real &a42, amrex::Real &a44, amrex::Real &b42, amrex::Real &b44, amrex::Real &c4, amrex::Real &a51, amrex::Real &a53, amrex::Real &a55, amrex::Real &b53, amrex::Real &b55)
Definition stokes_waves_K.H:152
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void stokes_waves(int stokes_order, amrex::Real wavelength, amrex::Real water_depth, amrex::Real wave_height, amrex::Real zsl, amrex::Real g, amrex::Real x, amrex::Real z, amrex::Real time, amrex::Real phase_offset, amrex::Real hyp_lo_limit, amrex::Real hyp_hi_limit, amrex::Real &eta, amrex::Real &u_w, amrex::Real &v_w, amrex::Real &w_w)
Definition stokes_waves_K.H:283