1- import math
2-
31import numpy as np
42
53import ndsl .constants as constants
64import ndsl .dsl .gt4py_utils as utils
75from ndsl import CubedSphereCommunicator , QuantityFactory
6+ from ndsl .dsl .typing import Float
87from ndsl .grid import GridData
98from ndsl .grid .gnomonic import great_circle_distance_lon_lat , lon_lat_midpoint
109from pyfv3 .dycore_state import DycoreState
1312
1413# maximum windspeed amplitude - close to windspeed of zonal-mean time-mean
1514# jet stream in troposphere
16- U0 = 35.0 # From Table VI of DCMIP2016
15+ U0 = Float ( 35.0 ) # From Table VI of DCMIP2016
1716# [lon, lat] of zonal wind perturbation centerpoint at 20E, 40N
18- PCEN = [math . pi / 9.0 , 2.0 * math . pi / 9.0 ] # From Table VI of DCMIP2016
19- U1 = 1.0
20- SURFACE_PRESSURE = 1.0e5 # units of (Pa), from Table VI of DCMIP2016
21- # NOTE RADIUS = 6.3712e6 in FV3 vs Jabowski paper 6.371229e6
22- R = constants . RADIUS / 10.0 # Perturbation radiusfor test case 13
17+ PCEN = [
18+ constants . PI / Float ( 9.0 ),
19+ Float ( 2.0 ) * constants . PI / Float ( 9.0 ),
20+ ] # From Table VI of DCMIP2016
21+ SURFACE_PRESSURE = Float ( 1.0e5 ) # units of (Pa), from Table VI of DCMIP2016
2322NHALO = constants .N_HALO_DEFAULT
2423
2524
26- def apply_perturbation (u_component , up , lon , lat ):
25+ def apply_perturbation (u_component , up , lon , lat , is_steady : bool = False ):
2726 """
2827 Apply a Gaussian perturbation to intiate a baroclinic wave in JRMS2006
2928 up is the maximum amplitude of the perturbation
3029 modifies u_component to include the perturbation of radius R
3130 """
31+ if is_steady :
32+ R = Float (1.0 ) # Steady State radius for test case 12
33+ else :
34+ # NOTE RADIUS = 6.3712e6 in FV3 vs Jabowski paper 6.371229e6
35+ R = constants .RADIUS / Float (10.0 ) # Perturbation radius for test case 13
3236 r = np .zeros ((u_component .shape [0 ], u_component .shape [1 ], 1 ))
3337 # Equation (11), distance from perturbation at 20E, 40N in JRMS2006
3438 r = great_circle_distance_lon_lat (PCEN [0 ], lon , PCEN [1 ], lat , constants .RADIUS , np )[
@@ -43,9 +47,21 @@ def apply_perturbation(u_component, up, lon, lat):
4347 )
4448
4549
46- def baroclinic_perturbed_zonal_wind (eta_v , lon , lat ):
50+ def baroclinic_perturbed_zonal_wind (
51+ eta_v ,
52+ lon ,
53+ lat ,
54+ is_steady : bool = False ,
55+ ):
4756 u = zonal_wind (eta_v , lat )
48- apply_perturbation (u , U1 , lon , lat )
57+
58+ if is_steady :
59+ u1 = Float (0.0 ) # Steady State for test case 12
60+ # TODO: Check if Fortran side is actually 0 (not initialized)
61+ else :
62+ u1 = Float (1.0 ) # Perturbation case for test case 13
63+
64+ apply_perturbation (u , u1 , lon , lat , is_steady = is_steady )
4965 return u
5066
5167
@@ -59,12 +75,16 @@ def wind_component_calc(
5975 islice_grid ,
6076 jslice ,
6177 jslice_grid ,
78+ is_steady : bool = False ,
6279):
6380 slice_grid = (islice_grid , jslice_grid )
6481 slice_3d = (islice , jslice , slice (None ))
6582 u_component = np .zeros (shape )
6683 u_component [slice_3d ] = baroclinic_perturbed_zonal_wind (
67- eta_v , lon [slice_grid ], lat [slice_grid ]
84+ eta_v ,
85+ lon [slice_grid ],
86+ lat [slice_grid ],
87+ is_steady = is_steady ,
6888 )
6989 u_component [slice_3d ] = init_utils .local_coordinate_transformation (
7090 u_component [slice_3d ],
@@ -95,6 +115,7 @@ def initialize_zonal_wind(
95115 jslice ,
96116 jslice_grid ,
97117 axis ,
118+ is_steady : bool = False ,
98119):
99120 shape = u .shape
100121 uu1 = wind_component_calc (
@@ -107,6 +128,7 @@ def initialize_zonal_wind(
107128 islice ,
108129 jslice ,
109130 jslice_grid ,
131+ is_steady = is_steady ,
110132 )
111133 uu3 = wind_component_calc (
112134 shape ,
@@ -118,6 +140,7 @@ def initialize_zonal_wind(
118140 islice_grid ,
119141 jslice ,
120142 jslice ,
143+ is_steady = is_steady ,
121144 )
122145 upper = (slice (None ),) * axis + (slice (0 , - 1 ),)
123146 lower = (slice (None ),) * axis + (slice (1 , None ),)
@@ -132,6 +155,7 @@ def initialize_zonal_wind(
132155 islice ,
133156 jslice ,
134157 jslice ,
158+ is_steady = is_steady ,
135159 )
136160 u [islice , jslice , :] = 0.25 * (uu1 + 2.0 * uu2 + uu3 )[islice , jslice , :]
137161
@@ -161,6 +185,7 @@ def baroclinic_initialization(
161185 hydrostatic ,
162186 nx ,
163187 ny ,
188+ is_steady : bool = False ,
164189):
165190 """
166191 Calls methods that compute initial state via the Jablonowski perturbation test case
@@ -191,6 +216,7 @@ def baroclinic_initialization(
191216 jslice = slice (0 , ny ),
192217 jslice_grid = slice (1 , ny + 1 ),
193218 axis = 1 ,
219+ is_steady = is_steady ,
194220 )
195221
196222 initialize_zonal_wind (
@@ -206,6 +232,7 @@ def baroclinic_initialization(
206232 jslice = slice (0 , ny + 1 ),
207233 jslice_grid = slice (0 , ny + 1 ),
208234 axis = 0 ,
235+ is_steady = is_steady ,
209236 )
210237
211238 slice_3d = (slice (0 , nx ), slice (0 , ny ), slice (None ))
@@ -251,6 +278,7 @@ def init_baroclinic_state(
251278 hydrostatic : bool ,
252279 moist_phys : bool ,
253280 comm : CubedSphereCommunicator ,
281+ is_steady : bool = False ,
254282) -> DycoreState :
255283 """
256284 Create a DycoreState object with quantities initialized to the Jablonowski &
@@ -322,6 +350,7 @@ def init_baroclinic_state(
322350 hydrostatic = hydrostatic ,
323351 nx = nx ,
324352 ny = ny ,
353+ is_steady = is_steady ,
325354 )
326355
327356 init_utils .p_var (
0 commit comments