Skip to content

Commit 6fff2bb

Browse files
committed
Merge branch 'jgfouca/port_gwd_compute_tendencies_from_stress_divergence' into master (PR E3SM-Project#7525)
Change list: 1) Main change: Fill out CXX impl of gwd_compute_tendencies_from_stress_divergence 2) gw_common_init: Allow it to be called multiple times by deallocating cref and alpha if they had been previously allocated. 3) Begin to fill in constants needed by GW 4) Create struct for containing common init data in C++ 5) Add C++ version of gw_common_init and gw_common_finalize 6) Don't just assume all C++ data is packed. Just have it all unpacked for now 7) Fix randomized test data for gwd_compute_tendencies_from_stress_divergence so that some actual interesting computations happen. 8) For now, have a f90 and cxx bridge available for this function and use the f90 one for baseline generation. Once we are sure we have things working, the f90 calls can be removed. [BFB] (for everything outside of eamxx/gw)
2 parents d545d88 + 1aa36dd commit 6fff2bb

37 files changed

+714
-450
lines changed

components/eam/src/physics/cam/gw/gw_common.F90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ subroutine gw_common_init(pver_in, pgwv_in, dc_in, cref_in, &
141141
pver = pver_in
142142
pgwv = pgwv_in
143143
dc = dc_in
144+
if (allocated(cref)) deallocate(cref)
144145
allocate(cref(-pgwv:pgwv), stat=ierr, errmsg=errstring)
145146
if (ierr /= 0) return
146147
cref = cref_in
@@ -154,6 +155,7 @@ subroutine gw_common_init(pver_in, pgwv_in, dc_in, cref_in, &
154155
kwv = kwv_in
155156
gravit = gravit_in
156157
rair = rair_in
158+
if (allocated(alpha)) deallocate(alpha)
157159
allocate(alpha(0:pver), stat=ierr, errmsg=errstring)
158160
if (ierr /= 0) return
159161
alpha = alpha_in

components/eamxx/src/physics/gw/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ if (NOT EAMXX_ENABLE_GPU OR Kokkos_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE OR Kokkos
3131
eti/gw_gw_ediff.cpp
3232
eti/gw_gw_diff_tend.cpp
3333
eti/gw_gw_oro_src.cpp
34+
eti/gw_gw_common_init.cpp
3435
) # GW ETI SRCS
3536
endif()
3637

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include "impl/gw_gw_common_init_impl.hpp"
2+
3+
namespace scream {
4+
namespace gw {
5+
6+
/*
7+
* Explicit instantiation for doing gw_common_init on Reals using the
8+
* default device.
9+
*/
10+
11+
template struct Functions<Real,DefaultDevice>;
12+
13+
} // namespace gw
14+
} // namespace scream

components/eamxx/src/physics/gw/gw_functions.hpp

Lines changed: 138 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@ namespace gw {
2121
template <typename ScalarT, typename DeviceT>
2222
struct Functions
2323
{
24-
//
25-
// ---------- GW constants ---------
26-
//
27-
struct GWC {
28-
};
29-
3024
//
3125
// ------- Types --------
3226
//
@@ -54,47 +48,159 @@ struct Functions
5448
using view_1d = typename KT::template view_1d<S>;
5549
template <typename S>
5650
using view_2d = typename KT::template view_2d<S>;
51+
template <typename S>
52+
using view_3d = typename KT::template view_3d<S>;
5753

5854
template <typename S>
5955
using uview_1d = typename ekat::template Unmanaged<view_1d<S> >;
6056
template <typename S>
6157
using uview_2d = typename ekat::template Unmanaged<view_2d<S> >;
58+
template <typename S>
59+
using uview_3d = typename ekat::template Unmanaged<view_3d<S> >;
6260

6361
using MemberType = typename KT::MemberType;
6462

65-
using WorkspaceManager = typename ekat::WorkspaceManager<Spack, Device>;
63+
using WorkspaceManager = typename ekat::WorkspaceManager<Scalar, Device>;
6664
using Workspace = typename WorkspaceManager::Workspace;
6765

66+
//
67+
// ---------- GW constants ---------
68+
//
69+
struct GWC {
70+
// Index the cardinal directions.
71+
static inline constexpr int west = 0;
72+
static inline constexpr int east = 1;
73+
static inline constexpr int south = 2;
74+
static inline constexpr int north = 3;
75+
76+
// rair/gravit
77+
static inline constexpr Real rog = C::Rair / C::gravit;
78+
79+
// Background diffusivity.
80+
static inline constexpr Real dback = 0.05;
81+
82+
// Minimum non-zero stress.
83+
static inline constexpr Real taumin = 1.e-10;
84+
85+
// Maximum allowed change in u-c (before efficiency applied).
86+
static inline constexpr Real umcfac = 0.5;
87+
88+
// Minimum value of (u-c)**2.
89+
static inline constexpr Real ubmc2mn = 0.01;
90+
};
91+
92+
//
93+
// --------- Structs for organizing data ---------
94+
//
95+
96+
struct GwCommonInit {
97+
GwCommonInit() : initialized(false) {}
98+
99+
// Tell us if initialize has been called
100+
bool initialized;
101+
102+
// This flag preserves answers for vanilla CAM by making a few changes (e.g.
103+
// order of operations) when only orographic waves are on.
104+
bool orographic_only; // = .false.
105+
106+
// Number of levels in the atmosphere.
107+
int pver;
108+
109+
// Maximum number of waves allowed (i.e. wavenumbers are -pgwv:pgwv).
110+
int pgwv;
111+
112+
// Bin width for spectrum.
113+
Real dc; // = huge(1._r8)
114+
115+
// Reference speeds for the spectrum.
116+
view_1d<Real> cref;
117+
118+
// Whether or not molecular diffusion is being done, and bottom level where
119+
// it is done.
120+
bool do_molec_diff; // = .false.
121+
int nbot_molec; // = huge(1)
122+
123+
// Whether or not to enforce an upper boundary condition of tau = 0.
124+
bool tau_0_ubc; // = .false.
125+
126+
// Critical Froude number.
127+
Real fcrit2; // = huge(1._r8)
128+
129+
// Effective horizontal wave number.
130+
Real kwv; // = huge(1._r8)
131+
132+
// Interface levels for gravity wave sources.
133+
int ktop; // = huge(1)
134+
int kbotbg; // = huge(1)
135+
136+
// Effective wavenumber.
137+
Real effkwv; // = huge(1._r8)
138+
139+
// Newtonian cooling coefficients.
140+
view_1d<Real> alpha;
141+
142+
// Maximum wind tendency from stress divergence (before efficiency applied).
143+
Real tndmax; // = huge(1._r8)
144+
};
145+
146+
//
147+
// --------- Init/Finalize Functions ---------
148+
//
149+
static void gw_common_init(
150+
// Inputs
151+
const Int& pver_in,
152+
const Int& pgwv_in,
153+
const Real& dc_in,
154+
const uview_1d<const Real>& cref_in,
155+
const bool& orographic_only_in,
156+
const bool& do_molec_diff_in,
157+
const bool& tau_0_ubc_in,
158+
const Int& nbot_molec_in,
159+
const Int& ktop_in,
160+
const Int& kbotbg_in,
161+
const Real& fcrit2_in,
162+
const Real& kwv_in,
163+
const uview_1d<const Real>& alpha_in);
164+
165+
static void gw_common_finalize()
166+
{
167+
s_common_init.cref = decltype(s_common_init.cref)();
168+
s_common_init.alpha = decltype(s_common_init.alpha)();
169+
}
170+
68171
//
69172
// --------- Functions ---------
70173
//
71174

72175
KOKKOS_FUNCTION
73176
static void gwd_compute_tendencies_from_stress_divergence(
74177
// Inputs
75-
const Int& ncol,
178+
const MemberType& team,
179+
const Workspace& workspace,
180+
const GwCommonInit& init,
76181
const Int& pver,
77182
const Int& pgwv,
78-
const Int& ngwv,
79183
const bool& do_taper,
80-
const Spack& dt,
81-
const Spack& effgw,
82-
const uview_1d<const Int>& tend_level,
83-
const uview_1d<const Spack>& lat,
84-
const uview_1d<const Spack>& dpm,
85-
const uview_1d<const Spack>& rdpm,
86-
const uview_1d<const Spack>& c,
87-
const uview_1d<const Spack>& ubm,
88-
const uview_1d<const Spack>& t,
89-
const uview_1d<const Spack>& nm,
90-
const uview_1d<const Spack>& xv,
91-
const uview_1d<const Spack>& yv,
184+
const Real& dt,
185+
const Real& effgw,
186+
const Int& tend_level,
187+
const Int& max_level,
188+
const Real& lat,
189+
const uview_1d<const Real>& dpm,
190+
const uview_1d<const Real>& rdpm,
191+
const uview_1d<const Real>& c,
192+
const uview_1d<const Real>& ubm,
193+
const uview_1d<const Real>& t,
194+
const uview_1d<const Real>& nm,
195+
const Real& xv,
196+
const Real& yv,
92197
// Inputs/Outputs
93-
const uview_1d<Spack>& tau,
198+
const uview_2d<Real>& tau,
199+
const uview_2d<Real>& work,
94200
// Outputs
95-
const uview_1d<Spack>& gwut,
96-
const uview_1d<Spack>& utgw,
97-
const uview_1d<Spack>& vtgw);
201+
const uview_2d<Real>& gwut,
202+
const uview_1d<Real>& utgw,
203+
const uview_1d<Real>& vtgw);
98204

99205
KOKKOS_FUNCTION
100206
static void gw_prof(
@@ -137,7 +243,6 @@ struct Functions
137243
const Int& pver,
138244
const Int& pgwv,
139245
const Int& ncol,
140-
const Int& ngwv,
141246
const uview_1d<const Int>& src_level,
142247
const uview_1d<const Spack>& ubi,
143248
const uview_1d<const Spack>& c,
@@ -156,7 +261,6 @@ struct Functions
156261
const Int& pver,
157262
const Int& pgwv,
158263
const Int& ncol,
159-
const Int& ngwv,
160264
const uview_1d<const Int>& tend_level,
161265
const uview_1d<const Spack>& tau,
162266
const uview_1d<const Spack>& ubi,
@@ -172,7 +276,6 @@ struct Functions
172276
const Int& pver,
173277
const Int& pgwv,
174278
const Int& ncol,
175-
const Int& ngwv,
176279
const Spack& dt,
177280
const uview_1d<const Int>& tend_level,
178281
const uview_1d<const Spack>& pmid,
@@ -198,7 +301,6 @@ struct Functions
198301
const Int& pver,
199302
const Int& pgwv,
200303
const Int& ncol,
201-
const Int& ngwv,
202304
const uview_1d<const Int>& src_level,
203305
const uview_1d<const Int>& tend_level,
204306
const bool& do_taper,
@@ -256,7 +358,6 @@ struct Functions
256358
const Int& pver,
257359
const Int& pgwv,
258360
const Int& ncol,
259-
const Int& ngwv,
260361
const Int& kbot,
261362
const uview_1d<const Spack>& frontgf,
262363
// Outputs
@@ -268,7 +369,6 @@ struct Functions
268369
const Int& pver,
269370
const Int& pgwv,
270371
const Int& ncol,
271-
const Int& ngwv,
272372
const Int& kbot,
273373
const uview_1d<const Spack>& u,
274374
const uview_1d<const Spack>& v,
@@ -334,7 +434,6 @@ struct Functions
334434
const Int& pver,
335435
const Int& pgwv,
336436
const Int& ncol,
337-
const Int& ngwv,
338437
const uview_1d<const Spack>& lat,
339438
const Spack& hdepth_min,
340439
const uview_1d<const Spack>& hdepth,
@@ -355,7 +454,6 @@ struct Functions
355454
const Int& pver,
356455
const Int& pgwv,
357456
const Int& ncol,
358-
const Int& ngwv,
359457
const uview_1d<const Spack>& lat,
360458
const uview_1d<const Spack>& u,
361459
const uview_1d<const Spack>& v,
@@ -384,7 +482,6 @@ struct Functions
384482
// Inputs
385483
const Int& ncol,
386484
const Int& pver,
387-
const Int& ngwv,
388485
const Int& kbot,
389486
const Int& ktop,
390487
const uview_1d<const Int>& tend_level,
@@ -436,6 +533,12 @@ struct Functions
436533
const uview_1d<Spack>& xv,
437534
const uview_1d<Spack>& yv,
438535
const uview_1d<Spack>& c);
536+
537+
//
538+
// --------- Members ---------
539+
//
540+
inline static GwCommonInit s_common_init;
541+
439542
}; // struct Functions
440543

441544
} // namespace gw
@@ -463,5 +566,6 @@ struct Functions
463566
# include "impl/gw_gw_ediff_impl.hpp"
464567
# include "impl/gw_gw_diff_tend_impl.hpp"
465568
# include "impl/gw_gw_oro_src_impl.hpp"
569+
# include "impl/gw_gw_common_init_impl.hpp"
466570
#endif // GPU && !KOKKOS_ENABLE_*_RELOCATABLE_DEVICE_CODE
467571
#endif // P3_FUNCTIONS_HPP

components/eamxx/src/physics/gw/impl/gw_gw_beres_src_impl.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ void Functions<S,D>::gw_beres_src(
1818
const Int& pver,
1919
const Int& pgwv,
2020
const Int& ncol,
21-
const Int& ngwv,
2221
const uview_1d<const Spack>& lat,
2322
const uview_1d<const Spack>& u,
2423
const uview_1d<const Spack>& v,

components/eamxx/src/physics/gw/impl/gw_gw_cm_src_impl.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ void Functions<S,D>::gw_cm_src(
1818
const Int& pver,
1919
const Int& pgwv,
2020
const Int& ncol,
21-
const Int& ngwv,
2221
const Int& kbot,
2322
const uview_1d<const Spack>& u,
2423
const uview_1d<const Spack>& v,
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#ifndef GW_GW_COMMON_INIT_IMPL_HPP
2+
#define GW_GW_COMMON_INIT_IMPL_HPP
3+
4+
#include "gw_functions.hpp" // for ETI only but harmless for GPU
5+
6+
namespace scream {
7+
namespace gw {
8+
9+
/*
10+
* Implementation of gw gw_common_init. Clients should NOT
11+
* #include this file, but include gw_functions.hpp instead.
12+
*/
13+
14+
template<typename S, typename D>
15+
void Functions<S,D>::gw_common_init(
16+
// Inputs
17+
const Int& pver_in,
18+
const Int& pgwv_in,
19+
const Real& dc_in,
20+
const uview_1d<const Real>& cref_in,
21+
const bool& orographic_only_in,
22+
const bool& do_molec_diff_in,
23+
const bool& tau_0_ubc_in,
24+
const Int& nbot_molec_in,
25+
const Int& ktop_in,
26+
const Int& kbotbg_in,
27+
const Real& fcrit2_in,
28+
const Real& kwv_in,
29+
const uview_1d<const Real>& alpha_in)
30+
{
31+
s_common_init.initialized = true;
32+
s_common_init.pver = pver_in;
33+
s_common_init.pgwv = pgwv_in;
34+
s_common_init.dc = dc_in;
35+
s_common_init.cref = view_1d<Real>("cref", cref_in.size());
36+
Kokkos::deep_copy(s_common_init.cref, cref_in);
37+
s_common_init.orographic_only = orographic_only_in;
38+
s_common_init.do_molec_diff = do_molec_diff_in;
39+
s_common_init.tau_0_ubc = tau_0_ubc_in;
40+
s_common_init.nbot_molec = nbot_molec_in;
41+
s_common_init.ktop = ktop_in;
42+
s_common_init.kbotbg = kbotbg_in;
43+
s_common_init.fcrit2 = fcrit2_in;
44+
s_common_init.kwv = kwv_in;
45+
s_common_init.alpha = view_1d<Real>("alpha", alpha_in.size());
46+
Kokkos::deep_copy(s_common_init.alpha, alpha_in);
47+
s_common_init.effkwv = kwv_in * fcrit2_in;
48+
s_common_init.tndmax = orographic_only_in ? 500. / 86400. : 400. / 86400.;
49+
}
50+
51+
} // namespace gw
52+
} // namespace scream
53+
54+
#endif

0 commit comments

Comments
 (0)