ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_MOSTStress.H
Go to the documentation of this file.
1 #ifndef ERF_MOSTStress_H
2 #define ERF_MOSTStress_H
3 
4 #include <ERF_Constants.H>
5 #include <ERF_IndexDefines.H>
6 #include <ERF_MOSTRoughness.H>
7 #include <ERF_Wstar.H>
8 
9 /**
10  * Structure of plain old data relevant to MOST BCs
11  */
12 struct most_data
13 {
14 public:
15  amrex::Real z0_const{amrex::Real(0.1)}; ///< Roughness height -- default constant value(m)
16  amrex::Real kappa{KAPPA}; ///< von Karman constant
17  amrex::Real gravity{CONST_GRAV}; ///< Acceleration due to gravity (m/s^2)
18  amrex::Real surf_temp_flux{zero}; ///< Heat flux TODO: decide whether this is <θ'w'> or <θv'w'> under moist conditions
19  amrex::Real surf_moist_flux{zero}; ///< Moisture flux
20 
21  amrex::Real Cnk_a{amrex::Real(0.0185)}; ///< Standard Charnock constant https://doi.org/amrex::Real(10.1175)/JAMC-D-17-amrex::Real(0137.1)
22  amrex::Real Cnk_b1{one/amrex::Real(30.0)}; ///< Modified Charnock Eq (4) https://doi.org/amrex::Real(10.1175)/JAMC-D-17-amrex::Real(0137.1)
23  amrex::Real Cnk_b2{amrex::Real(1260.0)}; ///< Modified Charnock Eq (4) https://doi.org/amrex::Real(10.1175)/JAMC-D-17-amrex::Real(0137.1)
24  amrex::Real Cnk_d{amrex::Real(30.0)}; ///< Modified Charnock Eq (4) https://doi.org/amrex::Real(10.1175)/JAMC-D-17-amrex::Real(0137.1)
26  bool visc{false}; ///< Use viscous Charnock formulation
27 
31 
32  const amrex::Real Bjr_beta = amrex::Real(1.2); // Empirical parameter from Beljaars 1995 QJRMS
33 };
34 
35 
36 /**
37  * Structure of similarity functions for Moeng formulation
38  */
40 {
41  //
42  // Similarity functions from Jimenez (2012)
43  //
44  AMREX_GPU_HOST_DEVICE
45  AMREX_FORCE_INLINE
47  calc_psi_m2 (amrex::Real zeta) const
48  {
49  if (zeta > 0) {
50  amrex::Real x = std::pow(one + std::pow(zeta, amrex::Real(2.5)), one/amrex::Real(2.5));
51  return ( -amrex::Real(6.1)*std::log(zeta + x) );
52  } else {
53  amrex::Real x = std::pow(one - amrex::Real(16.0)*zeta, fourth);
54  amrex::Real psi_k_m = two * std::log(myhalf * (one + x)) + std::log(myhalf * (one + x * x)) -
55  two * std::atan(x) + PIoTwo;
56  amrex::Real y = std::pow(one - amrex::Real(10.0)*zeta, one/three);
57  amrex::Real psi_c_m = (three/two)*std::log((y*y + y + one)/three)
58  - std::sqrt(three)*std::atan((two*y + one)/std::sqrt(three))
59  + PI/std::sqrt(three);
60  return ( (psi_k_m + zeta*zeta*psi_c_m) / (one + zeta*zeta) );
61  }
62  }
63 
64  AMREX_GPU_HOST_DEVICE
65  AMREX_FORCE_INLINE
67  calc_psi_h2 (amrex::Real zeta) const
68  {
69  if (zeta > 0) {
70  amrex::Real x = std::pow(one + std::pow(zeta, amrex::Real(1.1)), one/amrex::Real(1.1));
71  return ( -amrex::Real(6.1)*std::log(zeta + x) );
72  } else {
73  amrex::Real x = std::sqrt(one - amrex::Real(16.0)*zeta);
74  amrex::Real psi_k_h = two * std::log(myhalf * (one + x));
75  amrex::Real y = std::pow(one - amrex::Real(34.0)*zeta, one/three);
76  amrex::Real psi_c_h = (three/two)*std::log((y*y + y + one)/three)
77  - std::sqrt(three)*std::atan((two*y + one)/std::sqrt(three))
78  + PI/std::sqrt(three);
79  return ( (psi_k_h + zeta*zeta*psi_c_h) / (one + zeta*zeta) );
80  }
81  }
82 
83 
84  //
85  // Similarity functions from Businger & Dyer (1966)
86  //
87  AMREX_GPU_HOST_DEVICE
88  AMREX_FORCE_INLINE
90  calc_psi_m (amrex::Real zeta) const
91  {
92  if (zeta > 0) {
93  return -beta_m * zeta;
94  } else {
95  amrex::Real x = std::sqrt(std::sqrt(one - gamma_m * zeta));
96  return two * std::log(myhalf * (one + x)) + std::log(myhalf * (one + x * x)) -
97  two * std::atan(x) + PIoTwo;
98  }
99  }
100 
101  AMREX_GPU_HOST_DEVICE
102  AMREX_FORCE_INLINE
104  calc_psi_h (amrex::Real zeta) const
105  {
106  if (zeta > 0) {
107  return -beta_h * zeta;
108  } else {
109  amrex::Real x = std::sqrt(one - gamma_h * zeta);
110  return two * std::log(myhalf * (one + x));
111  }
112  }
113 
114 private:
115  amrex::Real beta_m{amrex::Real(5.0)}; ///< Constants from Dyer, BLM, 1974
116  amrex::Real beta_h{amrex::Real(5.0)}; ///< https://doi.org/amrex::Real(10.1007)/BF00240838
119 };
120 
121 
122 /**
123  * Empirical kinematic viscosity [m2/s] formula from Andreas (1989) CRREL Rep.
124  * 89-11, valid between -173 and 277 deg C.
125  */
126 AMREX_GPU_DEVICE
127 AMREX_FORCE_INLINE
130 {
131  amrex::Real TC = T_degK - amrex::Real(273.15);
132  return amrex::Real(1.326e-5)*(one + amrex::Real(6.542e-3)*TC + amrex::Real(8.301e-6)*TC*TC - amrex::Real(4.84e-9)*TC*TC*TC);
133 }
134 
135 
136 /**
137  * Adiabatic with constant roughness
138  */
139 struct adiabatic
140 {
142  amrex::Real Qvflux)
143  {
144  mdata.surf_temp_flux = Tflux;
145  mdata.surf_moist_flux = Qvflux;
146  }
147 
148  AMREX_GPU_DEVICE
149  AMREX_FORCE_INLINE
150  void
151  iterate_flux (const int& i,
152  const int& j,
153  const int& k,
154  const int& /*max_iters*/,
155  const amrex::Array4<const amrex::Real>& zref_arr,
156  const amrex::Array4<const amrex::Real>& z0_arr,
157  const amrex::Array4<const amrex::Real>& umm_arr,
158  const amrex::Array4<const amrex::Real>& /*tm_arr*/,
159  const amrex::Array4<const amrex::Real>& /*tvm_arr*/,
160  const amrex::Array4<const amrex::Real>& /*qvm_arr*/,
161  const amrex::Array4<amrex::Real>& u_star_arr,
162  const amrex::Array4<amrex::Real>& /*w_star_arr*/,
163  const amrex::Array4<amrex::Real>& t_star_arr,
164  const amrex::Array4<amrex::Real>& q_star_arr,
165  const amrex::Array4<amrex::Real>& /*t_surf_arr*/,
166  const amrex::Array4<amrex::Real>& /*q_surf_arr*/,
167  const amrex::Array4<amrex::Real>& olen_arr,
168  const amrex::Array4<amrex::Real>& /*pblh_arr*/,
169  const amrex::Array4<amrex::Real>& /*Hwave_arr*/,
170  const amrex::Array4<amrex::Real>& /*Lwave_arr*/,
171  const amrex::Array4<amrex::Real>& /*eta_arr*/) const
172  {
173  olen_arr(i,j,k) = bogus_large_value;
174  u_star_arr(i,j,k) = mdata.kappa * umm_arr(i,j,k) / std::log(zref_arr(i,j,k) / z0_arr(i,j,k));
175  t_star_arr(i,j,k) = zero;
176  q_star_arr(i,j,k) = zero;
177  }
178 
179 private:
182 };
183 
184 
185 /**
186  * Adiabatic with charnock roughness
187  */
189 {
191  amrex::Real Qvflux,
192  amrex::Real cnk_a,
193  bool cnk_visc)
194  {
195  mdata.surf_temp_flux = Tflux;
196  mdata.surf_moist_flux = Qvflux;
197  mdata.Cnk_a = cnk_a;
198  mdata.visc = cnk_visc;
199  }
200 
201  AMREX_GPU_DEVICE
202  AMREX_FORCE_INLINE
203  void
204  iterate_flux (const int& i,
205  const int& j,
206  const int& k,
207  const int& max_iters,
208  const amrex::Array4<const amrex::Real>& zref_arr,
209  const amrex::Array4<amrex::Real>& z0_arr,
210  const amrex::Array4<const amrex::Real>& umm_arr,
211  const amrex::Array4<const amrex::Real>& tm_arr,
212  const amrex::Array4<const amrex::Real>& /*tvm_arr*/,
213  const amrex::Array4<const amrex::Real>& /*qvm_arr*/,
214  const amrex::Array4<amrex::Real>& u_star_arr,
215  const amrex::Array4<amrex::Real>& /*w_star_arr*/,
216  const amrex::Array4<amrex::Real>& t_star_arr,
217  const amrex::Array4<amrex::Real>& q_star_arr,
218  const amrex::Array4<amrex::Real>& /*t_surf_arr*/,
219  const amrex::Array4<amrex::Real>& /*q_surf_arr*/,
220  const amrex::Array4<amrex::Real>& olen_arr,
221  const amrex::Array4<amrex::Real>& /*pblh_arr*/,
222  const amrex::Array4<amrex::Real>& /*Hwave_arr*/,
223  const amrex::Array4<amrex::Real>& /*Lwave_arr*/,
224  const amrex::Array4<amrex::Real>& /*eta_arr*/) const
225  {
226  amrex::Real ustar = zero;
227  amrex::Real zref = zref_arr(i,j,k);
228  amrex::Real z0 = z0_arr(i,j,k);
229  amrex::Real z0_old = z0;
230  amrex::Real psi_m = zero;
231  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
232  amrex::Real C = std::log(zref / z0);
233 
234  // Fixed point iteration on roughness
235  int iter_z = 0;
236  do {
237  // Transfer curr to old
238  z0_old = z0;
239 
240  // Update
241  C = std::log(zref / z0_old);
242  ustar = mdata.kappa * umm / (C - psi_m);
243  if (mdata.Cnk_a > 0) {
244  z0 = (mdata.Cnk_a / mdata.gravity) * ustar * ustar;
245  if (mdata.visc) {
246  z0 += air_viscosity(tm_arr(i,j,k)) / std::max(ustar, amrex::Real(0.05));
247  }
248  } else {
249  z0 = COARE3_roughness(zref, umm, ustar);
250  }
251 
252  ++iter_z;
253  } while ( (std::abs(z0 - z0_old) > tol_z) && (iter_z <= max_iters) );
254  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter_z < max_iters,
255  "Maximum number of MOST roughness iterations reached.");
256  C = std::log(zref / z0);
257 
258  // Populate the stored MOST arrays
259  z0_arr(i,j,k) = z0;
260  olen_arr(i,j,k) = bogus_large_value;
261  u_star_arr(i,j,k) = mdata.kappa * umm / (C - psi_m);
262  t_star_arr(i,j,k) = zero;
263  q_star_arr(i,j,k) = zero;
264  }
265 
266 private:
269 #ifdef AMREX_USE_FLOAT
270  const amrex::Real tol_z = amrex::Real(1.0e-6);
271 #else
272  const amrex::Real tol_z = amrex::Real(1.0e-10);
273 #endif
274  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
275 };
276 
277 
278 /**
279  * Adiabatic with modified charnock roughness
280  */
282 {
284  amrex::Real Qvflux,
285  amrex::Real depth)
286  {
287  mdata.surf_temp_flux = Tflux;
288  mdata.surf_moist_flux = Qvflux;
289  mdata.Cnk_d = depth;
290  mdata.Cnk_b = mdata.Cnk_b1 * std::log(mdata.Cnk_b2 / mdata.Cnk_d);
291  }
292 
293  AMREX_GPU_DEVICE
294  AMREX_FORCE_INLINE
295  void
296  iterate_flux (const int& i,
297  const int& j,
298  const int& k,
299  const int& max_iters,
300  const amrex::Array4<const amrex::Real>& zref_arr,
301  const amrex::Array4<amrex::Real>& z0_arr,
302  const amrex::Array4<const amrex::Real>& umm_arr,
303  const amrex::Array4<const amrex::Real>& /*tm_arr*/,
304  const amrex::Array4<const amrex::Real>& /*tvm_arr*/,
305  const amrex::Array4<const amrex::Real>& /*qvm_arr*/,
306  const amrex::Array4<amrex::Real>& u_star_arr,
307  const amrex::Array4<amrex::Real>& /*w_star_arr*/,
308  const amrex::Array4<amrex::Real>& t_star_arr,
309  const amrex::Array4<amrex::Real>& q_star_arr,
310  const amrex::Array4<amrex::Real>& /*t_surf_arr*/,
311  const amrex::Array4<amrex::Real>& /*q_surf_arr*/,
312  const amrex::Array4<amrex::Real>& olen_arr,
313  const amrex::Array4<amrex::Real>& /*pblh_arr*/,
314  const amrex::Array4<amrex::Real>& /*Hwave_arr*/,
315  const amrex::Array4<amrex::Real>& /*Lwave_arr*/,
316  const amrex::Array4<amrex::Real>& /*eta_arr*/) const
317  {
318  amrex::Real ustar = zero;
319  amrex::Real zref = zref_arr(i,j,k);
320  amrex::Real z0 = z0_arr(i,j,k);
321  amrex::Real z0_old = z0;
322  amrex::Real psi_m = zero;
323  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
324  amrex::Real C = std::log(zref / z0);
325 
326  // Fixed point iteration on roughness
327  int iter_z = 0;
328  do {
329  // Transfer curr to old
330  z0_old = z0;
331 
332  // Update
333  C = std::log(zref / z0_old);
334  ustar = mdata.kappa * umm / (C - psi_m);
335  z0 = std::exp( (amrex::Real(2.7)*ustar - amrex::Real(1.8)/mdata.Cnk_b) / (ustar + amrex::Real(0.17)/mdata.Cnk_b) );
336 
337  ++iter_z;
338  } while ( (std::abs(z0 - z0_old) > tol_z) && (iter_z <= max_iters) );
339  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter_z < max_iters,
340  "Maximum number of MOST roughness iterations reached.");
341  C = std::log(zref / z0);
342 
343  // Populate the stored MOST arrays
344  z0_arr(i,j,k) = z0;
345  olen_arr(i,j,k) = bogus_large_value;
346  u_star_arr(i,j,k) = mdata.kappa * umm / (C - psi_m);
347  t_star_arr(i,j,k) = zero;
348  q_star_arr(i,j,k) = zero;
349  }
350 
351 private:
354 #ifdef AMREX_USE_FLOAT
355  const amrex::Real tol_z = amrex::Real(1.0e-6);
356 #else
357  const amrex::Real tol_z = amrex::Real(1.0e-10);
358 #endif
359  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
360 };
361 
362 
363 /**
364  * Adiabatic with Donelan roughness
365  */
367 {
369  amrex::Real Qvflux)
370  {
371  mdata.surf_temp_flux = Tflux;
372  mdata.surf_moist_flux = Qvflux;
373  }
374 
375  AMREX_GPU_DEVICE
376  AMREX_FORCE_INLINE
377  void
378  iterate_flux (const int& i,
379  const int& j,
380  const int& k,
381  const int& max_iters,
382  const amrex::Array4<const amrex::Real>& zref_arr,
383  const amrex::Array4<amrex::Real>& z0_arr,
384  const amrex::Array4<const amrex::Real>& umm_arr,
385  const amrex::Array4<const amrex::Real>& /*tm_arr*/,
386  const amrex::Array4<const amrex::Real>& /*tvm_arr*/,
387  const amrex::Array4<const amrex::Real>& /*qvm_arr*/,
388  const amrex::Array4<amrex::Real>& u_star_arr,
389  const amrex::Array4<amrex::Real>& /*w_star_arr*/,
390  const amrex::Array4<amrex::Real>& t_star_arr,
391  const amrex::Array4<amrex::Real>& q_star_arr,
392  const amrex::Array4<amrex::Real>& /*t_surf_arr*/,
393  const amrex::Array4<amrex::Real>& /*q_surf_arr*/,
394  const amrex::Array4<amrex::Real>& olen_arr,
395  const amrex::Array4<amrex::Real>& /*pblh_arr*/,
396  const amrex::Array4<amrex::Real>& /*Hwave_arr*/,
397  const amrex::Array4<amrex::Real>& /*Lwave_arr*/,
398  const amrex::Array4<amrex::Real>& /*eta_arr*/) const
399  {
400  int iter = 0;
401  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
402  amrex::Real ustar = zero;
403  amrex::Real zref = zref_arr(i,j,k);
404  amrex::Real z0 = zero;
405  u_star_arr(i,j,k) = mdata.kappa * umm / std::log(zref / z0_arr(i,j,k));
406  if (u_star_arr(i,j,k) == bogus_large_value) {
407  u_star_arr(i,j,k) = mdata.kappa * umm / std::log(zref / z0_arr(i,j,k));
408  }
409  do {
410  ustar = u_star_arr(i,j,k);
411  z0 = Donelan_roughness(ustar);
412  u_star_arr(i,j,k) = mdata.kappa * umm / std::log(zref / z0);
413  ++iter;
414  } while ((std::abs(u_star_arr(i,j,k) - ustar) > tol) && iter <= max_iters);
415  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter < max_iters,
416  "Maximum number of MOST iterations reached.");
417 
418  // Populate the stored MOST arrays
419  z0_arr(i,j,k) = z0;
420  olen_arr(i,j,k) = bogus_large_value;
421  t_star_arr(i,j,k) = zero;
422  q_star_arr(i,j,k) = zero;
423  }
424 
425 private:
428  const amrex::Real tol = amrex::Real(1.0e-5);
429  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
430 };
431 
432 
433 /**
434  * Adiabatic with wave-coupled roughness
435  */
437 {
439  amrex::Real Qvflux)
440  {
441  mdata.surf_temp_flux = Tflux;
442  mdata.surf_moist_flux = Qvflux;
443  }
444 
445  AMREX_GPU_DEVICE
446  AMREX_FORCE_INLINE
447  void
448  iterate_flux (const int& i,
449  const int& j,
450  const int& k,
451  const int& max_iters,
452  const amrex::Array4<const amrex::Real>& zref_arr,
453  const amrex::Array4<amrex::Real>& z0_arr,
454  const amrex::Array4<const amrex::Real>& umm_arr,
455  const amrex::Array4<const amrex::Real>& /*tm_arr*/,
456  const amrex::Array4<const amrex::Real>& /*tvm_arr*/,
457  const amrex::Array4<const amrex::Real>& /*qvm_arr*/,
458  const amrex::Array4<amrex::Real>& u_star_arr,
459  const amrex::Array4<amrex::Real>& /*w_star_arr*/,
460  const amrex::Array4<amrex::Real>& t_star_arr,
461  const amrex::Array4<amrex::Real>& q_star_arr,
462  const amrex::Array4<amrex::Real>& /*t_surf_arr*/,
463  const amrex::Array4<amrex::Real>& /*q_surf_arr*/,
464  const amrex::Array4<amrex::Real>& olen_arr,
465  const amrex::Array4<amrex::Real>& /*pblh_arr*/,
466  const amrex::Array4<amrex::Real>& Hwave_arr,
467  const amrex::Array4<amrex::Real>& Lwave_arr,
468  const amrex::Array4<amrex::Real>& eta_arr) const
469  {
470  int iter = 0;
471  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
472  amrex::Real ustar = zero;
473  amrex::Real zref = zref_arr(i,j,k);
474  amrex::Real z0 = zero;
475  int ie, je;
476  ie = i < lbound(eta_arr).x ? lbound(eta_arr).x : i;
477  je = j < lbound(eta_arr).y ? lbound(eta_arr).y : j;
478  ie = ie > ubound(eta_arr).x ? ubound(eta_arr).x : ie;
479  je = je > ubound(eta_arr).y ? ubound(eta_arr).y : je;
480  u_star_arr(i,j,k) = mdata.kappa * umm / std::log(zref / z0_arr(i,j,k));
481  do {
482  ustar = u_star_arr(i,j,k);
483  z0 = std::min( std::max(amrex::Real(1200.0) * Hwave_arr(i,j,k) * std::pow( Hwave_arr(i,j,k)/(Lwave_arr(i,j,k)+eps), amrex::Real(4.5) )
484  + amrex::Real(0.11) * eta_arr(ie,je,k,EddyDiff::Mom_v) / ustar, z0_eps), z0_max );
485  u_star_arr(i,j,k) = mdata.kappa * umm / std::log(zref / z0);
486  ++iter;
487  } while ((std::abs(u_star_arr(i,j,k) - ustar) > tol) && iter <= max_iters);
488  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter < max_iters,
489  "Maximum number of MOST iterations reached.");
490 
491  // Populate the stored MOST arrays
492  z0_arr(i,j,k) = z0;
493  olen_arr(i,j,k) = bogus_large_value;
494  t_star_arr(i,j,k) = zero;
495  q_star_arr(i,j,k) = zero;
496  }
497 
498 private:
501  const amrex::Real tol = amrex::Real(1.0e-5);
502 #ifdef AMREX_USE_FLOAT
503  const amrex::Real eps = amrex::Real(1e-8);
504 #else
505  const amrex::Real eps = amrex::Real(1e-15);
506 #endif
507  const amrex::Real z0_eps = amrex::Real(1.0e-6);
509  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
510 };
511 
512 
513 /**
514  * Surface flux with constant roughness
515  */
517 {
519  amrex::Real Qvflux,
520  bool cons_qflux)
521  {
522  mdata.surf_temp_flux = Tflux;
523  mdata.surf_moist_flux = Qvflux;
524  spec_qflux = cons_qflux;
525  }
526 
527  AMREX_GPU_DEVICE
528  AMREX_FORCE_INLINE
529  void
530  iterate_flux (const int& i,
531  const int& j,
532  const int& k,
533  const int& max_iters,
534  const amrex::Array4<const amrex::Real>& zref_arr,
535  const amrex::Array4<const amrex::Real>& z0_arr,
536  const amrex::Array4<const amrex::Real>& umm_arr,
537  const amrex::Array4<const amrex::Real>& tm_arr,
538  const amrex::Array4<const amrex::Real>& tvm_arr,
539  const amrex::Array4<const amrex::Real>& qvm_arr,
540  const amrex::Array4<amrex::Real>& u_star_arr,
541  const amrex::Array4<amrex::Real>& w_star_arr,
542  const amrex::Array4<amrex::Real>& t_star_arr,
543  const amrex::Array4<amrex::Real>& q_star_arr,
544  const amrex::Array4<amrex::Real>& t_surf_arr,
545  const amrex::Array4<amrex::Real>& q_surf_arr,
546  const amrex::Array4<amrex::Real>& olen_arr,
547  const amrex::Array4<amrex::Real>& pblh_arr,
548  const amrex::Array4<amrex::Real>& /*Hwave_arr*/,
549  const amrex::Array4<amrex::Real>& /*Lwave_arr*/,
550  const amrex::Array4<amrex::Real>& /*eta_arr*/) const
551  {
552  int iter = 0;
553  amrex::Real ustar = zero;
554  amrex::Real wstar = zero;
555  amrex::Real tflux = zero;
556  amrex::Real qflux = zero;
557  amrex::Real zeta = zero;
558  amrex::Real psi_m = zero;
559  amrex::Real psi_h = zero;
560  amrex::Real Olen = zero;
561  amrex::Real zref = zref_arr(i,j,k);
562  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
563  if (u_star_arr(i,j,k) == bogus_large_value) {
564  u_star_arr(i,j,k) = mdata.kappa * umm / std::log(zref / z0_arr(i,j,k));
565  } else {
566  Olen = olen_arr(i,j,k);
567  zeta = zref / Olen;
568  psi_m = sfuns.calc_psi_m(zeta);
569  psi_h = sfuns.calc_psi_h(zeta);
570  }
571  do {
572  ustar = u_star_arr(i,j,k);
573  qflux = (spec_qflux) ? mdata.surf_moist_flux :
574  -(qvm_arr(i,j,k) - q_surf_arr(i,j,k)) * ustar * mdata.kappa /
575  (std::log(zref / z0_arr(i,j,k)) - psi_h); // <w'Qv'>
576  tflux = mdata.surf_temp_flux*(1 + amrex::Real(0.61)*qvm_arr(i,j,k)) + qflux*amrex::Real(0.61)*tm_arr(i,j,k);
577  if (w_star_arr) {
578  // update w* and Umagmean
579  w_star_arr(i,j,k) = calc_wstar(tflux, pblh_arr(i,j,k), tvm_arr(i,j,k));
580  wstar = mdata.Bjr_beta * w_star_arr(i,j,k);
581  umm = std::sqrt(umm_arr(i,j,k)*umm_arr(i,j,k) + wstar*wstar);
582  umm = std::max(umm, WSMIN);
583  }
584  Olen = -ustar * ustar * ustar * tvm_arr(i,j,k) / (mdata.kappa * mdata.gravity * tflux);
585  zeta = zref / Olen;
586  psi_m = sfuns.calc_psi_m(zeta);
587  psi_h = sfuns.calc_psi_h(zeta);
588  u_star_arr(i,j,k) = mdata.kappa * umm / (std::log(zref / z0_arr(i,j,k)) - psi_m);
589  ++iter;
590  } while ((std::abs(u_star_arr(i,j,k) - ustar) > tol) && iter <= max_iters);
591  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter < max_iters,
592  "Maximum number of MOST iterations reached.");
593 
594  // Populate the stored MOST arrays
595  olen_arr(i,j,k) = Olen;
596  t_surf_arr(i,j,k) = mdata.surf_temp_flux * (std::log(zref / z0_arr(i,j,k)) - psi_h) /
597  (u_star_arr(i,j,k) * mdata.kappa) + tm_arr(i,j,k);
598  t_star_arr(i,j,k) = -mdata.surf_temp_flux / u_star_arr(i,j,k);
599  if (spec_qflux) {
600  q_surf_arr(i,j,k) = mdata.surf_moist_flux * (std::log(zref / z0_arr(i,j,k)) - psi_h) /
601  (u_star_arr(i,j,k) * mdata.kappa) + qvm_arr(i,j,k);
602  q_star_arr(i,j,k) = -mdata.surf_moist_flux / u_star_arr(i,j,k);
603  } else {
604  q_star_arr(i,j,k) = mdata.kappa * (qvm_arr(i,j,k) - q_surf_arr(i,j,k)) /
605  (std::log(zref / z0_arr(i,j,k)) - psi_h);
606  }
607  }
608 
609 private:
613  const amrex::Real tol = amrex::Real(1.0e-5);
614  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
615 };
616 
617 
618 /**
619  * Surface flux with charnock roughness
620  */
622 {
624  amrex::Real Qvflux,
625  amrex::Real cnk_a,
626  bool cnk_visc,
627  bool cons_qflux)
628  {
629  mdata.surf_temp_flux = Tflux;
630  mdata.surf_moist_flux = Qvflux;
631  mdata.Cnk_a = cnk_a;
632  mdata.visc = cnk_visc;
633  spec_qflux = cons_qflux;
634  }
635 
636  AMREX_GPU_DEVICE
637  AMREX_FORCE_INLINE
638  void
639  iterate_flux (const int& i,
640  const int& j,
641  const int& k,
642  const int& max_iters,
643  const amrex::Array4<const amrex::Real>& zref_arr,
644  const amrex::Array4<amrex::Real>& z0_arr,
645  const amrex::Array4<const amrex::Real>& umm_arr,
646  const amrex::Array4<const amrex::Real>& tm_arr,
647  const amrex::Array4<const amrex::Real>& tvm_arr,
648  const amrex::Array4<const amrex::Real>& qvm_arr,
649  const amrex::Array4<amrex::Real>& u_star_arr,
650  const amrex::Array4<amrex::Real>& w_star_arr,
651  const amrex::Array4<amrex::Real>& t_star_arr,
652  const amrex::Array4<amrex::Real>& q_star_arr,
653  const amrex::Array4<amrex::Real>& t_surf_arr,
654  const amrex::Array4<amrex::Real>& q_surf_arr,
655  const amrex::Array4<amrex::Real>& olen_arr,
656  const amrex::Array4<amrex::Real>& pblh_arr,
657  const amrex::Array4<amrex::Real>& /*Hwave_arr*/,
658  const amrex::Array4<amrex::Real>& /*Lwave_arr*/,
659  const amrex::Array4<amrex::Real>& /*eta_arr*/) const
660  {
661  int iter = 0;
662  amrex::Real ustar = zero;
663  amrex::Real wstar = zero;
664  amrex::Real tflux = zero;
665  amrex::Real qflux = zero;
666  amrex::Real z0 = zero;
667  amrex::Real zeta = zero;
668  amrex::Real psi_m = zero;
669  amrex::Real psi_h = zero;
670  amrex::Real Olen = zero;
671  amrex::Real zref = zref_arr(i,j,k);
672  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
673  if (u_star_arr(i,j,k) == bogus_large_value) {
674  u_star_arr(i,j,k) = mdata.kappa * umm / std::log(zref / z0_arr(i,j,k));
675  } else {
676  Olen = olen_arr(i,j,k);
677  zeta = zref / Olen;
678  psi_m = sfuns.calc_psi_m(zeta);
679  psi_h = sfuns.calc_psi_h(zeta);
680  }
681  do {
682  ustar = u_star_arr(i,j,k);
683  if (mdata.Cnk_a > 0) {
684  z0 = (mdata.Cnk_a / mdata.gravity) * ustar * ustar;
685  if (mdata.visc) {
686  z0 += air_viscosity(tm_arr(i,j,k)) / std::max(ustar, amrex::Real(0.05));
687  }
688  } else {
689  z0 = COARE3_roughness(zref, umm, ustar);
690  }
691  qflux = (spec_qflux) ? mdata.surf_moist_flux :
692  -(qvm_arr(i,j,k) - q_surf_arr(i,j,k)) * ustar * mdata.kappa /
693  (std::log(zref / z0_arr(i,j,k)) - psi_h); // <w'Qv'>
694  tflux = mdata.surf_temp_flux*(1 + amrex::Real(0.61)*qvm_arr(i,j,k)) + qflux*amrex::Real(0.61)*tm_arr(i,j,k);
695  if (w_star_arr) {
696  // update w* and Umagmean
697  w_star_arr(i,j,k) = calc_wstar(tflux, pblh_arr(i,j,k), tvm_arr(i,j,k));
698  wstar = mdata.Bjr_beta * w_star_arr(i,j,k);
699  umm = std::sqrt(umm_arr(i,j,k)*umm_arr(i,j,k) + wstar*wstar);
700  umm = std::max(umm, WSMIN);
701  }
702  Olen = -ustar * ustar * ustar * tvm_arr(i,j,k) / (mdata.kappa * mdata.gravity * tflux);
703  zeta = zref / Olen;
704  psi_m = sfuns.calc_psi_m(zeta);
705  psi_h = sfuns.calc_psi_h(zeta);
706  u_star_arr(i,j,k) = mdata.kappa * umm / (std::log(zref / z0) - psi_m);
707  ++iter;
708  } while ((std::abs(u_star_arr(i,j,k) - ustar) > tol) && iter <= max_iters);
709  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter < max_iters,
710  "Maximum number of MOST iterations reached.");
711 
712  // Populate the stored MOST arrays
713  z0_arr(i,j,k) = z0;
714  olen_arr(i,j,k) = Olen;
715  t_surf_arr(i,j,k) = mdata.surf_temp_flux * (std::log(zref / z0) - psi_h) /
716  (u_star_arr(i,j,k) * mdata.kappa) + tm_arr(i,j,k);
717  t_star_arr(i,j,k) = -mdata.surf_temp_flux / u_star_arr(i,j,k);
718  if (spec_qflux) {
719  q_surf_arr(i,j,k) = mdata.surf_moist_flux * (std::log(zref / z0_arr(i,j,k)) - psi_h) /
720  (u_star_arr(i,j,k) * mdata.kappa) + qvm_arr(i,j,k);
721  q_star_arr(i,j,k) = -mdata.surf_moist_flux / u_star_arr(i,j,k);
722  } else {
723  q_star_arr(i,j,k) = mdata.kappa * (qvm_arr(i,j,k) - q_surf_arr(i,j,k)) /
724  (std::log(zref / z0_arr(i,j,k)) - psi_h);
725  }
726  }
727 
728 private:
732  const amrex::Real tol = amrex::Real(1.0e-5);
733  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
734 };
735 
736 
737 /**
738  * Surface flux with modified charnock roughness
739  */
741 {
743  amrex::Real Qvflux,
744  amrex::Real depth,
745  bool cons_qflux)
746  {
747  mdata.surf_temp_flux = Tflux;
748  mdata.surf_moist_flux = Qvflux;
749  mdata.Cnk_d = depth;
750  mdata.Cnk_b = mdata.Cnk_b1 * std::log(mdata.Cnk_b2 / mdata.Cnk_d);
751  spec_qflux = cons_qflux;
752  }
753 
754  AMREX_GPU_DEVICE
755  AMREX_FORCE_INLINE
756  void
757  iterate_flux (const int& i,
758  const int& j,
759  const int& k,
760  const int& max_iters,
761  const amrex::Array4<const amrex::Real>& zref_arr,
762  const amrex::Array4<amrex::Real>& z0_arr,
763  const amrex::Array4<const amrex::Real>& umm_arr,
764  const amrex::Array4<const amrex::Real>& tm_arr,
765  const amrex::Array4<const amrex::Real>& tvm_arr,
766  const amrex::Array4<const amrex::Real>& qvm_arr,
767  const amrex::Array4<amrex::Real>& u_star_arr,
768  const amrex::Array4<amrex::Real>& w_star_arr,
769  const amrex::Array4<amrex::Real>& t_star_arr,
770  const amrex::Array4<amrex::Real>& q_star_arr,
771  const amrex::Array4<amrex::Real>& t_surf_arr,
772  const amrex::Array4<amrex::Real>& q_surf_arr,
773  const amrex::Array4<amrex::Real>& olen_arr,
774  const amrex::Array4<amrex::Real>& pblh_arr,
775  const amrex::Array4<amrex::Real>& /*Hwave_arr*/,
776  const amrex::Array4<amrex::Real>& /*Lwave_arr*/,
777  const amrex::Array4<amrex::Real>& /*eta_arr*/) const
778  {
779  int iter = 0;
780  amrex::Real ustar = zero;
781  amrex::Real wstar = zero;
782  amrex::Real tflux = zero;
783  amrex::Real qflux = zero;
784  amrex::Real z0 = zero;
785  amrex::Real zeta = zero;
786  amrex::Real psi_m = zero;
787  amrex::Real psi_h = zero;
788  amrex::Real Olen = zero;
789  amrex::Real zref = zref_arr(i,j,k);
790  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
791  if (u_star_arr(i,j,k) == bogus_large_value) {
792  u_star_arr(i,j,k) = mdata.kappa * umm / std::log(zref / z0_arr(i,j,k));
793  } else {
794  Olen = olen_arr(i,j,k);
795  zeta = zref / Olen;
796  psi_m = sfuns.calc_psi_m(zeta);
797  psi_h = sfuns.calc_psi_h(zeta);
798  }
799  do {
800  ustar = u_star_arr(i,j,k);
801  z0 = std::exp( (amrex::Real(2.7)*ustar - amrex::Real(1.8)/mdata.Cnk_b) / (ustar + amrex::Real(0.17)/mdata.Cnk_b) );
802  qflux = (spec_qflux) ? mdata.surf_moist_flux :
803  -(qvm_arr(i,j,k) - q_surf_arr(i,j,k)) * ustar * mdata.kappa /
804  (std::log(zref / z0_arr(i,j,k)) - psi_h); // <w'Qv'>
805  tflux = mdata.surf_temp_flux*(1 + amrex::Real(0.61)*qvm_arr(i,j,k)) + qflux*amrex::Real(0.61)*tm_arr(i,j,k);
806  if (w_star_arr) {
807  // update w* and Umagmean
808  w_star_arr(i,j,k) = calc_wstar(tflux, pblh_arr(i,j,k), tvm_arr(i,j,k));
809  wstar = mdata.Bjr_beta * w_star_arr(i,j,k);
810  umm = std::sqrt(umm_arr(i,j,k)*umm_arr(i,j,k) + wstar*wstar);
811  umm = std::max(umm, WSMIN);
812  }
813  Olen = -ustar * ustar * ustar * tvm_arr(i,j,k) / (mdata.kappa * mdata.gravity * tflux);
814  zeta = zref / Olen;
815  psi_m = sfuns.calc_psi_m(zeta);
816  psi_h = sfuns.calc_psi_h(zeta);
817  u_star_arr(i,j,k) = mdata.kappa * umm / (std::log(zref / z0) - psi_m);
818  ++iter;
819  } while ((std::abs(u_star_arr(i,j,k) - ustar) > tol) && iter <= max_iters);
820  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter < max_iters,
821  "Maximum number of MOST iterations reached.");
822 
823  // Populate the stored MOST arrays
824  z0_arr(i,j,k) = z0;
825  olen_arr(i,j,k) = Olen;
826  t_surf_arr(i,j,k) = mdata.surf_temp_flux * (std::log(zref / z0) - psi_h) /
827  (u_star_arr(i,j,k) * mdata.kappa) + tm_arr(i,j,k);
828  t_star_arr(i,j,k) = -mdata.surf_temp_flux / u_star_arr(i,j,k);
829  if (spec_qflux) {
830  q_surf_arr(i,j,k) = mdata.surf_moist_flux * (std::log(zref / z0_arr(i,j,k)) - psi_h) /
831  (u_star_arr(i,j,k) * mdata.kappa) + qvm_arr(i,j,k);
832  q_star_arr(i,j,k) = -mdata.surf_moist_flux / u_star_arr(i,j,k);
833  } else {
834  q_star_arr(i,j,k) = mdata.kappa * (qvm_arr(i,j,k) - q_surf_arr(i,j,k)) /
835  (std::log(zref / z0_arr(i,j,k)) - psi_h);
836  }
837  }
838 
839 private:
843  const amrex::Real tol = amrex::Real(1.0e-5);
844  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
845 };
846 
847 
848 /**
849  * Surface flux with donelan roughness
850  */
852 {
854  amrex::Real Qvflux,
855  bool cons_qflux)
856  {
857  mdata.surf_temp_flux = Tflux;
858  mdata.surf_moist_flux = Qvflux;
859  spec_qflux = cons_qflux;
860  }
861 
862  AMREX_GPU_DEVICE
863  AMREX_FORCE_INLINE
864  void
865  iterate_flux (const int& i,
866  const int& j,
867  const int& k,
868  const int& max_iters,
869  const amrex::Array4<const amrex::Real>& zref_arr,
870  const amrex::Array4<amrex::Real>& z0_arr,
871  const amrex::Array4<const amrex::Real>& umm_arr,
872  const amrex::Array4<const amrex::Real>& tm_arr,
873  const amrex::Array4<const amrex::Real>& tvm_arr,
874  const amrex::Array4<const amrex::Real>& qvm_arr,
875  const amrex::Array4<amrex::Real>& u_star_arr,
876  const amrex::Array4<amrex::Real>& w_star_arr,
877  const amrex::Array4<amrex::Real>& t_star_arr,
878  const amrex::Array4<amrex::Real>& q_star_arr,
879  const amrex::Array4<amrex::Real>& t_surf_arr,
880  const amrex::Array4<amrex::Real>& q_surf_arr,
881  const amrex::Array4<amrex::Real>& olen_arr,
882  const amrex::Array4<amrex::Real>& pblh_arr,
883  const amrex::Array4<amrex::Real>& /*Hwave_arr*/,
884  const amrex::Array4<amrex::Real>& /*Lwave_arr*/,
885  const amrex::Array4<amrex::Real>& /*eta_arr*/) const
886  {
887  int iter = 0;
888  amrex::Real ustar = zero;
889  amrex::Real wstar = zero;
890  amrex::Real tflux = zero;
891  amrex::Real qflux = zero;
892  amrex::Real z0 = zero;
893  amrex::Real zeta = zero;
894  amrex::Real psi_m = zero;
895  amrex::Real psi_h = zero;
896  amrex::Real Olen = zero;
897  amrex::Real zref = zref_arr(i,j,k);
898  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
899  if (u_star_arr(i,j,k) == bogus_large_value) {
900  u_star_arr(i,j,k) = mdata.kappa * umm / std::log(zref / z0_arr(i,j,k));
901  } else {
902  Olen = olen_arr(i,j,k);
903  zeta = zref / Olen;
904  psi_m = sfuns.calc_psi_m(zeta);
905  psi_h = sfuns.calc_psi_h(zeta);
906  }
907  do {
908  ustar = u_star_arr(i,j,k);
909  z0 = Donelan_roughness(ustar);
910  qflux = (spec_qflux) ? mdata.surf_moist_flux :
911  -(qvm_arr(i,j,k) - q_surf_arr(i,j,k)) * ustar * mdata.kappa /
912  (std::log(zref / z0_arr(i,j,k)) - psi_h); // <w'Qv'>
913  tflux = mdata.surf_temp_flux*(1 + amrex::Real(0.61)*qvm_arr(i,j,k)) + qflux*amrex::Real(0.61)*tm_arr(i,j,k);
914  if (w_star_arr) {
915  // update w* and Umagmean
916  w_star_arr(i,j,k) = calc_wstar(tflux, pblh_arr(i,j,k), tvm_arr(i,j,k));
917  wstar = mdata.Bjr_beta * w_star_arr(i,j,k);
918  umm = std::sqrt(umm_arr(i,j,k)*umm_arr(i,j,k) + wstar*wstar);
919  umm = std::max(umm, WSMIN);
920  }
921  Olen = -ustar * ustar * ustar * tvm_arr(i,j,k) / (mdata.kappa * mdata.gravity * tflux);
922  zeta = zref / Olen;
923  psi_m = sfuns.calc_psi_m(zeta);
924  psi_h = sfuns.calc_psi_h(zeta);
925  u_star_arr(i,j,k) = mdata.kappa * umm / (std::log(zref / z0) - psi_m);
926  ++iter;
927  } while ((std::abs(u_star_arr(i,j,k) - ustar) > tol) && iter <= max_iters);
928  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter < max_iters,
929  "Maximum number of MOST iterations reached.");
930 
931  // Populate the stored MOST arrays
932  z0_arr(i,j,k) = z0;
933  olen_arr(i,j,k) = Olen;
934  t_surf_arr(i,j,k) = mdata.surf_temp_flux * (std::log(zref / z0) - psi_h) /
935  (u_star_arr(i,j,k) * mdata.kappa) + tm_arr(i,j,k);
936  t_star_arr(i,j,k) = -mdata.surf_temp_flux / u_star_arr(i,j,k);
937  if (spec_qflux) {
938  q_surf_arr(i,j,k) = mdata.surf_moist_flux * (std::log(zref / z0_arr(i,j,k)) - psi_h) /
939  (u_star_arr(i,j,k) * mdata.kappa) + qvm_arr(i,j,k);
940  q_star_arr(i,j,k) = -mdata.surf_moist_flux / u_star_arr(i,j,k);
941  } else {
942  q_star_arr(i,j,k) = mdata.kappa * (qvm_arr(i,j,k) - q_surf_arr(i,j,k)) /
943  (std::log(zref / z0_arr(i,j,k)) - psi_h);
944  }
945  }
946 
947 private:
951  const amrex::Real tol = amrex::Real(1.0e-5);
952  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
953 };
954 
955 
956 /**
957  * Surface flux with wave-coupled roughness
958  */
960 {
962  amrex::Real Qvflux,
963  bool cons_qflux)
964  {
965  mdata.surf_temp_flux = Tflux;
966  mdata.surf_moist_flux = Qvflux;
967  spec_qflux = cons_qflux;
968  }
969 
970  AMREX_GPU_DEVICE
971  AMREX_FORCE_INLINE
972  void
973  iterate_flux (const int& i,
974  const int& j,
975  const int& k,
976  const int& max_iters,
977  const amrex::Array4<const amrex::Real>& zref_arr,
978  const amrex::Array4<amrex::Real>& z0_arr,
979  const amrex::Array4<const amrex::Real>& umm_arr,
980  const amrex::Array4<const amrex::Real>& tm_arr,
981  const amrex::Array4<const amrex::Real>& tvm_arr,
982  const amrex::Array4<const amrex::Real>& qvm_arr,
983  const amrex::Array4<amrex::Real>& u_star_arr,
984  const amrex::Array4<amrex::Real>& w_star_arr,
985  const amrex::Array4<amrex::Real>& t_star_arr,
986  const amrex::Array4<amrex::Real>& q_star_arr,
987  const amrex::Array4<amrex::Real>& t_surf_arr,
988  const amrex::Array4<amrex::Real>& q_surf_arr,
989  const amrex::Array4<amrex::Real>& olen_arr,
990  const amrex::Array4<amrex::Real>& pblh_arr,
991  const amrex::Array4<amrex::Real>& Hwave_arr,
992  const amrex::Array4<amrex::Real>& Lwave_arr,
993  const amrex::Array4<amrex::Real>& eta_arr) const
994  {
995  int iter = 0;
996  amrex::Real ustar = zero;
997  amrex::Real wstar = zero;
998  amrex::Real tflux = zero;
999  amrex::Real qflux = zero;
1000  amrex::Real z0 = zero;
1001  amrex::Real zeta = zero;
1002  amrex::Real psi_m = zero;
1003  amrex::Real psi_h = zero;
1004  amrex::Real Olen = zero;
1005  amrex::Real zref = zref_arr(i,j,k);
1006  int ie, je;
1007  ie = i < lbound(eta_arr).x ? lbound(eta_arr).x : i;
1008  je = j < lbound(eta_arr).y ? lbound(eta_arr).y : j;
1009  ie = ie > ubound(eta_arr).x ? ubound(eta_arr).x : ie;
1010  je = je > ubound(eta_arr).y ? ubound(eta_arr).y : je;
1011  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
1012  if (u_star_arr(i,j,k) == bogus_large_value) {
1013  u_star_arr(i,j,k) = mdata.kappa * umm / std::log(zref / z0_arr(i,j,k));
1014  } else {
1015  Olen = olen_arr(i,j,k);
1016  zeta = zref / Olen;
1017  psi_m = sfuns.calc_psi_m(zeta);
1018  psi_h = sfuns.calc_psi_h(zeta);
1019  }
1020  do {
1021  ustar = u_star_arr(i,j,k);
1022  z0 = std::min( std::max(amrex::Real(1200.0) * Hwave_arr(i,j,k) * std::pow( Hwave_arr(i,j,k)/(Lwave_arr(i,j,k)+eps), amrex::Real(4.5) )
1023  + amrex::Real(0.11) * eta_arr(ie,je,k,EddyDiff::Mom_v) / ustar, z0_eps), z0_max );
1024  qflux = (spec_qflux) ? mdata.surf_moist_flux :
1025  -(qvm_arr(i,j,k) - q_surf_arr(i,j,k)) * ustar * mdata.kappa /
1026  (std::log(zref / z0_arr(i,j,k)) - psi_h); // <w'Qv'>
1027  tflux = mdata.surf_temp_flux*(1 + amrex::Real(0.61)*qvm_arr(i,j,k)) + qflux*amrex::Real(0.61)*tm_arr(i,j,k);
1028  if (w_star_arr) {
1029  // update w* and Umagmean
1030  w_star_arr(i,j,k) = calc_wstar(tflux, pblh_arr(i,j,k), tvm_arr(i,j,k));
1031  wstar = mdata.Bjr_beta * w_star_arr(i,j,k);
1032  umm = std::sqrt(umm_arr(i,j,k)*umm_arr(i,j,k) + wstar*wstar);
1033  umm = std::max(umm, WSMIN);
1034  }
1035  Olen = -ustar * ustar * ustar * tvm_arr(i,j,k) / (mdata.kappa * mdata.gravity * tflux);
1036  zeta = zref / Olen;
1037  psi_m = sfuns.calc_psi_m(zeta);
1038  psi_h = sfuns.calc_psi_h(zeta);
1039  u_star_arr(i,j,k) = mdata.kappa * umm / (std::log(zref / z0) - psi_m);
1040  ++iter;
1041  } while ((std::abs(u_star_arr(i,j,k) - ustar) > tol) && iter <= max_iters);
1042  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter < max_iters,
1043  "Maximum number of MOST iterations reached.");
1044 
1045  // Populate the stored MOST arrays
1046  z0_arr(i,j,k) = z0;
1047  olen_arr(i,j,k) = Olen;
1048  t_surf_arr(i,j,k) = mdata.surf_temp_flux * (std::log(zref / z0) - psi_h) /
1049  (u_star_arr(i,j,k) * mdata.kappa) + tm_arr(i,j,k);
1050  t_star_arr(i,j,k) = -mdata.surf_temp_flux / u_star_arr(i,j,k);
1051  if (spec_qflux) {
1052  q_surf_arr(i,j,k) = mdata.surf_moist_flux * (std::log(zref / z0_arr(i,j,k)) - psi_h) /
1053  (u_star_arr(i,j,k) * mdata.kappa) + qvm_arr(i,j,k);
1054  q_star_arr(i,j,k) = -mdata.surf_moist_flux / u_star_arr(i,j,k);
1055  } else {
1056  q_star_arr(i,j,k) = mdata.kappa * (qvm_arr(i,j,k) - q_surf_arr(i,j,k)) /
1057  (std::log(zref / z0_arr(i,j,k)) - psi_h);
1058  }
1059  }
1060 
1061 private:
1065  const amrex::Real tol = amrex::Real(1.0e-5);
1066 #ifdef AMREX_USE_FLOAT
1067  const amrex::Real eps = amrex::Real(1e-8);
1068 #else
1069  const amrex::Real eps = amrex::Real(1e-15);
1070 #endif
1071  const amrex::Real z0_eps = amrex::Real(1.0e-6);
1073  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
1074 };
1075 
1076 
1077 /**
1078  * Surface temperature with constant roughness
1079  */
1081 {
1083  amrex::Real Qvflux,
1084  bool cons_qflux)
1085  {
1086  mdata.surf_temp_flux = Tflux;
1087  mdata.surf_moist_flux = Qvflux;
1088  spec_qflux = cons_qflux;
1089  }
1090 
1091  AMREX_GPU_DEVICE
1092  AMREX_FORCE_INLINE
1093  void
1094  iterate_flux (const int& i,
1095  const int& j,
1096  const int& k,
1097  const int& max_iters,
1098  const amrex::Array4<const amrex::Real>& zref_arr,
1099  const amrex::Array4<const amrex::Real>& z0_arr,
1100  const amrex::Array4<const amrex::Real>& umm_arr,
1101  const amrex::Array4<const amrex::Real>& tm_arr,
1102  const amrex::Array4<const amrex::Real>& tvm_arr,
1103  const amrex::Array4<const amrex::Real>& qvm_arr,
1104  const amrex::Array4<amrex::Real>& u_star_arr,
1105  const amrex::Array4<amrex::Real>& w_star_arr,
1106  const amrex::Array4<amrex::Real>& t_star_arr,
1107  const amrex::Array4<amrex::Real>& q_star_arr,
1108  const amrex::Array4<amrex::Real>& t_surf_arr,
1109  const amrex::Array4<amrex::Real>& q_surf_arr,
1110  const amrex::Array4<amrex::Real>& olen_arr,
1111  const amrex::Array4<amrex::Real>& pblh_arr,
1112  const amrex::Array4<amrex::Real>& /*Hwave_arr*/,
1113  const amrex::Array4<amrex::Real>& /*Lwave_arr*/,
1114  const amrex::Array4<amrex::Real>& /*eta_arr*/) const
1115  {
1116  amrex::Real Rib = zero;
1117  amrex::Real zeta = zero;
1118  amrex::Real zeta_old = zero;
1119  amrex::Real psi_m = zero;
1120  amrex::Real psi_h = zero;
1121  amrex::Real num = zero;
1122  amrex::Real den = zero;
1123  amrex::Real zref = zref_arr(i,j,k);
1124  amrex::Real z0 = z0_arr(i,j,k);
1125  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
1126  amrex::Real C = std::log(zref / z0);
1127 
1128  // First iteration we assume neutral (L -> inf)
1129  if (u_star_arr(i,j,k) == bogus_large_value) { olen_arr(i,j,k) = amrex::Real(1.0e3); }
1130  zeta = zref / olen_arr(i,j,k);
1131 
1132  // Water vapor in atmos and surface
1133  amrex::Real qv_s, qv_a;
1134  if (q_surf_arr(i,j,k) > zero) {
1135  qv_s = q_surf_arr(i,j,k);
1136  } else {
1137  // First iteration and no qv_surf was specified
1138  // Use mean since there will be no flux
1139  qv_s = qvm_arr(i,j,k);
1140  }
1141  qv_a = qvm_arr(i,j,k);
1142 
1143  // update w* and Umagmean from Beljaars (1995)
1144  if (w_star_arr) {
1145  // NOTE: Thv flux is lagged, similar to WRF
1146  psi_m = sfuns.calc_psi_m2(zeta);
1147  psi_h = sfuns.calc_psi_h2(zeta);
1148  amrex::Real ustar = mdata.kappa * umm / (C - psi_m);
1149  amrex::Real tstar = mdata.kappa * (tm_arr(i,j,k) - t_surf_arr(i,j,k)) / (C - psi_h);
1151  -ustar * mdata.kappa * (qv_a - qv_s) / (C - psi_h);
1152  amrex::Real tflux = -ustar*tstar*(1 + amrex::Real(0.61)*qvm_arr(i,j,k)) + amrex::Real(0.61)*tm_arr(i,j,k)*qflux;
1153  w_star_arr(i,j,k) = calc_wstar(tflux, pblh_arr(i,j,k), tvm_arr(i,j,k));
1154  amrex::Real wstar = mdata.Bjr_beta * w_star_arr(i,j,k);
1155  umm = std::sqrt(umm_arr(i,j,k)*umm_arr(i,j,k) + wstar*wstar);
1156  umm = std::max(umm, WSMIN);
1157  }
1158 
1159  // Bulk Richardson number w/ moisture
1160  amrex::Real thv_s = t_surf_arr(i,j,k) * (one + amrex::Real(0.61)*qv_s);
1161  amrex::Real thv_a = tm_arr(i,j,k) * (one + amrex::Real(0.61)*qv_a);
1162  Rib = ( (mdata.gravity * zref) / tm_arr(i,j,k) ) *
1163  ( (thv_a - thv_s) / (umm * umm) );
1164  Rib = std::min(std::max(Rib,-amrex::Real(4.0)),amrex::Real(4.0));
1165 
1166  // Fixed point iteration on zeta
1167  int iter = 0;
1168  do {
1169  // Transfer curr to old
1170  zeta_old = zeta;
1171 
1172  // Stability functions
1173  psi_m = sfuns.calc_psi_m2(zeta_old);
1174  psi_h = sfuns.calc_psi_h2(zeta_old);
1175 
1176  // Limiting
1177  num = std::max(C - psi_m, amrex::Real(1.0));
1178  den = std::max(C - psi_h, amrex::Real(1.0));
1179 
1180  // Update with under relaxation
1181  zeta = (one - alpha) * zeta_old + alpha * Rib * num * num / den;
1182 
1183  ++iter;
1184  } while ( (std::abs(zeta - zeta_old) > tol) && (iter <= max_iters) );
1185  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter < max_iters,
1186  "Maximum number of MOST iterations reached.");
1187 
1188  // Populate the stored MOST arrays
1189  olen_arr(i,j,k) = zref / zeta;
1190  u_star_arr(i,j,k) = mdata.kappa * umm / (C - psi_m);
1191  t_star_arr(i,j,k) = mdata.kappa * (tm_arr(i,j,k) - t_surf_arr(i,j,k)) / (C - psi_h);
1192  if (spec_qflux) {
1193  q_surf_arr(i,j,k) = mdata.surf_moist_flux * (C - psi_h) /
1194  (u_star_arr(i,j,k) * mdata.kappa) + qvm_arr(i,j,k);
1195  q_star_arr(i,j,k) = -mdata.surf_moist_flux / u_star_arr(i,j,k);
1196  } else {
1197  q_star_arr(i,j,k) = mdata.kappa * (qvm_arr(i,j,k) - q_surf_arr(i,j,k)) / (C - psi_h);
1198  }
1199  }
1200 
1201 private:
1205  const amrex::Real tol = amrex::Real(1.0e-3);
1207  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
1208 };
1209 
1210 
1211 /**
1212  * Surface temperature with charnock roughness
1213  */
1215 {
1217  amrex::Real Qvflux,
1218  amrex::Real cnk_a,
1219  bool cnk_visc,
1220  bool cons_qflux)
1221  {
1222  mdata.surf_temp_flux = Tflux;
1223  mdata.surf_moist_flux = Qvflux;
1224  mdata.Cnk_a = cnk_a;
1225  mdata.visc = cnk_visc;
1226  spec_qflux = cons_qflux;
1227  }
1228 
1229  AMREX_GPU_DEVICE
1230  AMREX_FORCE_INLINE
1231  void
1232  iterate_flux (const int& i,
1233  const int& j,
1234  const int& k,
1235  const int& max_iters,
1236  const amrex::Array4<const amrex::Real>& zref_arr,
1237  const amrex::Array4<amrex::Real>& z0_arr,
1238  const amrex::Array4<const amrex::Real>& umm_arr,
1239  const amrex::Array4<const amrex::Real>& tm_arr,
1240  const amrex::Array4<const amrex::Real>& tvm_arr,
1241  const amrex::Array4<const amrex::Real>& qvm_arr,
1242  const amrex::Array4<amrex::Real>& u_star_arr,
1243  const amrex::Array4<amrex::Real>& w_star_arr,
1244  const amrex::Array4<amrex::Real>& t_star_arr,
1245  const amrex::Array4<amrex::Real>& q_star_arr,
1246  const amrex::Array4<amrex::Real>& t_surf_arr,
1247  const amrex::Array4<amrex::Real>& q_surf_arr,
1248  const amrex::Array4<amrex::Real>& olen_arr,
1249  const amrex::Array4<amrex::Real>& pblh_arr,
1250  const amrex::Array4<amrex::Real>& /*Hwave_arr*/,
1251  const amrex::Array4<amrex::Real>& /*Lwave_arr*/,
1252  const amrex::Array4<amrex::Real>& /*eta_arr*/) const
1253  {
1254  amrex::Real Rib = zero;
1255  amrex::Real zeta = zero;
1256  amrex::Real zeta_old = zero;
1257  amrex::Real psi_m = zero;
1258  amrex::Real psi_h = zero;
1259  amrex::Real num = zero;
1260  amrex::Real den = zero;
1261  amrex::Real z0 = z0_arr(i,j,k);
1262  amrex::Real z0_old = z0;
1263  amrex::Real ustar = zero;
1264  amrex::Real zref = zref_arr(i,j,k);
1265  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
1266  amrex::Real C = std::log(zref / z0);
1267 
1268  // First iteration we assume neutral (L -> inf)
1269  if (u_star_arr(i,j,k) == bogus_large_value) {
1270  olen_arr(i,j,k) = amrex::Real(1.0e3);
1271  }
1272  zeta = zref / olen_arr(i,j,k);
1273 
1274  // Water vapor in atmos and surface
1275  amrex::Real qv_s, qv_a;
1276  if (q_surf_arr(i,j,k) > zero) {
1277  qv_s = q_surf_arr(i,j,k);
1278  } else {
1279  // First iteration and no qv_surf was specified
1280  // Use mean since there will be no flux
1281  qv_s = qvm_arr(i,j,k);
1282  }
1283  qv_a = qvm_arr(i,j,k);
1284 
1285  // update w* and Umagmean from Beljaars (1995)
1286  if (w_star_arr) {
1287  // NOTE: Thv flux is lagged, similar to WRF
1288  psi_m = sfuns.calc_psi_m2(zeta);
1289  psi_h = sfuns.calc_psi_h2(zeta);
1290  ustar = mdata.kappa * umm / (C - psi_m);
1291  amrex::Real tstar = mdata.kappa * (tm_arr(i,j,k) - t_surf_arr(i,j,k)) / (C - psi_h);
1293  -ustar * mdata.kappa * (qv_a - qv_s) / (C - psi_h);
1294  amrex::Real tflux = -ustar*tstar*(1 + amrex::Real(0.61)*qvm_arr(i,j,k)) + amrex::Real(0.61)*tm_arr(i,j,k)*qflux;
1295  w_star_arr(i,j,k) = calc_wstar(tflux, pblh_arr(i,j,k), tvm_arr(i,j,k));
1296  amrex::Real wstar = mdata.Bjr_beta * w_star_arr(i,j,k);
1297  umm = std::sqrt(umm_arr(i,j,k)*umm_arr(i,j,k) + wstar*wstar);
1298  umm = std::max(umm, WSMIN);
1299  }
1300 
1301  // Bulk Richardson number w/ moisture
1302  amrex::Real thv_s = t_surf_arr(i,j,k) * (one + amrex::Real(0.61)*qv_s);
1303  amrex::Real thv_a = tm_arr(i,j,k) * (one + amrex::Real(0.61)*qv_a);
1304  Rib = ( (mdata.gravity * zref) / tm_arr(i,j,k) ) *
1305  ( (thv_a - thv_s) / (umm * umm) );
1306  Rib = std::min(std::max(Rib,-amrex::Real(4.0)),amrex::Real(4.0));
1307 
1308  // Fixed point iteration on zeta
1309  int iter = 0;
1310  do {
1311  // Transfer curr to old
1312  zeta_old = zeta;
1313 
1314  // Stability functions
1315  psi_m = sfuns.calc_psi_m2(zeta_old);
1316  psi_h = sfuns.calc_psi_h2(zeta_old);
1317 
1318  // Fixed point iteration on roughness
1319  int iter_z = 0;
1320  do {
1321  // Transfer curr to old
1322  z0_old = z0;
1323 
1324  // Update
1325  C = std::log(zref / z0_old);
1326  ustar = mdata.kappa * umm / (C - psi_m);
1327  if (mdata.Cnk_a > 0) {
1328  z0 = (mdata.Cnk_a / mdata.gravity) * ustar * ustar;
1329  if (mdata.visc) {
1330  z0 += air_viscosity(tm_arr(i,j,k)) / std::max(ustar, amrex::Real(0.05));
1331  }
1332  } else {
1333  z0 = COARE3_roughness(zref, umm, ustar);
1334  }
1335 
1336  ++iter_z;
1337  } while ( (std::abs(z0 - z0_old) > tol_z) && (iter_z <= max_iters) );
1338  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter_z < max_iters,
1339  "Maximum number of MOST roughness iterations reached.");
1340  C = std::log(zref / z0);
1341 
1342  // Limiting
1343  num = std::max(C - psi_m, amrex::Real(1.0));
1344  den = std::max(C - psi_h, amrex::Real(1.0));
1345 
1346  // Update with under relaxation
1347  zeta = (amrex::Real(1.0) - alpha) * zeta_old + alpha * Rib * num * num / den;
1348 
1349  ++iter;
1350  } while ( (std::abs(zeta - zeta_old) > tol) && (iter <= max_iters) );
1351  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter < max_iters,
1352  "Maximum number of MOST iterations reached.");
1353 
1354  // Populate the stored MOST arrays
1355  z0_arr(i,j,k) = z0;
1356  olen_arr(i,j,k) = zref / zeta;
1357  u_star_arr(i,j,k) = mdata.kappa * umm / (C - psi_m);
1358  t_star_arr(i,j,k) = mdata.kappa * (tm_arr(i,j,k) - t_surf_arr(i,j,k)) / (C - psi_h);
1359  if (spec_qflux) {
1360  q_surf_arr(i,j,k) = mdata.surf_moist_flux * (C - psi_h) /
1361  (u_star_arr(i,j,k) * mdata.kappa) + qvm_arr(i,j,k);
1362  q_star_arr(i,j,k) = -mdata.surf_moist_flux / u_star_arr(i,j,k);
1363  } else {
1364  q_star_arr(i,j,k) = mdata.kappa * (qvm_arr(i,j,k) - q_surf_arr(i,j,k)) / (C - psi_h);
1365  }
1366  }
1367 
1368 private:
1372  const amrex::Real tol = amrex::Real(1.0e-3);
1373 #ifdef AMREX_USE_FLOAT
1374  const amrex::Real tol_z = amrex::Real(1.0e-6);
1375 #else
1376  const amrex::Real tol_z = amrex::Real(1.0e-10);
1377 #endif
1379  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
1380 };
1381 
1382 
1383 /**
1384  * Surface temperature with modified charnock roughness
1385  */
1387 {
1389  amrex::Real Qvflux,
1390  amrex::Real depth,
1391  bool cons_qflux)
1392  {
1393  mdata.surf_temp_flux = Tflux;
1394  mdata.surf_moist_flux = Qvflux;
1395  mdata.Cnk_d = depth;
1396  mdata.Cnk_b = mdata.Cnk_b1 * std::log(mdata.Cnk_b2 / mdata.Cnk_d);
1397  spec_qflux = cons_qflux;
1398  }
1399 
1400  AMREX_GPU_DEVICE
1401  AMREX_FORCE_INLINE
1402  void
1403  iterate_flux (const int& i,
1404  const int& j,
1405  const int& k,
1406  const int& max_iters,
1407  const amrex::Array4<const amrex::Real>& zref_arr,
1408  const amrex::Array4<amrex::Real>& z0_arr,
1409  const amrex::Array4<const amrex::Real>& umm_arr,
1410  const amrex::Array4<const amrex::Real>& tm_arr,
1411  const amrex::Array4<const amrex::Real>& tvm_arr,
1412  const amrex::Array4<const amrex::Real>& qvm_arr,
1413  const amrex::Array4<amrex::Real>& u_star_arr,
1414  const amrex::Array4<amrex::Real>& w_star_arr,
1415  const amrex::Array4<amrex::Real>& t_star_arr,
1416  const amrex::Array4<amrex::Real>& q_star_arr,
1417  const amrex::Array4<amrex::Real>& t_surf_arr,
1418  const amrex::Array4<amrex::Real>& q_surf_arr,
1419  const amrex::Array4<amrex::Real>& olen_arr,
1420  const amrex::Array4<amrex::Real>& pblh_arr,
1421  const amrex::Array4<amrex::Real>& /*Hwave_arr*/,
1422  const amrex::Array4<amrex::Real>& /*Lwave_arr*/,
1423  const amrex::Array4<amrex::Real>& /*eta_arr*/) const
1424  {
1425  amrex::Real Rib = zero;
1426  amrex::Real zeta = zero;
1427  amrex::Real zeta_old = zero;
1428  amrex::Real psi_m = zero;
1429  amrex::Real psi_h = zero;
1430  amrex::Real num = zero;
1431  amrex::Real den = zero;
1432  amrex::Real z0 = z0_arr(i,j,k);
1433  amrex::Real z0_old = z0;
1434  amrex::Real ustar = zero;
1435  amrex::Real zref = zref_arr(i,j,k);
1436  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
1437  amrex::Real C = std::log(zref / z0);
1438 
1439  // First iteration we assume neutral (L -> inf)
1440  if (u_star_arr(i,j,k) == bogus_large_value) {
1441  olen_arr(i,j,k) = amrex::Real(1000);
1442  }
1443  zeta = zref / olen_arr(i,j,k);
1444 
1445  // Water vapor in atmos and surface
1446  amrex::Real qv_s, qv_a;
1447  if (q_surf_arr(i,j,k) > zero) {
1448  qv_s = q_surf_arr(i,j,k);
1449  } else {
1450  // First iteration and no qv_surf was specified
1451  // Use mean since there will be no flux
1452  qv_s = qvm_arr(i,j,k);
1453  }
1454  qv_a = qvm_arr(i,j,k);
1455 
1456  // update w* and Umagmean from Beljaars (1995)
1457  if (w_star_arr) {
1458  // NOTE: Thv flux is lagged, similar to WRF
1459  psi_m = sfuns.calc_psi_m2(zeta);
1460  psi_h = sfuns.calc_psi_h2(zeta);
1461  ustar = mdata.kappa * umm / (C - psi_m);
1462  amrex::Real tstar = mdata.kappa * (tm_arr(i,j,k) - t_surf_arr(i,j,k)) / (C - psi_h);
1464  -ustar * mdata.kappa * (qv_a - qv_s) / (C - psi_h);
1465  amrex::Real tflux = -ustar*tstar*(1 + amrex::Real(0.61)*qvm_arr(i,j,k)) + amrex::Real(0.61)*tm_arr(i,j,k)*qflux;
1466  w_star_arr(i,j,k) = calc_wstar(tflux, pblh_arr(i,j,k), tvm_arr(i,j,k));
1467  amrex::Real wstar = mdata.Bjr_beta * w_star_arr(i,j,k);
1468  umm = std::sqrt(umm_arr(i,j,k)*umm_arr(i,j,k) + wstar*wstar);
1469  umm = std::max(umm, WSMIN);
1470  }
1471 
1472  // Bulk Richardson number w/ moisture
1473  amrex::Real thv_s = t_surf_arr(i,j,k) * (amrex::Real(1.0) + amrex::Real(0.61)*qv_s);
1474  amrex::Real thv_a = tm_arr(i,j,k) * (amrex::Real(1.0) + amrex::Real(0.61)*qv_a);
1475  Rib = ( (mdata.gravity * zref) / tm_arr(i,j,k) ) *
1476  ( (thv_a - thv_s) / (umm * umm) );
1477  Rib = std::min(std::max(Rib,-amrex::Real(4.0)),amrex::Real(4.0));
1478 
1479  // Fixed point iteration on zeta
1480  int iter = 0;
1481  do {
1482  // Transfer curr to old
1483  zeta_old = zeta;
1484 
1485  // Stability functions
1486  psi_m = sfuns.calc_psi_m2(zeta_old);
1487  psi_h = sfuns.calc_psi_h2(zeta_old);
1488 
1489  // Fixed point iteration on roughness
1490  int iter_z = 0;
1491  do {
1492  // Transfer curr to old
1493  z0_old = z0;
1494 
1495  // Update
1496  C = std::log(zref / z0_old);
1497  ustar = mdata.kappa * umm / (C - psi_m);
1498  z0 = std::exp( (amrex::Real(2.7)*ustar - amrex::Real(1.8)/mdata.Cnk_b) / (ustar + amrex::Real(0.17)/mdata.Cnk_b) );
1499 
1500  ++iter_z;
1501  } while ( (std::abs(z0 - z0_old) > tol_z) && (iter_z <= max_iters) );
1502  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter_z < max_iters,
1503  "Maximum number of MOST roughness iterations reached.");
1504  C = std::log(zref / z0);
1505 
1506  // Limiting
1507  num = std::max(C - psi_m, amrex::Real(1.0));
1508  den = std::max(C - psi_h, amrex::Real(1.0));
1509 
1510  // Update with under relaxation
1511  zeta = (amrex::Real(1.0) - alpha) * zeta_old + alpha * Rib * num * num / den;
1512 
1513  ++iter;
1514  } while ( (std::abs(zeta - zeta_old) > tol) && (iter <= max_iters) );
1515  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter < max_iters,
1516  "Maximum number of MOST iterations reached.");
1517 
1518  // Populate the stored MOST arrays
1519  z0_arr(i,j,k) = z0;
1520  olen_arr(i,j,k) = zref / zeta;
1521  u_star_arr(i,j,k) = mdata.kappa * umm / (C - psi_m);
1522  t_star_arr(i,j,k) = mdata.kappa * (tm_arr(i,j,k) - t_surf_arr(i,j,k)) / (C - psi_h);
1523  if (spec_qflux) {
1524  q_surf_arr(i,j,k) = mdata.surf_moist_flux * (C - psi_h) /
1525  (u_star_arr(i,j,k) * mdata.kappa) + qvm_arr(i,j,k);
1526  q_star_arr(i,j,k) = -mdata.surf_moist_flux / u_star_arr(i,j,k);
1527  } else {
1528  q_star_arr(i,j,k) = mdata.kappa * (qvm_arr(i,j,k) - q_surf_arr(i,j,k)) / (C - psi_h);
1529  }
1530  }
1531 
1532 private:
1536  const amrex::Real tol = amrex::Real(1.0e-3);
1537 #ifdef AMREX_USE_FLOAT
1538  const amrex::Real tol_z = amrex::Real(1.0e-6);
1539 #else
1540  const amrex::Real tol_z = amrex::Real(1.0e-10);
1541 #endif
1543  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
1544 };
1545 
1546 
1547 /**
1548  * Surface temperature with donelan roughness
1549  */
1551 {
1553  amrex::Real Qvflux,
1554  bool cons_qflux)
1555  {
1556  mdata.surf_temp_flux = Tflux;
1557  mdata.surf_moist_flux = Qvflux;
1558  spec_qflux = cons_qflux;
1559  }
1560 
1561  AMREX_GPU_DEVICE
1562  AMREX_FORCE_INLINE
1563  void
1564  iterate_flux (const int& i,
1565  const int& j,
1566  const int& k,
1567  const int& max_iters,
1568  const amrex::Array4<const amrex::Real>& zref_arr,
1569  const amrex::Array4<amrex::Real>& z0_arr,
1570  const amrex::Array4<const amrex::Real>& umm_arr,
1571  const amrex::Array4<const amrex::Real>& tm_arr,
1572  const amrex::Array4<const amrex::Real>& tvm_arr,
1573  const amrex::Array4<const amrex::Real>& qvm_arr,
1574  const amrex::Array4<amrex::Real>& u_star_arr,
1575  const amrex::Array4<amrex::Real>& w_star_arr,
1576  const amrex::Array4<amrex::Real>& t_star_arr,
1577  const amrex::Array4<amrex::Real>& q_star_arr,
1578  const amrex::Array4<amrex::Real>& t_surf_arr,
1579  const amrex::Array4<amrex::Real>& q_surf_arr,
1580  const amrex::Array4<amrex::Real>& olen_arr,
1581  const amrex::Array4<amrex::Real>& pblh_arr,
1582  const amrex::Array4<amrex::Real>& /*Hwave_arr*/,
1583  const amrex::Array4<amrex::Real>& /*Lwave_arr*/,
1584  const amrex::Array4<amrex::Real>& /*eta_arr*/) const
1585  {
1586  int iter = 0;
1587  amrex::Real ustar = zero;
1588  amrex::Real wstar = zero;
1589  amrex::Real z0 = zero;
1590  amrex::Real tflux = zero;
1591  amrex::Real qflux = zero;
1592  amrex::Real zeta = zero;
1593  amrex::Real psi_m = zero;
1594  amrex::Real psi_h = zero;
1595  amrex::Real Olen = zero;
1596  amrex::Real Oleno = zero;
1597  amrex::Real zref = zref_arr(i,j,k);
1598  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
1599  if (u_star_arr(i,j,k) == bogus_large_value) {
1600  u_star_arr(i,j,k) = mdata.kappa * umm / std::log(zref / z0_arr(i,j,k));
1601  } else {
1602  Olen = olen_arr(i,j,k);
1603  Oleno = Olen;
1604  zeta = zref / Olen;
1605  psi_m = sfuns.calc_psi_m(zeta);
1606  psi_h = sfuns.calc_psi_h(zeta);
1607  }
1608  do {
1609  ustar = u_star_arr(i,j,k);
1610  z0 = Donelan_roughness(ustar);
1611  tflux = -(tm_arr(i,j,k) - t_surf_arr(i,j,k)) * ustar * mdata.kappa /
1612  (std::log(zref / z0) - psi_h); // <w'T'>
1613  tflux *= (1 + amrex::Real(0.61)*qvm_arr(i,j,k));
1614  qflux = (spec_qflux) ? mdata.surf_moist_flux :
1615  -(qvm_arr(i,j,k) - q_surf_arr(i,j,k)) * ustar * mdata.kappa /
1616  (std::log(zref / z0_arr(i,j,k)) - psi_h); // <w'Qv'>
1617  tflux += amrex::Real(0.61)*tm_arr(i,j,k) * qflux; // ~= <w'Tv'>
1618  if (w_star_arr) {
1619  // update w* and Umagmean
1620  w_star_arr(i,j,k) = calc_wstar(tflux, pblh_arr(i,j,k), tvm_arr(i,j,k));
1621  wstar = mdata.Bjr_beta * w_star_arr(i,j,k);
1622  umm = std::sqrt(umm_arr(i,j,k)*umm_arr(i,j,k) + wstar*wstar);
1623  umm = std::max(umm, WSMIN);
1624  }
1625  Olen = -ustar * ustar * ustar * tvm_arr(i,j,k) / (mdata.kappa * mdata.gravity * tflux);
1626  if ( (((Olen >= zero) && (Oleno <= zero)) ||
1627  ((Olen <= zero) && (Oleno >= zero))) &&
1628  std::fabs(Olen) + std::fabs(Oleno) < amrex::Real(1.0)) {
1629  Olen = myhalf * (Olen + Oleno);
1630  }
1631  Oleno = Olen;
1632  zeta = zref / Olen;
1633  psi_m = sfuns.calc_psi_m(zeta);
1634  psi_h = sfuns.calc_psi_h(zeta);
1635  u_star_arr(i,j,k) = mdata.kappa * umm / (std::log(zref / z0) - psi_m);
1636  ++iter;
1637  } while ((std::abs(u_star_arr(i,j,k) - ustar) > tol) && iter <= max_iters);
1638  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter < max_iters,
1639  "Maximum number of MOST iterations reached.");
1640 
1641  // Populate the stored MOST arrays
1642  z0_arr(i,j,k) = z0;
1643  olen_arr(i,j,k) = Olen;
1644  t_star_arr(i,j,k) = mdata.kappa * (tm_arr(i,j,k) - t_surf_arr(i,j,k)) /
1645  (std::log(zref / z0) - psi_h);
1646  if (spec_qflux) {
1647  q_surf_arr(i,j,k) = mdata.surf_moist_flux * (std::log(zref / z0_arr(i,j,k)) - psi_h) /
1648  (u_star_arr(i,j,k) * mdata.kappa) + qvm_arr(i,j,k);
1649  q_star_arr(i,j,k) = -mdata.surf_moist_flux / u_star_arr(i,j,k);
1650  } else {
1651  q_star_arr(i,j,k) = mdata.kappa * (qvm_arr(i,j,k) - q_surf_arr(i,j,k)) /
1652  (std::log(zref / z0_arr(i,j,k)) - psi_h);
1653  }
1654  }
1655 
1656 private:
1660  const amrex::Real tol = amrex::Real(1.0e-5);
1661  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
1662 };
1663 
1664 
1665 /**
1666  * Surface temperature with wave-coupled roughness
1667  */
1669 {
1671  amrex::Real Qvflux,
1672  bool cons_qflux)
1673  {
1674  mdata.surf_temp_flux = Tflux;
1675  mdata.surf_moist_flux = Qvflux;
1676  spec_qflux = cons_qflux;
1677  }
1678 
1679  AMREX_GPU_DEVICE
1680  AMREX_FORCE_INLINE
1681  void
1682  iterate_flux (const int& i,
1683  const int& j,
1684  const int& k,
1685  const int& max_iters,
1686  const amrex::Array4<const amrex::Real>& zref_arr,
1687  const amrex::Array4<amrex::Real>& z0_arr,
1688  const amrex::Array4<const amrex::Real>& umm_arr,
1689  const amrex::Array4<const amrex::Real>& tm_arr,
1690  const amrex::Array4<const amrex::Real>& tvm_arr,
1691  const amrex::Array4<const amrex::Real>& qvm_arr,
1692  const amrex::Array4<amrex::Real>& u_star_arr,
1693  const amrex::Array4<amrex::Real>& w_star_arr,
1694  const amrex::Array4<amrex::Real>& t_star_arr,
1695  const amrex::Array4<amrex::Real>& q_star_arr,
1696  const amrex::Array4<amrex::Real>& t_surf_arr,
1697  const amrex::Array4<amrex::Real>& q_surf_arr,
1698  const amrex::Array4<amrex::Real>& olen_arr,
1699  const amrex::Array4<amrex::Real>& pblh_arr,
1700  const amrex::Array4<amrex::Real>& Hwave_arr,
1701  const amrex::Array4<amrex::Real>& Lwave_arr,
1702  const amrex::Array4<amrex::Real>& eta_arr) const
1703  {
1704  int iter = 0;
1705  amrex::Real ustar = zero;
1706  amrex::Real wstar = zero;
1707  amrex::Real z0 = zero;
1708  amrex::Real tflux = zero;
1709  amrex::Real qflux = zero;
1710  amrex::Real zeta = zero;
1711  amrex::Real psi_m = zero;
1712  amrex::Real psi_h = zero;
1713  amrex::Real Olen = zero;
1714  amrex::Real Oleno = zero;
1715  amrex::Real zref = zref_arr(i,j,k);
1716  int ie, je;
1717  ie = i < lbound(eta_arr).x ? lbound(eta_arr).x : i;
1718  je = j < lbound(eta_arr).y ? lbound(eta_arr).y : j;
1719  ie = ie > ubound(eta_arr).x ? ubound(eta_arr).x : ie;
1720  je = je > ubound(eta_arr).y ? ubound(eta_arr).y : je;
1721  amrex::Real umm = std::max(umm_arr(i,j,k), WSMIN);
1722  if (u_star_arr(i,j,k) == bogus_large_value) {
1723  u_star_arr(i,j,k) = mdata.kappa * umm / std::log(zref / z0_arr(i,j,k));
1724  } else {
1725  Olen = olen_arr(i,j,k);
1726  Oleno = Olen;
1727  zeta = zref / Olen;
1728  psi_m = sfuns.calc_psi_m(zeta);
1729  psi_h = sfuns.calc_psi_h(zeta);
1730  }
1731  do {
1732  ustar = u_star_arr(i,j,k);
1733  z0 = std::min( std::max(amrex::Real(1200.0) * Hwave_arr(i,j,k) * std::pow( Hwave_arr(i,j,k)/(Lwave_arr(i,j,k)+eps), amrex::Real(4.5) )
1734  + amrex::Real(0.11) * eta_arr(ie,je,k,EddyDiff::Mom_v) / ustar, z0_eps), z0_max );
1735  tflux = -(tm_arr(i,j,k) - t_surf_arr(i,j,k)) * ustar * mdata.kappa /
1736  (std::log(zref / z0) - psi_h); // <w'T'>
1737  tflux *= (1 + amrex::Real(0.61)*qvm_arr(i,j,k));
1738  qflux = (spec_qflux) ? mdata.surf_moist_flux :
1739  -(qvm_arr(i,j,k) - q_surf_arr(i,j,k)) * ustar * mdata.kappa /
1740  (std::log(zref / z0_arr(i,j,k)) - psi_h); // <w'Qv'>
1741  tflux += amrex::Real(0.61)*tm_arr(i,j,k) * qflux; // ~= <w'Tv'>
1742  if (w_star_arr) {
1743  // update w* and Umagmean
1744  w_star_arr(i,j,k) = calc_wstar(tflux, pblh_arr(i,j,k), tvm_arr(i,j,k));
1745  wstar = mdata.Bjr_beta * w_star_arr(i,j,k);
1746  umm = std::sqrt(umm_arr(i,j,k)*umm_arr(i,j,k) + wstar*wstar);
1747  umm = std::max(umm, WSMIN);
1748  }
1749  Olen = -ustar * ustar * ustar * tvm_arr(i,j,k) / (mdata.kappa * mdata.gravity * tflux);
1750  if ( (((Olen >= zero) && (Oleno <= zero)) ||
1751  ((Olen <= zero) && (Oleno >= zero))) &&
1752  std::fabs(Olen) + std::fabs(Oleno) < amrex::Real(1.0)) {
1753  Olen = myhalf * (Olen + Oleno);
1754  }
1755  Oleno = Olen;
1756  zeta = zref / Olen;
1757  psi_m = sfuns.calc_psi_m(zeta);
1758  psi_h = sfuns.calc_psi_h(zeta);
1759  u_star_arr(i,j,k) = mdata.kappa * umm / (std::log(zref / z0) - psi_m);
1760  ++iter;
1761  } while ((std::abs(u_star_arr(i,j,k) - ustar) > tol) && iter <= max_iters);
1762  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(iter < max_iters,
1763  "Maximum number of MOST iterations reached.");
1764 
1765  // Populate the stored MOST arrays
1766  z0_arr(i,j,k) = z0;
1767  olen_arr(i,j,k) = Olen;
1768  t_star_arr(i,j,k) = mdata.kappa * (tm_arr(i,j,k) - t_surf_arr(i,j,k)) /
1769  (std::log(zref / z0) - psi_h);
1770  if (spec_qflux) {
1771  q_surf_arr(i,j,k) = mdata.surf_moist_flux * (std::log(zref / z0_arr(i,j,k)) - psi_h) /
1772  (u_star_arr(i,j,k) * mdata.kappa) + qvm_arr(i,j,k);
1773  q_star_arr(i,j,k) = -mdata.surf_moist_flux / u_star_arr(i,j,k);
1774  } else {
1775  q_star_arr(i,j,k) = mdata.kappa * (qvm_arr(i,j,k) - q_surf_arr(i,j,k)) /
1776  (std::log(zref / z0_arr(i,j,k)) - psi_h);
1777  }
1778  }
1779 
1780 private:
1784  const amrex::Real tol = amrex::Real(1.0e-5);
1785 #ifdef AMREX_USE_FLOAT
1786  const amrex::Real eps = amrex::Real(1e-8);
1787 #else
1788  const amrex::Real eps = amrex::Real(1e-15);
1789 #endif
1790  const amrex::Real z0_eps = amrex::Real(1.0e-6);
1792  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
1793 };
1794 
1795 
1796 /**
1797  * Moeng flux formulation
1798  */
1800 {
1802 
1803  AMREX_GPU_DEVICE
1804  AMREX_FORCE_INLINE
1805  amrex::Real
1806  compute_q_flux (const int& i,
1807  const int& j,
1808  const int& k,
1809  const amrex::Array4<const amrex::Real>& cons_arr,
1810  const amrex::Array4<const amrex::Real>& velx_arr,
1811  const amrex::Array4<const amrex::Real>& vely_arr,
1812  const amrex::Array4<const amrex::Real>& umm_arr,
1813  const amrex::Array4<const amrex::Real>& qvm_arr,
1814  const amrex::Array4<const amrex::Real>& u_star_arr,
1815  const amrex::Array4<const amrex::Real>& q_star_arr,
1816  const amrex::Array4<const amrex::Real>& q_surf_arr) const
1817  {
1818  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
1819  amrex::Real qv = cons_arr(i,j,k,RhoQ1_comp) / rho;
1820  amrex::Real velx = myhalf * ( velx_arr(i,j,k) + velx_arr(i+1,j ,k) );
1821  amrex::Real vely = myhalf * ( vely_arr(i,j,k) + vely_arr(i ,j+1,k) );
1822 
1823  amrex::Real qv_mean = qvm_arr(i,j,0);
1824  amrex::Real ustar = u_star_arr(i,j,0);
1825  amrex::Real qstar = q_star_arr(i,j,0);
1826  amrex::Real qv_surf = q_surf_arr(i,j,0);
1827  amrex::Real wsp_mean = umm_arr(i,j,0);
1828  wsp_mean = std::max(wsp_mean, WSMIN);
1829 
1830  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
1831  amrex::Real num1 = wsp * (qv_mean-qv_surf);
1832  amrex::Real num2 = wsp_mean * (qv-qv_mean);
1833 
1834  // NOTE: this is rho*<Qv'w'> = -K dQvdz
1835  amrex::Real moflux = (std::abs(qstar) > eps) ?
1836  -rho*qstar*ustar*(num1+num2)/((qv_mean-qv_surf)*wsp_mean) : zero;
1837 
1838  return moflux;
1839  }
1840 
1841  AMREX_GPU_DEVICE
1842  AMREX_FORCE_INLINE
1843  amrex::Real
1844  compute_t_flux (const int& i,
1845  const int& j,
1846  const int& k,
1847  const amrex::Array4<const amrex::Real>& cons_arr,
1848  const amrex::Array4<const amrex::Real>& velx_arr,
1849  const amrex::Array4<const amrex::Real>& vely_arr,
1850  const amrex::Array4<const amrex::Real>& umm_arr,
1851  const amrex::Array4<const amrex::Real>& tm_arr,
1852  const amrex::Array4<const amrex::Real>& u_star_arr,
1853  const amrex::Array4<const amrex::Real>& t_star_arr,
1854  const amrex::Array4<const amrex::Real>& t_surf_arr) const
1855  {
1856  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
1857  amrex::Real theta = cons_arr(i,j,k,RhoTheta_comp) / rho;
1858  amrex::Real velx = myhalf * ( velx_arr(i,j,k) + velx_arr(i+1,j ,k) );
1859  amrex::Real vely = myhalf * ( vely_arr(i,j,k) + vely_arr(i ,j+1,k) );
1860 
1861  amrex::Real theta_mean = tm_arr(i,j,0);
1862  amrex::Real ustar = u_star_arr(i,j,0);
1863  amrex::Real tstar = t_star_arr(i,j,0);
1864  amrex::Real theta_surf = t_surf_arr(i,j,0);
1865  amrex::Real wsp_mean = umm_arr(i,j,0);
1866  wsp_mean = std::max(wsp_mean, WSMIN);
1867 
1868  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
1869  amrex::Real num1 = wsp * (theta_mean-theta_surf);
1870  amrex::Real num2 = wsp_mean * (theta-theta_mean);
1871 
1872  // NOTE: this is rho*<T'w'> = -K dTdz
1873  amrex::Real moflux = (std::abs(tstar) > eps) ?
1874  -rho*tstar*ustar*(num1+num2)/((theta_mean-theta_surf)*wsp_mean) : zero;
1875 
1876  return moflux;
1877  }
1878 
1879  AMREX_GPU_DEVICE
1880  AMREX_FORCE_INLINE
1881  amrex::Real
1882  compute_u_flux (const int& i,
1883  const int& j,
1884  const int& k,
1885  const amrex::Array4<const amrex::Real>& cons_arr,
1886  const amrex::Array4<const amrex::Real>& velx_arr,
1887  const amrex::Array4<const amrex::Real>& vely_arr,
1888  const amrex::Array4<const amrex::Real>& umm_arr,
1889  const amrex::Array4<const amrex::Real>& um_arr,
1890  const amrex::Array4<const amrex::Real>& u_star_arr) const
1891  {
1892  amrex::Real velx = velx_arr(i,j,k);
1893  amrex::Real vely = fourth * ( vely_arr(i ,j,k) + vely_arr(i ,j+1,k)
1894  + vely_arr(i-1,j,k) + vely_arr(i-1,j+1,k) );
1895  amrex::Real rho = myhalf * ( cons_arr(i-1,j,k,Rho_comp) + cons_arr(i,j,k,Rho_comp) );
1896 
1897  amrex::Real umean = um_arr(i,j,0);
1898  amrex::Real ustar = myhalf * ( u_star_arr(i-1,j,0) + u_star_arr(i,j,0) );
1899  amrex::Real wsp_mean = myhalf * ( umm_arr(i-1,j,0) + umm_arr(i,j,0) );
1900  wsp_mean = std::max(wsp_mean, WSMIN);
1901 
1902  // Note: The surface mean shear stress is decomposed into tau_xz by
1903  // multiplying the modeled shear stress (rho*ustar^2) with
1904  // a factor of umean/wsp_mean for directionality; this factor
1905  // modifies the denominator from what is in Moeng amrex::Real(1984.)
1906  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
1907  amrex::Real num1 = wsp * umean;
1908  amrex::Real num2 = wsp_mean * (velx-umean);
1909 
1910  // NOTE: this is rho*<u'w'> = -K dudz
1911  amrex::Real stressx = -rho*ustar*ustar * (num1+num2)/(wsp_mean*wsp_mean);
1912 
1913  return stressx;
1914  }
1915 
1916  AMREX_GPU_DEVICE
1917  AMREX_FORCE_INLINE
1918  amrex::Real
1919  compute_v_flux (const int& i,
1920  const int& j,
1921  const int& k,
1922  const amrex::Array4<const amrex::Real>& cons_arr,
1923  const amrex::Array4<const amrex::Real>& velx_arr,
1924  const amrex::Array4<const amrex::Real>& vely_arr,
1925  const amrex::Array4<const amrex::Real>& umm_arr,
1926  const amrex::Array4<const amrex::Real>& vm_arr,
1927  const amrex::Array4<const amrex::Real>& u_star_arr) const
1928  {
1929  amrex::Real velx = fourth * ( velx_arr(i,j ,k) + velx_arr(i+1,j ,k)
1930  + velx_arr(i,j-1,k) + velx_arr(i+1,j-1,k) );
1931  amrex::Real vely = vely_arr(i,j,k);
1932  amrex::Real rho = myhalf * ( cons_arr(i,j-1,k,Rho_comp) + cons_arr(i,j,k,Rho_comp) );
1933 
1934  amrex::Real vmean = vm_arr(i,j,0);
1935  amrex::Real ustar = myhalf * ( u_star_arr(i,j-1,0) + u_star_arr(i,j,0) );
1936  amrex::Real wsp_mean = myhalf * ( umm_arr(i,j-1,0) + umm_arr(i,j,0) );
1937  wsp_mean = std::max(wsp_mean, WSMIN);
1938 
1939  // Note: The surface mean shear stress is decomposed into tau_yz by
1940  // multiplying the modeled shear stress (rho*ustar^2) with
1941  // a factor of vmean/wsp_mean for directionality; this factor
1942  // modifies the denominator from what is in Moeng amrex::Real(1984.)
1943  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
1944  amrex::Real num1 = wsp * vmean;
1945  amrex::Real num2 = wsp_mean * (vely-vmean);
1946 
1947  // NOTE: this is rho*<v'w'> = -K dvdz
1948  amrex::Real stressy = -rho*ustar*ustar * (num1+num2)/(wsp_mean*wsp_mean);
1949 
1950  return stressy;
1951  }
1952 
1953 private:
1954 #ifdef AMREX_USE_FLOAT
1955  const amrex::Real eps = amrex::Real(1e-8);
1956 #else
1957  const amrex::Real eps = amrex::Real(1e-15);
1958 #endif
1959  const amrex::Real WSMIN = amrex::Real(0.1); // minimum wind speed
1960 };
1961 
1962 
1963 /**
1964  * Donelan flux formulation
1965  */
1967 {
1969 
1970  AMREX_GPU_DEVICE
1971  AMREX_FORCE_INLINE
1972  amrex::Real
1973  compute_q_flux (const int& /*i*/,
1974  const int& /*j*/,
1975  const int& /*k*/,
1976  const amrex::Array4<const amrex::Real>& /*cons_arr*/,
1977  const amrex::Array4<const amrex::Real>& /*velx_arr*/,
1978  const amrex::Array4<const amrex::Real>& /*vely_arr*/,
1979  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
1980  const amrex::Array4<const amrex::Real>& /*qm_arr*/,
1981  const amrex::Array4<const amrex::Real>& /*u_star_arr*/,
1982  const amrex::Array4<const amrex::Real>& /*q_star_arr*/,
1983  const amrex::Array4<const amrex::Real>& /*q_surf_arr*/) const
1984  {
1985  // NOTE: this is rho*<q'w'> = -K dqdz
1986  amrex::Real moflux = zero;
1987 
1988  return moflux;
1989  }
1990 
1991  AMREX_GPU_DEVICE
1992  AMREX_FORCE_INLINE
1993  amrex::Real
1994  compute_t_flux (const int& i,
1995  const int& j,
1996  const int& k,
1997  const amrex::Array4<const amrex::Real>& cons_arr,
1998  const amrex::Array4<const amrex::Real>& /*velx_arr*/,
1999  const amrex::Array4<const amrex::Real>& /*vely_arr*/,
2000  const amrex::Array4<const amrex::Real>& umm_arr,
2001  const amrex::Array4<const amrex::Real>& tm_arr,
2002  const amrex::Array4<const amrex::Real>& /*u_star_arr*/,
2003  const amrex::Array4<const amrex::Real>& /*t_star_arr*/,
2004  const amrex::Array4<const amrex::Real>& t_surf_arr) const
2005  {
2006  amrex::Real Ch = amrex::Real(0.0012);
2007  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
2008 
2009  amrex::Real theta_surf = t_surf_arr(i,j,0);
2010  amrex::Real theta_mean = tm_arr(i,j,0);
2011  amrex::Real wsp_mean = umm_arr(i,j,0);
2012 
2013  // NOTE: this is rho*<T'w'> = -K dTdz
2014  amrex::Real moflux = -rho * Ch * wsp_mean * (theta_mean - theta_surf);
2015 
2016  return moflux;
2017  }
2018 
2019  AMREX_GPU_DEVICE
2020  AMREX_FORCE_INLINE
2021  amrex::Real
2022  compute_u_flux (const int& i,
2023  const int& j,
2024  const int& k,
2025  const amrex::Array4<const amrex::Real>& cons_arr,
2026  const amrex::Array4<const amrex::Real>& velx_arr,
2027  const amrex::Array4<const amrex::Real>& vely_arr,
2028  const amrex::Array4<const amrex::Real>& umm_arr,
2029  const amrex::Array4<const amrex::Real>& /*um_arr*/,
2030  const amrex::Array4<const amrex::Real>& /*u_star_arr*/) const
2031  {
2032  amrex::Real velx = velx_arr(i,j,k);
2033  amrex::Real vely = fourth * ( vely_arr(i ,j,k) + vely_arr(i ,j+1,k)
2034  + vely_arr(i-1,j,k) + vely_arr(i-1,j+1,k) );
2035  amrex::Real rho = myhalf * ( cons_arr(i-1,j,k,Rho_comp) + cons_arr(i,j,k,Rho_comp) );
2036 
2037  amrex::Real Cd = amrex::Real(0.001);
2038  const amrex::Real c = amrex::Real(7e-5);
2039  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2040  amrex::Real wsp_mean = myhalf * ( umm_arr(i-1,j,0) + umm_arr(i,j,0) );
2041  if (wsp_mean <= amrex::Real(5.0)) {
2042  Cd = amrex::Real(0.001);
2043  } else if (wsp_mean < amrex::Real(25.0) && wsp_mean > amrex::Real(5.0)) {
2044  Cd = amrex::Real(0.001) + c * (wsp_mean - amrex::Real(5.0));
2045  } else {
2046  Cd = amrex::Real(0.0024);
2047  }
2048 
2049  // NOTE: this is rho*<u'w'> = -K dudz
2050  amrex::Real stressx = -rho * Cd * velx * wsp;
2051 
2052  return stressx;
2053  }
2054 
2055  AMREX_GPU_DEVICE
2056  AMREX_FORCE_INLINE
2057  amrex::Real
2058  compute_v_flux (const int& i,
2059  const int& j,
2060  const int& k,
2061  const amrex::Array4<const amrex::Real>& cons_arr,
2062  const amrex::Array4<const amrex::Real>& velx_arr,
2063  const amrex::Array4<const amrex::Real>& vely_arr,
2064  const amrex::Array4<const amrex::Real>& umm_arr,
2065  const amrex::Array4<const amrex::Real>& /*vm_arr*/,
2066  const amrex::Array4<const amrex::Real>& /*u_star_arr*/) const
2067  {
2068  amrex::Real velx = fourth * ( velx_arr(i,j ,k) + velx_arr(i+1,j ,k)
2069  + velx_arr(i,j-1,k) + velx_arr(i+1,j-1,k) );
2070  amrex::Real vely = vely_arr(i,j,k);
2071  amrex::Real rho = myhalf * ( cons_arr(i,j-1,k,Rho_comp) + cons_arr(i,j,k,Rho_comp) );
2072 
2073  amrex::Real Cd = amrex::Real(0.001);
2074  const amrex::Real c = amrex::Real(7e-5);
2075  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2076  amrex::Real wsp_mean = myhalf * ( umm_arr(i,j-1,0) + umm_arr(i,j,0) );
2077  if (wsp_mean <= amrex::Real(5.0)) {
2078  Cd = amrex::Real(0.001);
2079  } else if (wsp_mean < amrex::Real(25.0) && wsp_mean > amrex::Real(5.0)) {
2080  Cd = amrex::Real(0.001) + c * (wsp_mean - amrex::Real(5.0));
2081  } else {
2082  Cd = amrex::Real(0.0024);
2083  }
2084 
2085  // NOTE: this is rho*<v'w'> = -K dvdz
2086  amrex::Real stressy = -rho * Cd * vely * wsp;
2087 
2088  return stressy;
2089  }
2090 
2091 private:
2092 
2093 };
2094 
2095 
2096 /**
2097  * Custom flux formulation
2098  */
2100 {
2101  custom_flux (bool specified_rho_surf)
2102  : fluxes_include_rho(specified_rho_surf)
2103  {}
2104 
2105  AMREX_GPU_DEVICE
2106  AMREX_FORCE_INLINE
2107  amrex::Real
2108  compute_q_flux (const int& i,
2109  const int& j,
2110  const int& k,
2111  const amrex::Array4<const amrex::Real>& cons_arr,
2112  const amrex::Array4<const amrex::Real>& /*velx_arr*/,
2113  const amrex::Array4<const amrex::Real>& /*vely_arr*/,
2114  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2115  const amrex::Array4<const amrex::Real>& /*qm_arr*/,
2116  const amrex::Array4<const amrex::Real>& /*u_star_arr*/,
2117  const amrex::Array4<const amrex::Real>& q_star_arr,
2118  const amrex::Array4<const amrex::Real>& /*q_surf_arr*/) const
2119  {
2120  amrex::Real rho = (fluxes_include_rho) ? one : cons_arr(i,j,k,Rho_comp);
2121  amrex::Real qstar = q_star_arr(i,j,0);
2122 
2123  // NOTE: this is rho*<q'w'> = -K dqdz
2124  amrex::Real moflux = (std::abs(qstar) > eps) ? rho * qstar : zero;
2125 
2126  return moflux;
2127  }
2128 
2129  AMREX_GPU_DEVICE
2130  AMREX_FORCE_INLINE
2131  amrex::Real
2132  compute_t_flux (const int& i,
2133  const int& j,
2134  const int& k,
2135  const amrex::Array4<const amrex::Real>& cons_arr,
2136  const amrex::Array4<const amrex::Real>& /*velx_arr*/,
2137  const amrex::Array4<const amrex::Real>& /*vely_arr*/,
2138  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2139  const amrex::Array4<const amrex::Real>& /*tm_arr*/,
2140  const amrex::Array4<const amrex::Real>& /*u_star_arr*/,
2141  const amrex::Array4<const amrex::Real>& t_star_arr,
2142  const amrex::Array4<const amrex::Real>& /*t_surf_arr*/) const
2143  {
2144  amrex::Real rho = (fluxes_include_rho) ? one : cons_arr(i,j,k,Rho_comp);
2145  amrex::Real tstar = t_star_arr(i,j,0);
2146 
2147  // NOTE: this is rho*<T'w'> = -K dTdz
2148  amrex::Real moflux = (std::abs(tstar) > eps) ? rho * tstar : zero;
2149 
2150  return moflux;
2151  }
2152 
2153  AMREX_GPU_DEVICE
2154  AMREX_FORCE_INLINE
2155  amrex::Real
2156  compute_u_flux (const int& i,
2157  const int& j,
2158  const int& k,
2159  const amrex::Array4<const amrex::Real>& cons_arr,
2160  const amrex::Array4<const amrex::Real>& velx_arr,
2161  const amrex::Array4<const amrex::Real>& vely_arr,
2162  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2163  const amrex::Array4<const amrex::Real>& /*um_arr*/,
2164  const amrex::Array4<const amrex::Real>& u_star_arr) const
2165  {
2166  amrex::Real velx = velx_arr(i,j,k);
2167  amrex::Real vely = fourth * ( vely_arr(i ,j,k) + vely_arr(i ,j+1,k)
2168  + vely_arr(i-1,j,k) + vely_arr(i-1,j+1,k) );
2169  amrex::Real rho = (fluxes_include_rho) ? one : myhalf * ( cons_arr(i-1,j,k,Rho_comp) + cons_arr(i,j,k,Rho_comp) );
2170 
2171  amrex::Real ustar = myhalf * ( u_star_arr(i-1,j,0) + u_star_arr(i,j,0) );
2172  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2173 
2174  // NOTE: this is rho*<u'w'> = -K dudz
2175  amrex::Real stressx = -rho * ustar * ustar * velx / wsp;
2176 
2177  return stressx;
2178  }
2179 
2180  AMREX_GPU_DEVICE
2181  AMREX_FORCE_INLINE
2182  amrex::Real
2183  compute_v_flux (const int& i,
2184  const int& j,
2185  const int& k,
2186  const amrex::Array4<const amrex::Real>& cons_arr,
2187  const amrex::Array4<const amrex::Real>& velx_arr,
2188  const amrex::Array4<const amrex::Real>& vely_arr,
2189  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2190  const amrex::Array4<const amrex::Real>& /*vm_arr*/,
2191  const amrex::Array4<const amrex::Real>& u_star_arr) const
2192  {
2193  amrex::Real velx = fourth * ( velx_arr(i,j ,k) + velx_arr(i+1,j ,k)
2194  + velx_arr(i,j-1,k) + velx_arr(i+1,j-1,k) );
2195  amrex::Real vely = vely_arr(i,j,k);
2196  amrex::Real rho = (fluxes_include_rho) ? one : myhalf * ( cons_arr(i,j-1,k,Rho_comp) + cons_arr(i,j,k,Rho_comp) );
2197 
2198  amrex::Real ustar = myhalf * ( u_star_arr(i,j-1,0) + u_star_arr(i,j,0) );
2199  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2200 
2201  // NOTE: this is rho*<v'w'> = -K dvdz
2202  amrex::Real stressy = -rho * ustar * ustar * vely / wsp;
2203 
2204  return stressy;
2205  }
2206 
2207 private:
2208 #ifdef AMREX_USE_FLOAT
2209  const amrex::Real eps = amrex::Real(1e-8);
2210 #else
2211  const amrex::Real eps = amrex::Real(1e-15);
2212 #endif
2213  const bool fluxes_include_rho{false};
2214 };
2215 
2216 
2217 /**
2218  * Bulk coefficient flux formulation
2219  */
2221 {
2223  amrex::Real m_Ch,
2224  amrex::Real m_Cq)
2225  {
2226  mdata.Cd = m_Cd;
2227  mdata.Ch = m_Ch;
2228  mdata.Cq = m_Cq;
2229  }
2230 
2231  AMREX_GPU_DEVICE
2232  AMREX_FORCE_INLINE
2233  amrex::Real
2234  compute_q_flux (const int& i,
2235  const int& j,
2236  const int& k,
2237  const amrex::Array4<const amrex::Real>& cons_arr,
2238  const amrex::Array4<const amrex::Real>& velx_arr,
2239  const amrex::Array4<const amrex::Real>& vely_arr,
2240  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2241  const amrex::Array4<const amrex::Real>& /*qm_arr*/,
2242  const amrex::Array4<const amrex::Real>& /*u_star_arr*/,
2243  const amrex::Array4<const amrex::Real>& /*q_star_arr*/,
2244  const amrex::Array4<const amrex::Real>& q_surf_arr) const
2245  {
2246  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
2247  amrex::Real qv = cons_arr(i,j,k,RhoQ1_comp)/cons_arr(i,j,k,Rho_comp);
2248  amrex::Real qvsurf = q_surf_arr(i,j,0);
2249  amrex::Real velx = myhalf * ( velx_arr(i,j,k) + velx_arr(i+1,j ,k) );
2250  amrex::Real vely = myhalf * ( vely_arr(i,j,k) + vely_arr(i ,j+1,k) );
2251  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2252 
2253  // NOTE: this is rho*<q'w'> = -K dqdz
2254  amrex::Real moflux = rho * mdata.Cq * wsp * (qvsurf - qv);
2255 
2256  return moflux;
2257  }
2258 
2259  AMREX_GPU_DEVICE
2260  AMREX_FORCE_INLINE
2261  amrex::Real
2262  compute_t_flux (const int& i,
2263  const int& j,
2264  const int& k,
2265  const amrex::Array4<const amrex::Real>& cons_arr,
2266  const amrex::Array4<const amrex::Real>& velx_arr,
2267  const amrex::Array4<const amrex::Real>& vely_arr,
2268  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2269  const amrex::Array4<const amrex::Real>& /*tm_arr*/,
2270  const amrex::Array4<const amrex::Real>& /*u_star_arr*/,
2271  const amrex::Array4<const amrex::Real>& /*t_star_arr*/,
2272  const amrex::Array4<const amrex::Real>& t_surf_arr) const
2273  {
2274  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
2275  amrex::Real th = cons_arr(i,j,k,RhoTheta_comp)/cons_arr(i,j,k,Rho_comp);
2276  amrex::Real thsurf = t_surf_arr(i,j,0);
2277  amrex::Real velx = myhalf * ( velx_arr(i,j,k) + velx_arr(i+1,j ,k) );
2278  amrex::Real vely = myhalf * ( vely_arr(i,j,k) + vely_arr(i ,j+1,k) );
2279  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2280 
2281  // NOTE: this is rho*<T'w'> = -K dTdz
2282  amrex::Real moflux = rho * mdata.Ch * wsp * (thsurf - th);
2283 
2284  return moflux;
2285  }
2286 
2287  AMREX_GPU_DEVICE
2288  AMREX_FORCE_INLINE
2289  amrex::Real
2290  compute_u_flux (const int& i,
2291  const int& j,
2292  const int& k,
2293  const amrex::Array4<const amrex::Real>& cons_arr,
2294  const amrex::Array4<const amrex::Real>& velx_arr,
2295  const amrex::Array4<const amrex::Real>& vely_arr,
2296  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2297  const amrex::Array4<const amrex::Real>& /*um_arr*/,
2298  const amrex::Array4<const amrex::Real>& /*u_star_arr*/) const
2299  {
2300  amrex::Real rho = myhalf * ( cons_arr(i-1,j,k,Rho_comp) + cons_arr(i,j,k,Rho_comp) );
2301  amrex::Real velx = velx_arr(i,j,k);
2302  amrex::Real vely = fourth * ( vely_arr(i ,j,k) + vely_arr(i ,j+1,k)
2303  + vely_arr(i-1,j,k) + vely_arr(i-1,j+1,k) );
2304  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2305 
2306  // NOTE: this is rho*<u'w'> = -K dudz
2307  // NOTE: tau_tot = rho * Cd * wsp^2, multiply by u/wsp to get tau_13
2308  amrex::Real stressx = -rho * mdata.Cd * wsp * velx;
2309 
2310  return stressx;
2311  }
2312 
2313  AMREX_GPU_DEVICE
2314  AMREX_FORCE_INLINE
2315  amrex::Real
2316  compute_v_flux (const int& i,
2317  const int& j,
2318  const int& k,
2319  const amrex::Array4<const amrex::Real>& cons_arr,
2320  const amrex::Array4<const amrex::Real>& velx_arr,
2321  const amrex::Array4<const amrex::Real>& vely_arr,
2322  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2323  const amrex::Array4<const amrex::Real>& /*vm_arr*/,
2324  const amrex::Array4<const amrex::Real>& /*u_star_arr*/) const
2325  {
2326  amrex::Real rho = myhalf * ( cons_arr(i,j-1,k,Rho_comp) + cons_arr(i,j,k,Rho_comp) );
2327  amrex::Real velx = fourth * ( velx_arr(i,j ,k) + velx_arr(i+1,j ,k)
2328  + velx_arr(i,j-1,k) + velx_arr(i+1,j-1,k) );
2329  amrex::Real vely = vely_arr(i,j,k);
2330  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2331 
2332  // NOTE: this is rho*<v'w'> = -K dvdz
2333  // NOTE: tau_tot = rho * Cd * wsp^2, multiply by v/wsp to get tau_13
2334  amrex::Real stressy = -rho * mdata.Cd * wsp * vely;
2335 
2336  return stressy;
2337  }
2338 
2339 private:
2341 };
2342 
2343 
2344 /**
2345  * RICO flux formulation
2346  */
2348 {
2349  rico_flux (amrex::Real l_theta_z0, amrex::Real l_qsat_z0)
2350  : theta_z0{l_theta_z0}, qsat_z0{l_qsat_z0} {}
2351 
2352 
2353  AMREX_GPU_DEVICE
2354  AMREX_FORCE_INLINE
2355  amrex::Real
2356  compute_q_flux (const int& i,
2357  const int& j,
2358  const int& k,
2359  const amrex::Array4<const amrex::Real>& cons_arr,
2360  const amrex::Array4<const amrex::Real>& velx_arr,
2361  const amrex::Array4<const amrex::Real>& vely_arr,
2362  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2363  const amrex::Array4<const amrex::Real>& /*qm_arr*/,
2364  const amrex::Array4<const amrex::Real>& /*u_star_arr*/,
2365  const amrex::Array4<const amrex::Real>& q_star_arr,
2366  const amrex::Array4<const amrex::Real>& /*t_surf_arr*/) const
2367  {
2368  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
2369  amrex::Real qstar = q_star_arr(i,j,0);
2370  amrex::Real q = cons_arr(i, j, k, RhoQ1_comp) / rho;
2371 
2372  amrex::Real velx = myhalf * (velx_arr(i,j,k) + velx_arr(i+1,j,k));
2373  amrex::Real vely = myhalf * (vely_arr(i,j,k) + vely_arr(i,j+1,k));
2374  amrex::Real wsp = std::sqrt(velx*velx + vely*vely);
2375 
2376  // NOTE: this is rho*<q'w'> = -K dqdz
2377  amrex::Real moflux = (std::abs(qstar) > eps) ? - rho * qstar * wsp * (q - qsat_z0) : zero;
2378 
2379  return moflux;
2380  }
2381 
2382  AMREX_GPU_DEVICE
2383  AMREX_FORCE_INLINE
2384  amrex::Real
2385  compute_t_flux (const int& i,
2386  const int& j,
2387  const int& k,
2388  const amrex::Array4<const amrex::Real>& cons_arr,
2389  const amrex::Array4<const amrex::Real>& velx_arr,
2390  const amrex::Array4<const amrex::Real>& vely_arr,
2391  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2392  const amrex::Array4<const amrex::Real>& /*tm_arr*/,
2393  const amrex::Array4<const amrex::Real>& /*u_star_arr*/,
2394  const amrex::Array4<const amrex::Real>& t_star_arr,
2395  const amrex::Array4<const amrex::Real>& /*t_surf_arr*/) const
2396  {
2397  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
2398  amrex::Real tstar = t_star_arr(i, j, 0);
2399  amrex::Real theta = cons_arr(i, j, k, RhoTheta_comp) / rho;
2400 
2401  amrex::Real velx = myhalf * (velx_arr(i,j,k) + velx_arr(i+1,j,k));
2402  amrex::Real vely = myhalf * (vely_arr(i,j,k) + vely_arr(i,j+1,k));
2403  amrex::Real wsp = std::sqrt(velx*velx + vely*vely);
2404 
2405  // NOTE: this is rho*<T'w'> = -K dTdz
2406  amrex::Real moflux = (std::abs(tstar) > eps) ? - rho * tstar * wsp * (theta - theta_z0) : zero;
2407 
2408  return moflux;
2409  }
2410 
2411  AMREX_GPU_DEVICE
2412  AMREX_FORCE_INLINE
2413  amrex::Real
2414  compute_u_flux (const int& i,
2415  const int& j,
2416  const int& k,
2417  const amrex::Array4<const amrex::Real>& cons_arr,
2418  const amrex::Array4<const amrex::Real>& velx_arr,
2419  const amrex::Array4<const amrex::Real>& vely_arr,
2420  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2421  const amrex::Array4<const amrex::Real>& /*um_arr*/,
2422  const amrex::Array4<const amrex::Real>& u_star_arr) const
2423  {
2424  amrex::Real velx = velx_arr(i,j,k);
2425  amrex::Real vely = fourth * ( vely_arr(i ,j,k) + vely_arr(i ,j+1,k)
2426  + vely_arr(i-1,j,k) + vely_arr(i-1,j+1,k) );
2427  amrex::Real rho = myhalf * ( cons_arr(i-1,j,k,Rho_comp) + cons_arr(i,j,k,Rho_comp) );
2428 
2429  amrex::Real ustar = myhalf * ( u_star_arr(i-1,j,0) + u_star_arr(i,j,0) );
2430  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2431 
2432  // NOTE: this is rho*<u'w'> = -K dudz
2433  amrex::Real stressx = -rho * ustar * wsp * velx;
2434 
2435  return stressx;
2436  }
2437 
2438  AMREX_GPU_DEVICE
2439  AMREX_FORCE_INLINE
2440  amrex::Real
2441  compute_v_flux (const int& i,
2442  const int& j,
2443  const int& k,
2444  const amrex::Array4<const amrex::Real>& cons_arr,
2445  const amrex::Array4<const amrex::Real>& velx_arr,
2446  const amrex::Array4<const amrex::Real>& vely_arr,
2447  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2448  const amrex::Array4<const amrex::Real>& /*vm_arr*/,
2449  const amrex::Array4<const amrex::Real>& u_star_arr) const
2450  {
2451  amrex::Real velx = fourth * ( velx_arr(i,j ,k) + velx_arr(i+1,j ,k)
2452  + velx_arr(i,j-1,k) + velx_arr(i+1,j-1,k) );
2453  amrex::Real vely = vely_arr(i,j,k);
2454  amrex::Real rho = myhalf * ( cons_arr(i,j-1,k,Rho_comp) + cons_arr(i,j,k,Rho_comp) );
2455 
2456  amrex::Real ustar = myhalf * ( u_star_arr(i,j-1,0) + u_star_arr(i,j,0) );
2457  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2458 
2459  // NOTE: this is rho*<v'w'> = -K dvdz
2460  amrex::Real stressy = -rho * ustar * wsp * vely;
2461 
2462  return stressy;
2463  }
2464 
2465 private:
2466 #ifdef AMREX_USE_FLOAT
2467  const amrex::Real eps = amrex::Real(1e-8);
2468 #else
2469  const amrex::Real eps = amrex::Real(1e-15);
2470 #endif
2473 };
2474 
2475 
2476 /**
2477  * Rotate flux formulation
2478  */
2480 {
2482 
2483  AMREX_GPU_DEVICE
2484  AMREX_FORCE_INLINE
2485  amrex::Real
2486  compute_q_flux (const int& i,
2487  const int& j,
2488  const int& k,
2489  const amrex::Array4<const amrex::Real>& cons_arr,
2490  const amrex::Array4<const amrex::Real>& /*velx_arr*/,
2491  const amrex::Array4<const amrex::Real>& /*vely_arr*/,
2492  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2493  const amrex::Array4<const amrex::Real>& qvm_arr,
2494  const amrex::Array4<const amrex::Real>& /*u_star_arr*/,
2495  const amrex::Array4<const amrex::Real>& q_star_arr,
2496  const amrex::Array4<const amrex::Real>& q_surf_arr) const
2497  {
2498  // NOTE: this is the total stress
2499  amrex::Real qv_mean = qvm_arr(i,j,0);
2500  amrex::Real qv_surf = q_surf_arr(i,j,0);
2501  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
2502  amrex::Real qstar = q_star_arr(i,j,0);
2503  amrex::Real moflux = (std::abs(qstar) > eps) ? -rho * qstar * (qv_mean-qv_surf): zero;
2504 
2505  return moflux;
2506  }
2507 
2508  AMREX_GPU_DEVICE
2509  AMREX_FORCE_INLINE
2510  amrex::Real
2511  compute_t_flux (const int& i,
2512  const int& j,
2513  const int& k,
2514  const amrex::Array4<const amrex::Real>& cons_arr,
2515  const amrex::Array4<const amrex::Real>& /*velx_arr*/,
2516  const amrex::Array4<const amrex::Real>& /*vely_arr*/,
2517  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2518  const amrex::Array4<const amrex::Real>& tm_arr,
2519  const amrex::Array4<const amrex::Real>& /*u_star_arr*/,
2520  const amrex::Array4<const amrex::Real>& t_star_arr,
2521  const amrex::Array4<const amrex::Real>& t_surf_arr) const
2522  {
2523  // NOTE: this is the total stress
2524  amrex::Real theta_mean = tm_arr(i,j,0);
2525  amrex::Real theta_surf = t_surf_arr(i,j,0);
2526  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
2527  amrex::Real tstar = t_star_arr(i,j,0);
2528  amrex::Real moflux = (std::abs(tstar) > eps) ? -rho * tstar * (theta_mean-theta_surf) : zero;
2529 
2530  return moflux;
2531  }
2532 
2533  AMREX_GPU_DEVICE
2534  AMREX_FORCE_INLINE
2535  amrex::Real
2536  compute_u_flux (const int& i,
2537  const int& j,
2538  const int& k,
2539  const amrex::Array4<const amrex::Real>& cons_arr,
2540  const amrex::Array4<const amrex::Real>& /*velx_arr*/,
2541  const amrex::Array4<const amrex::Real>& /*vely_arr*/,
2542  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2543  const amrex::Array4<const amrex::Real>& /*um_arr*/,
2544  const amrex::Array4<const amrex::Real>& u_star_arr) const
2545  {
2546  // NOTE: this is the total stress
2547  amrex::Real rho = myhalf *( cons_arr(i-1,j,k,Rho_comp) + cons_arr(i ,j,k,Rho_comp) );
2548  amrex::Real ustar = myhalf * ( u_star_arr(i-1,j,0) + u_star_arr(i,j,0) );
2549  amrex::Real stressx = -rho * ustar * ustar;
2550 
2551  return stressx;
2552  }
2553 
2554  AMREX_GPU_DEVICE
2555  AMREX_FORCE_INLINE
2556  amrex::Real
2557  compute_v_flux (const int& /*i*/,
2558  const int& /*j*/,
2559  const int& /*k*/,
2560  const amrex::Array4<const amrex::Real>& /*cons_arr*/,
2561  const amrex::Array4<const amrex::Real>& /*velx_arr*/,
2562  const amrex::Array4<const amrex::Real>& /*vely_arr*/,
2563  const amrex::Array4<const amrex::Real>& /*umm_arr*/,
2564  const amrex::Array4<const amrex::Real>& /*vm_arr*/,
2565  const amrex::Array4<const amrex::Real>& /*u_star_arr*/) const
2566  {
2567  // NOTE: this is the total stress
2568  amrex::Real stressy = zero;
2569 
2570  return stressy;
2571  }
2572 
2573 private:
2574 #ifdef AMREX_USE_FLOAT
2575  const amrex::Real eps = amrex::Real(1e-8);
2576 #else
2577  const amrex::Real eps = amrex::Real(1e-15);
2578 #endif
2579 };
2580 #endif
constexpr amrex::Real three
Definition: ERF_Constants.H:11
constexpr amrex::Real KAPPA
Definition: ERF_Constants.H:52
constexpr amrex::Real two
Definition: ERF_Constants.H:10
constexpr amrex::Real bogus_large_value
Definition: ERF_Constants.H:26
constexpr amrex::Real one
Definition: ERF_Constants.H:9
constexpr amrex::Real fourth
Definition: ERF_Constants.H:14
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13
constexpr amrex::Real PI
Definition: ERF_Constants.H:37
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:53
constexpr amrex::Real PIoTwo
Definition: ERF_Constants.H:38
@ num
Definition: ERF_DataStruct.H:24
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
Real z0
Definition: ERF_InitCustomPertVels_ScalarAdvDiff.H:8
rho
Definition: ERF_InitCustomPert_Bubble.H:106
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Donelan_roughness(amrex::Real ustar)
Definition: ERF_MOSTRoughness.H:29
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real COARE3_roughness(amrex::Real zref, amrex::Real umm, amrex::Real ustar)
Definition: ERF_MOSTRoughness.H:9
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real air_viscosity(amrex::Real T_degK)
Definition: ERF_MOSTStress.H:129
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real calc_wstar(const amrex::Real &ust, const amrex::Real &tst, const amrex::Real &qst, const amrex::Real &pblh, const amrex::Real &th, const amrex::Real &thv, const amrex::Real &qv=amrex::Real(0))
Definition: ERF_Wstar.H:13
@ Mom_v
Definition: ERF_IndexDefines.H:209
@ theta
Definition: ERF_MM5.H:20
@ qv
Definition: ERF_Kessler.H:29
@ q
Definition: ERF_WSM6.H:169
@ den
Definition: ERF_AdvanceWSM6.cpp:109
Definition: ERF_MOSTStress.H:189
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:274
most_data mdata
Definition: ERF_MOSTStress.H:267
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &) const
Definition: ERF_MOSTStress.H:204
const amrex::Real tol_z
Definition: ERF_MOSTStress.H:272
similarity_funs sfuns
Definition: ERF_MOSTStress.H:268
adiabatic_charnock(amrex::Real Tflux, amrex::Real Qvflux, amrex::Real cnk_a, bool cnk_visc)
Definition: ERF_MOSTStress.H:190
Definition: ERF_MOSTStress.H:367
similarity_funs sfuns
Definition: ERF_MOSTStress.H:427
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:429
most_data mdata
Definition: ERF_MOSTStress.H:426
adiabatic_donelan(amrex::Real Tflux, amrex::Real Qvflux)
Definition: ERF_MOSTStress.H:368
const amrex::Real tol
Definition: ERF_MOSTStress.H:428
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &) const
Definition: ERF_MOSTStress.H:378
Definition: ERF_MOSTStress.H:282
similarity_funs sfuns
Definition: ERF_MOSTStress.H:353
const amrex::Real tol_z
Definition: ERF_MOSTStress.H:357
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:359
adiabatic_mod_charnock(amrex::Real Tflux, amrex::Real Qvflux, amrex::Real depth)
Definition: ERF_MOSTStress.H:283
most_data mdata
Definition: ERF_MOSTStress.H:352
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &) const
Definition: ERF_MOSTStress.H:296
Definition: ERF_MOSTStress.H:437
const amrex::Real eps
Definition: ERF_MOSTStress.H:505
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &Hwave_arr, const amrex::Array4< amrex::Real > &Lwave_arr, const amrex::Array4< amrex::Real > &eta_arr) const
Definition: ERF_MOSTStress.H:448
const amrex::Real z0_eps
Definition: ERF_MOSTStress.H:507
most_data mdata
Definition: ERF_MOSTStress.H:499
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:509
similarity_funs sfuns
Definition: ERF_MOSTStress.H:500
const amrex::Real tol
Definition: ERF_MOSTStress.H:501
const amrex::Real z0_max
Definition: ERF_MOSTStress.H:508
adiabatic_wave_coupled(amrex::Real Tflux, amrex::Real Qvflux)
Definition: ERF_MOSTStress.H:438
Definition: ERF_MOSTStress.H:140
adiabatic(amrex::Real Tflux, amrex::Real Qvflux)
Definition: ERF_MOSTStress.H:141
similarity_funs sfuns
Definition: ERF_MOSTStress.H:181
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< const amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &) const
Definition: ERF_MOSTStress.H:151
most_data mdata
Definition: ERF_MOSTStress.H:180
Definition: ERF_MOSTStress.H:2221
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_u_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &) const
Definition: ERF_MOSTStress.H:2290
bulk_coeff_flux(amrex::Real m_Cd, amrex::Real m_Ch, amrex::Real m_Cq)
Definition: ERF_MOSTStress.H:2222
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_q_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &q_surf_arr) const
Definition: ERF_MOSTStress.H:2234
most_data mdata
Definition: ERF_MOSTStress.H:2340
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_t_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &t_surf_arr) const
Definition: ERF_MOSTStress.H:2262
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_v_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &) const
Definition: ERF_MOSTStress.H:2316
Definition: ERF_MOSTStress.H:2100
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_u_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &u_star_arr) const
Definition: ERF_MOSTStress.H:2156
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_q_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &q_star_arr, const amrex::Array4< const amrex::Real > &) const
Definition: ERF_MOSTStress.H:2108
custom_flux(bool specified_rho_surf)
Definition: ERF_MOSTStress.H:2101
const bool fluxes_include_rho
Definition: ERF_MOSTStress.H:2213
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_t_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &t_star_arr, const amrex::Array4< const amrex::Real > &) const
Definition: ERF_MOSTStress.H:2132
const amrex::Real eps
Definition: ERF_MOSTStress.H:2211
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_v_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &u_star_arr) const
Definition: ERF_MOSTStress.H:2183
Definition: ERF_MOSTStress.H:1967
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_u_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &) const
Definition: ERF_MOSTStress.H:2022
donelan_flux()
Definition: ERF_MOSTStress.H:1968
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_v_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &) const
Definition: ERF_MOSTStress.H:2058
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_t_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &t_surf_arr) const
Definition: ERF_MOSTStress.H:1994
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_q_flux(const int &, const int &, const int &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &) const
Definition: ERF_MOSTStress.H:1973
Definition: ERF_MOSTStress.H:1800
moeng_flux()
Definition: ERF_MOSTStress.H:1801
const amrex::Real eps
Definition: ERF_MOSTStress.H:1957
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_u_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &um_arr, const amrex::Array4< const amrex::Real > &u_star_arr) const
Definition: ERF_MOSTStress.H:1882
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:1959
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_t_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &u_star_arr, const amrex::Array4< const amrex::Real > &t_star_arr, const amrex::Array4< const amrex::Real > &t_surf_arr) const
Definition: ERF_MOSTStress.H:1844
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_q_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< const amrex::Real > &u_star_arr, const amrex::Array4< const amrex::Real > &q_star_arr, const amrex::Array4< const amrex::Real > &q_surf_arr) const
Definition: ERF_MOSTStress.H:1806
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_v_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &vm_arr, const amrex::Array4< const amrex::Real > &u_star_arr) const
Definition: ERF_MOSTStress.H:1919
Definition: ERF_MOSTStress.H:13
amrex::Real surf_moist_flux
Moisture flux.
Definition: ERF_MOSTStress.H:19
amrex::Real Cnk_b2
Modified Charnock Eq (4) https://doi.org/amrex::Real(10.1175)/JAMC-D-17-amrex::Real(0137....
Definition: ERF_MOSTStress.H:23
amrex::Real Cnk_b
Definition: ERF_MOSTStress.H:25
amrex::Real Ch
Definition: ERF_MOSTStress.H:29
amrex::Real Cnk_d
Modified Charnock Eq (4) https://doi.org/amrex::Real(10.1175)/JAMC-D-17-amrex::Real(0137....
Definition: ERF_MOSTStress.H:24
amrex::Real kappa
von Karman constant
Definition: ERF_MOSTStress.H:16
amrex::Real gravity
Acceleration due to gravity (m/s^2)
Definition: ERF_MOSTStress.H:17
amrex::Real Cnk_a
Standard Charnock constant https://doi.org/amrex::Real(10.1175)/JAMC-D-17-amrex::Real(0137....
Definition: ERF_MOSTStress.H:21
amrex::Real Cd
Definition: ERF_MOSTStress.H:28
amrex::Real Cq
Definition: ERF_MOSTStress.H:30
const amrex::Real Bjr_beta
Definition: ERF_MOSTStress.H:32
amrex::Real Cnk_b1
Modified Charnock Eq (4) https://doi.org/amrex::Real(10.1175)/JAMC-D-17-amrex::Real(0137....
Definition: ERF_MOSTStress.H:22
amrex::Real z0_const
Roughness height – default constant value(m)
Definition: ERF_MOSTStress.H:15
bool visc
Use viscous Charnock formulation.
Definition: ERF_MOSTStress.H:26
amrex::Real surf_temp_flux
Heat flux TODO: decide whether this is <θ'w'> or <θv'w'> under moist conditions.
Definition: ERF_MOSTStress.H:18
Definition: ERF_MOSTStress.H:2348
rico_flux(amrex::Real l_theta_z0, amrex::Real l_qsat_z0)
Definition: ERF_MOSTStress.H:2349
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_q_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &q_star_arr, const amrex::Array4< const amrex::Real > &) const
Definition: ERF_MOSTStress.H:2356
amrex::Real qsat_z0
Definition: ERF_MOSTStress.H:2472
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_t_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &t_star_arr, const amrex::Array4< const amrex::Real > &) const
Definition: ERF_MOSTStress.H:2385
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_u_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &u_star_arr) const
Definition: ERF_MOSTStress.H:2414
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_v_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &u_star_arr) const
Definition: ERF_MOSTStress.H:2441
const amrex::Real eps
Definition: ERF_MOSTStress.H:2469
amrex::Real theta_z0
Definition: ERF_MOSTStress.H:2471
Definition: ERF_MOSTStress.H:2480
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_v_flux(const int &, const int &, const int &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &) const
Definition: ERF_MOSTStress.H:2557
rotate_flux()
Definition: ERF_MOSTStress.H:2481
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_u_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &u_star_arr) const
Definition: ERF_MOSTStress.H:2536
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_t_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &t_star_arr, const amrex::Array4< const amrex::Real > &t_surf_arr) const
Definition: ERF_MOSTStress.H:2511
const amrex::Real eps
Definition: ERF_MOSTStress.H:2577
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_q_flux(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &q_star_arr, const amrex::Array4< const amrex::Real > &q_surf_arr) const
Definition: ERF_MOSTStress.H:2486
Definition: ERF_MOSTStress.H:40
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real calc_psi_m(amrex::Real zeta) const
Definition: ERF_MOSTStress.H:90
amrex::Real beta_m
Constants from Dyer, BLM, 1974.
Definition: ERF_MOSTStress.H:115
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real calc_psi_h2(amrex::Real zeta) const
Definition: ERF_MOSTStress.H:67
amrex::Real beta_h
https://doi.org/amrex::Real(10.1007)/BF00240838
Definition: ERF_MOSTStress.H:116
amrex::Real gamma_h
Definition: ERF_MOSTStress.H:118
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real calc_psi_h(amrex::Real zeta) const
Definition: ERF_MOSTStress.H:104
amrex::Real gamma_m
Definition: ERF_MOSTStress.H:117
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real calc_psi_m2(amrex::Real zeta) const
Definition: ERF_MOSTStress.H:47
Definition: ERF_MOSTStress.H:622
const amrex::Real tol
Definition: ERF_MOSTStress.H:732
surface_flux_charnock(amrex::Real Tflux, amrex::Real Qvflux, amrex::Real cnk_a, bool cnk_visc, bool cons_qflux)
Definition: ERF_MOSTStress.H:623
similarity_funs sfuns
Definition: ERF_MOSTStress.H:731
most_data mdata
Definition: ERF_MOSTStress.H:729
bool spec_qflux
Definition: ERF_MOSTStress.H:730
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &tvm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &w_star_arr, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &t_surf_arr, const amrex::Array4< amrex::Real > &q_surf_arr, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &pblh_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &) const
Definition: ERF_MOSTStress.H:639
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:733
Definition: ERF_MOSTStress.H:852
bool spec_qflux
Definition: ERF_MOSTStress.H:949
const amrex::Real tol
Definition: ERF_MOSTStress.H:951
surface_flux_donelan(amrex::Real Tflux, amrex::Real Qvflux, bool cons_qflux)
Definition: ERF_MOSTStress.H:853
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:952
most_data mdata
Definition: ERF_MOSTStress.H:948
similarity_funs sfuns
Definition: ERF_MOSTStress.H:950
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &tvm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &w_star_arr, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &t_surf_arr, const amrex::Array4< amrex::Real > &q_surf_arr, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &pblh_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &) const
Definition: ERF_MOSTStress.H:865
Definition: ERF_MOSTStress.H:741
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &tvm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &w_star_arr, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &t_surf_arr, const amrex::Array4< amrex::Real > &q_surf_arr, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &pblh_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &) const
Definition: ERF_MOSTStress.H:757
surface_flux_mod_charnock(amrex::Real Tflux, amrex::Real Qvflux, amrex::Real depth, bool cons_qflux)
Definition: ERF_MOSTStress.H:742
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:844
most_data mdata
Definition: ERF_MOSTStress.H:840
bool spec_qflux
Definition: ERF_MOSTStress.H:841
const amrex::Real tol
Definition: ERF_MOSTStress.H:843
similarity_funs sfuns
Definition: ERF_MOSTStress.H:842
Definition: ERF_MOSTStress.H:960
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:1073
surface_flux_wave_coupled(amrex::Real Tflux, amrex::Real Qvflux, bool cons_qflux)
Definition: ERF_MOSTStress.H:961
const amrex::Real z0_max
Definition: ERF_MOSTStress.H:1072
const amrex::Real z0_eps
Definition: ERF_MOSTStress.H:1071
most_data mdata
Definition: ERF_MOSTStress.H:1062
similarity_funs sfuns
Definition: ERF_MOSTStress.H:1064
const amrex::Real tol
Definition: ERF_MOSTStress.H:1065
bool spec_qflux
Definition: ERF_MOSTStress.H:1063
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &tvm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &w_star_arr, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &t_surf_arr, const amrex::Array4< amrex::Real > &q_surf_arr, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &pblh_arr, const amrex::Array4< amrex::Real > &Hwave_arr, const amrex::Array4< amrex::Real > &Lwave_arr, const amrex::Array4< amrex::Real > &eta_arr) const
Definition: ERF_MOSTStress.H:973
const amrex::Real eps
Definition: ERF_MOSTStress.H:1069
Definition: ERF_MOSTStress.H:517
similarity_funs sfuns
Definition: ERF_MOSTStress.H:612
surface_flux(amrex::Real Tflux, amrex::Real Qvflux, bool cons_qflux)
Definition: ERF_MOSTStress.H:518
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< const amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &tvm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &w_star_arr, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &t_surf_arr, const amrex::Array4< amrex::Real > &q_surf_arr, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &pblh_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &) const
Definition: ERF_MOSTStress.H:530
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:614
most_data mdata
Definition: ERF_MOSTStress.H:610
const amrex::Real tol
Definition: ERF_MOSTStress.H:613
bool spec_qflux
Definition: ERF_MOSTStress.H:611
Definition: ERF_MOSTStress.H:1215
most_data mdata
Definition: ERF_MOSTStress.H:1369
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &tvm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &w_star_arr, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &t_surf_arr, const amrex::Array4< amrex::Real > &q_surf_arr, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &pblh_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &) const
Definition: ERF_MOSTStress.H:1232
bool spec_qflux
Definition: ERF_MOSTStress.H:1370
surface_temp_charnock(amrex::Real Tflux, amrex::Real Qvflux, amrex::Real cnk_a, bool cnk_visc, bool cons_qflux)
Definition: ERF_MOSTStress.H:1216
const amrex::Real tol_z
Definition: ERF_MOSTStress.H:1376
const amrex::Real alpha
Definition: ERF_MOSTStress.H:1378
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:1379
const amrex::Real tol
Definition: ERF_MOSTStress.H:1372
similarity_funs sfuns
Definition: ERF_MOSTStress.H:1371
Definition: ERF_MOSTStress.H:1551
similarity_funs sfuns
Definition: ERF_MOSTStress.H:1659
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &tvm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &w_star_arr, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &t_surf_arr, const amrex::Array4< amrex::Real > &q_surf_arr, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &pblh_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &) const
Definition: ERF_MOSTStress.H:1564
most_data mdata
Definition: ERF_MOSTStress.H:1657
const amrex::Real tol
Definition: ERF_MOSTStress.H:1660
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:1661
bool spec_qflux
Definition: ERF_MOSTStress.H:1658
surface_temp_donelan(amrex::Real Tflux, amrex::Real Qvflux, bool cons_qflux)
Definition: ERF_MOSTStress.H:1552
Definition: ERF_MOSTStress.H:1387
surface_temp_mod_charnock(amrex::Real Tflux, amrex::Real Qvflux, amrex::Real depth, bool cons_qflux)
Definition: ERF_MOSTStress.H:1388
similarity_funs sfuns
Definition: ERF_MOSTStress.H:1535
const amrex::Real tol
Definition: ERF_MOSTStress.H:1536
const amrex::Real tol_z
Definition: ERF_MOSTStress.H:1540
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:1543
most_data mdata
Definition: ERF_MOSTStress.H:1533
bool spec_qflux
Definition: ERF_MOSTStress.H:1534
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &tvm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &w_star_arr, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &t_surf_arr, const amrex::Array4< amrex::Real > &q_surf_arr, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &pblh_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &) const
Definition: ERF_MOSTStress.H:1403
const amrex::Real alpha
Definition: ERF_MOSTStress.H:1542
Definition: ERF_MOSTStress.H:1669
const amrex::Real eps
Definition: ERF_MOSTStress.H:1788
surface_temp_wave_coupled(amrex::Real Tflux, amrex::Real Qvflux, bool cons_qflux)
Definition: ERF_MOSTStress.H:1670
const amrex::Real tol
Definition: ERF_MOSTStress.H:1784
most_data mdata
Definition: ERF_MOSTStress.H:1781
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &tvm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &w_star_arr, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &t_surf_arr, const amrex::Array4< amrex::Real > &q_surf_arr, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &pblh_arr, const amrex::Array4< amrex::Real > &Hwave_arr, const amrex::Array4< amrex::Real > &Lwave_arr, const amrex::Array4< amrex::Real > &eta_arr) const
Definition: ERF_MOSTStress.H:1682
const amrex::Real z0_eps
Definition: ERF_MOSTStress.H:1790
similarity_funs sfuns
Definition: ERF_MOSTStress.H:1783
bool spec_qflux
Definition: ERF_MOSTStress.H:1782
const amrex::Real z0_max
Definition: ERF_MOSTStress.H:1791
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:1792
Definition: ERF_MOSTStress.H:1081
surface_temp(amrex::Real Tflux, amrex::Real Qvflux, bool cons_qflux)
Definition: ERF_MOSTStress.H:1082
similarity_funs sfuns
Definition: ERF_MOSTStress.H:1204
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void iterate_flux(const int &i, const int &j, const int &k, const int &max_iters, const amrex::Array4< const amrex::Real > &zref_arr, const amrex::Array4< const amrex::Real > &z0_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &tvm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< amrex::Real > &u_star_arr, const amrex::Array4< amrex::Real > &w_star_arr, const amrex::Array4< amrex::Real > &t_star_arr, const amrex::Array4< amrex::Real > &q_star_arr, const amrex::Array4< amrex::Real > &t_surf_arr, const amrex::Array4< amrex::Real > &q_surf_arr, const amrex::Array4< amrex::Real > &olen_arr, const amrex::Array4< amrex::Real > &pblh_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &) const
Definition: ERF_MOSTStress.H:1094
const amrex::Real tol
Definition: ERF_MOSTStress.H:1205
bool spec_qflux
Definition: ERF_MOSTStress.H:1203
const amrex::Real alpha
Definition: ERF_MOSTStress.H:1206
const amrex::Real WSMIN
Definition: ERF_MOSTStress.H:1207
most_data mdata
Definition: ERF_MOSTStress.H:1202