Skip to content

Commit da19bff

Browse files
committed
Merge branch 'atmosphere/nominal_min_dc' into develop (PR #1079)
This merge eliminates the need for users to specify config_len_disp in their namelist.atmosphere files by introducing a new scalar variable, nominalMinDc, which specifies the nominal minimum grid distance where meshDensity == 1.0. The nominalMinDc variable is read from the "input" stream by the init_atmosphere core and scaled along with other mesh fields like dcEdge and dvEdge; the nominalMinDc variable is then written to the "output" stream by the init_atmosphere core, making it available to the atmoshere core. At start-up, the atmosphere core attempts to read both the config_len_disp namelist variable and the nominalMinDc variable, both of which default to 0.0. 1) If both config_len_disp and nominalMinDc are provided (in the namelist and input file, respectively) as positive values, the config_len_disp value is used as the horizontal length scale for horizontal diffusion and 3-d divergence damping; nominalMinDc is set to this value as well. Additionally, if config_len_disp and nominalMinDc differ (by more than ~1.0e-6 relative difference), a warning is printed to the log file; e.g.: WARNING: nominalMinDc was read from input file as a positive value (120000.) that differs WARNING: from the specified config_len_disp value (125000.) 2) If only one of config_len_disp and nominalMinDc is provided as a positive value, that positive value is used in the model (and in any case, nominalMinDc takes that value when written to model restart files). 3) If neither config_len_disp nor nominalMinDc are provided, the atmosphere core stops with an error: ERROR: Both config_len_disp and nominalMinDc are <= 0.0. ERROR: Please either specify config_len_disp in the &nhyd_model namelist group, ERROR: or use an input file that provides a valid value for the nominalMinDc variable. The changes in this merge are backwards-compatible, in the sense that old mesh files that lack the nominalMinDc variable can still be used, in which case the user must supply the config_len_disp option in their namelist.atmosphere file.
2 parents 7484cc7 + 88bb6d4 commit da19bff

5 files changed

Lines changed: 82 additions & 2 deletions

File tree

src/core_atmosphere/Registry.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,10 @@
142142
description="Formulation of horizontal mixing"
143143
possible_values="`2d_fixed' or `2d_smagorinsky'"/>
144144

145-
<nml_option name="config_len_disp" type="real" default_value="120000.0"
145+
<nml_option name="config_len_disp" type="real" default_value="0.0" in_defaults="false"
146146
units="m"
147147
description="Horizontal length scale, used by the Smagorinsky formulation of horizontal diffusion and by 3-d divergence damping"
148-
possible_values="Positive real values"/>
148+
possible_values="Positive real values. A zero value implies that the length scale is prescribed by the nominalMinDc value in the input file."/>
149149

150150
<nml_option name="config_visc4_2dsmag" type="real" default_value="0.05"
151151
units="-"
@@ -457,6 +457,7 @@
457457
<var name="fEdge"/>
458458
<var name="fVertex"/>
459459
<var name="meshDensity"/>
460+
<var name="nominalMinDc"/>
460461
<var name="bdyMaskCell"/>
461462
<var name="bdyMaskEdge"/>
462463
<var name="bdyMaskVertex"/>
@@ -592,6 +593,7 @@
592593
<var name="fEdge"/>
593594
<var name="fVertex"/>
594595
<var name="meshDensity"/>
596+
<var name="nominalMinDc"/>
595597
<var name="bdyMaskCell"/>
596598
<var name="bdyMaskEdge"/>
597599
<var name="bdyMaskVertex"/>
@@ -1305,6 +1307,9 @@
13051307
<var name="meshDensity" type="real" dimensions="nCells" units="unitless"
13061308
description="Mesh density function (used when generating the mesh) evaluated at a cell"/>
13071309

1310+
<var name="nominalMinDc" type="real" dimensions="" units="m"
1311+
description="Nominal minimum dcEdge value where meshDensity == 1.0"/>
1312+
13081313
<var name="meshScalingDel2" type="real" dimensions="nEdges" units="unitless"
13091314
description="Scaling coefficient for $\nabla^2$ eddy viscosity"/>
13101315

src/core_atmosphere/mpas_atm_core.F

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ function atm_core_init(domain, startTimeStamp) result(ierr)
7171
character (len=StrKIND), pointer :: initial_time1, initial_time2
7272
type (MPAS_Time_Type) :: startTime
7373

74+
real (kind=RKIND), pointer :: nominalMinDc
75+
real (kind=RKIND), pointer :: config_len_disp
76+
7477
integer, pointer :: nVertLevels, maxEdges, maxEdges2, num_scalars
7578
character (len=ShortStrKIND) :: init_stream_name
7679
real (kind=R8KIND) :: input_start_time, input_stop_time
@@ -149,6 +152,56 @@ function atm_core_init(domain, startTimeStamp) result(ierr)
149152
call MPAS_stream_mgr_reset_alarms(domain % streamManager, streamID='restart', direction=MPAS_STREAM_INPUT, ierr=ierr)
150153
call mpas_log_write(' ----- done reading initial state -----')
151154

155+
156+
!
157+
! Determine horizontal length scale used by horizontal diffusion and 3-d divergence damping
158+
!
159+
call mpas_pool_get_subpool(domain % blocklist % structs, 'mesh', mesh)
160+
nullify(nominalMinDc)
161+
call mpas_pool_get_array(mesh, 'nominalMinDc', nominalMinDc)
162+
163+
nullify(config_len_disp)
164+
call mpas_pool_get_config(domain % blocklist % configs, 'config_len_disp', config_len_disp)
165+
166+
call mpas_log_write('')
167+
168+
!
169+
! If config_len_disp was specified as a valid value, use that
170+
!
171+
if (config_len_disp > 0.0_RKIND) then
172+
call mpas_log_write('Setting nominalMinDc to $r based on namelist option config_len_disp', realArgs=[config_len_disp])
173+
174+
!
175+
! But if nominalMinDc was available in the input file and is different, print a warning
176+
!
177+
if (nominalMinDc > 0.0_RKIND .and. abs(nominalMinDc - config_len_disp) > 1.0e-6_RKIND * config_len_disp) then
178+
call mpas_log_write('nominalMinDc was read from input file as a positive value ($r) that differs', &
179+
realArgs=[nominalMinDc], messageType=MPAS_LOG_WARN)
180+
call mpas_log_write('from the specified config_len_disp value ($r)', &
181+
realArgs=[config_len_disp], messageType=MPAS_LOG_WARN)
182+
end if
183+
184+
nominalMinDc = config_len_disp
185+
186+
!
187+
! Otherwise, try to use nominalMinDc
188+
!
189+
else
190+
if (nominalMinDc > 0.0_RKIND) then
191+
call mpas_log_write('Setting config_len_disp to $r based on nominalMinDc value in input file', realArgs=[nominalMinDc])
192+
config_len_disp = nominalMinDc
193+
else
194+
call mpas_log_write('Both config_len_disp and nominalMinDc are <= 0.0.', messageType=MPAS_LOG_ERR)
195+
call mpas_log_write('Please either specify config_len_disp in the &nhyd_model namelist group,', &
196+
messageType=MPAS_LOG_ERR)
197+
call mpas_log_write('or use an input file that provides a valid value for the nominalMinDc variable.', &
198+
messageType=MPAS_LOG_ERR)
199+
ierr = 1
200+
return
201+
end if
202+
end if
203+
204+
152205
!
153206
! Read all other inputs
154207
! For now we don't do this here to match results with previous code; to match requires

src/core_init_atmosphere/Registry.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@
389389
<var name="cellsOnVertex"/>
390390
<var name="kiteAreasOnVertex"/>
391391
<var name="meshDensity"/>
392+
<var name="nominalMinDc"/>
392393
<var name="bdyMaskCell"/>
393394
<var name="bdyMaskEdge"/>
394395
<var name="bdyMaskVertex"/>
@@ -487,6 +488,7 @@
487488
<var name="cellsOnVertex"/>
488489
<var name="kiteAreasOnVertex"/>
489490
<var name="meshDensity"/>
491+
<var name="nominalMinDc"/>
490492
<var name="bdyMaskCell"/>
491493
<var name="bdyMaskEdge"/>
492494
<var name="bdyMaskVertex"/>
@@ -734,6 +736,9 @@
734736
<var name="meshDensity" type="real" dimensions="nCells" units="unitless"
735737
description="Mesh density function (used when generating the mesh) evaluated at a cell"/>
736738

739+
<var name="nominalMinDc" type="real" dimensions="" units="m"
740+
description="Nominal minimum dcEdge value where meshDensity == 1.0"/>
741+
737742
<!-- coefficients for vertical extrapolation to the surface -->
738743
<var name="cf1" type="real" dimensions="" units="unitless"
739744
description="Surface interpolation weight for level k=1 value"/>

src/core_init_atmosphere/mpas_init_atm_cases.F

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,7 @@ subroutine init_atm_case_jw(mesh, nCells, nVertLevels, state, diag, configs)
483483
real (kind=RKIND), dimension(:), pointer :: xVertex, yVertex, zVertex
484484
real (kind=RKIND), dimension(:), pointer :: dcEdge, dvEdge, areaCell, areaTriangle
485485
real (kind=RKIND), dimension(:,:), pointer :: kiteAreasOnVertex
486+
real (kind=RKIND), pointer :: nominalMinDc
486487

487488
real (kind=RKIND), dimension(:), pointer :: latCell, latVertex, lonVertex, latEdge, lonEdge
488489
real (kind=RKIND), dimension(:), pointer :: fEdge, fVertex
@@ -517,6 +518,7 @@ subroutine init_atm_case_jw(mesh, nCells, nVertLevels, state, diag, configs)
517518
call mpas_pool_get_array(mesh, 'areaCell', areaCell)
518519
call mpas_pool_get_array(mesh, 'areaTriangle', areaTriangle)
519520
call mpas_pool_get_array(mesh, 'kiteAreasOnVertex', kiteAreasOnVertex)
521+
call mpas_pool_get_array(mesh, 'nominalMinDc', nominalMinDc)
520522
call mpas_pool_get_config(mesh, 'on_a_sphere', on_a_sphere)
521523
call mpas_pool_get_config(mesh, 'sphere_radius', sphere_radius)
522524

@@ -534,6 +536,7 @@ subroutine init_atm_case_jw(mesh, nCells, nVertLevels, state, diag, configs)
534536
areaCell(:) = areaCell(:) * sphere_radius**2.0
535537
areaTriangle(:) = areaTriangle(:) * sphere_radius**2.0
536538
kiteAreasOnVertex(:,:) = kiteAreasOnVertex(:,:) * sphere_radius**2.0
539+
nominalMinDc = nominalMinDc * sphere_radius
537540

538541
call mpas_pool_get_array(mesh, 'weightsOnEdge', weightsOnEdge)
539542
call mpas_pool_get_array(mesh, 'nEdgesOnEdge', nEdgesOnEdge)
@@ -1403,6 +1406,7 @@ subroutine init_atm_case_squall_line(dminfo, mesh, nCells, nVertLevels, state, d
14031406
real (kind=RKIND), dimension(:), pointer :: xVertex, yVertex, zVertex
14041407
real (kind=RKIND), dimension(:), pointer :: dcEdge, dvEdge, areaCell, areaTriangle
14051408
real (kind=RKIND), dimension(:,:), pointer :: kiteAreasOnVertex
1409+
real (kind=RKIND), pointer :: nominalMinDc
14061410
logical, pointer :: on_a_sphere
14071411
real (kind=RKIND), pointer :: sphere_radius
14081412

@@ -1425,6 +1429,7 @@ subroutine init_atm_case_squall_line(dminfo, mesh, nCells, nVertLevels, state, d
14251429
call mpas_pool_get_array(mesh, 'areaCell', areaCell)
14261430
call mpas_pool_get_array(mesh, 'areaTriangle', areaTriangle)
14271431
call mpas_pool_get_array(mesh, 'kiteAreasOnVertex', kiteAreasOnVertex)
1432+
call mpas_pool_get_array(mesh, 'nominalMinDc', nominalMinDc)
14281433

14291434
call mpas_pool_get_config(mesh, 'on_a_sphere', on_a_sphere)
14301435
call mpas_pool_get_config(mesh, 'sphere_radius', sphere_radius)
@@ -1450,6 +1455,7 @@ subroutine init_atm_case_squall_line(dminfo, mesh, nCells, nVertLevels, state, d
14501455
areaCell(:) = areaCell(:) * a_scale**2.0
14511456
areaTriangle(:) = areaTriangle(:) * a_scale**2.0
14521457
kiteAreasOnVertex(:,:) = kiteAreasOnVertex(:,:) * a_scale**2.0
1458+
nominalMinDc = nominalMinDc * a_scale
14531459

14541460
call mpas_pool_get_array(mesh, 'weightsOnEdge', weightsOnEdge)
14551461
call mpas_pool_get_array(mesh, 'nEdgesOnEdge', nEdgesOnEdge)
@@ -2005,6 +2011,7 @@ subroutine init_atm_case_mtn_wave(mesh, nCells, nVertLevels, state, diag, config
20052011
real (kind=RKIND), dimension(:), pointer :: xVertex, yVertex, zVertex
20062012
real (kind=RKIND), dimension(:), pointer :: dcEdge, dvEdge, areaCell, areaTriangle
20072013
real (kind=RKIND), dimension(:,:), pointer :: kiteAreasOnVertex
2014+
real (kind=RKIND), pointer :: nominalMinDc
20082015
logical, pointer :: on_a_sphere
20092016
real (kind=RKIND), pointer :: sphere_radius
20102017
real (kind=RKIND), pointer :: config_coef_3rd_order
@@ -2031,6 +2038,7 @@ subroutine init_atm_case_mtn_wave(mesh, nCells, nVertLevels, state, diag, config
20312038
call mpas_pool_get_array(mesh, 'areaCell', areaCell)
20322039
call mpas_pool_get_array(mesh, 'areaTriangle', areaTriangle)
20332040
call mpas_pool_get_array(mesh, 'kiteAreasOnVertex', kiteAreasOnVertex)
2041+
call mpas_pool_get_array(mesh, 'nominalMinDc', nominalMinDc)
20342042

20352043
call mpas_pool_get_config(mesh, 'on_a_sphere', on_a_sphere)
20362044
call mpas_pool_get_config(mesh, 'sphere_radius', sphere_radius)
@@ -2072,6 +2080,7 @@ subroutine init_atm_case_mtn_wave(mesh, nCells, nVertLevels, state, diag, config
20722080
areaCell(:) = areaCell(:) * a_scale**2.0
20732081
areaTriangle(:) = areaTriangle(:) * a_scale**2.0
20742082
kiteAreasOnVertex(:,:) = kiteAreasOnVertex(:,:) * a_scale**2.0
2083+
nominalMinDc = nominalMinDc * a_scale
20752084

20762085

20772086
call mpas_pool_get_dimension(mesh, 'nEdges', nEdges)
@@ -5854,6 +5863,7 @@ subroutine init_atm_case_cam_mpas(stream_manager, dminfo, block, mesh, &
58545863
real(kind=RKIND), dimension(:), pointer :: xVertex, yVertex, zVertex
58555864
real(kind=RKIND), dimension(:), pointer :: dcEdge, dvEdge, areaCell, areaTriangle
58565865
real(kind=RKIND), dimension(:,:), pointer :: kiteAreasOnVertex
5866+
real(kind=RKIND), pointer :: nominalMinDc
58575867

58585868
real(kind=RKIND), dimension(:), pointer :: fEdge, fVertex
58595869
real(kind=RKIND), dimension(:), pointer :: latEdge
@@ -5940,6 +5950,7 @@ subroutine init_atm_case_cam_mpas(stream_manager, dminfo, block, mesh, &
59405950
call mpas_pool_get_array(mesh, 'areaCell', areaCell)
59415951
call mpas_pool_get_array(mesh, 'areaTriangle', areaTriangle)
59425952
call mpas_pool_get_array(mesh, 'kiteAreasOnVertex', kiteAreasOnVertex)
5953+
call mpas_pool_get_array(mesh, 'nominalMinDc', nominalMinDc)
59435954
call mpas_pool_get_config(mesh, 'on_a_sphere', on_a_sphere)
59445955
call mpas_pool_get_config(mesh, 'sphere_radius', sphere_radius)
59455956

@@ -5957,6 +5968,7 @@ subroutine init_atm_case_cam_mpas(stream_manager, dminfo, block, mesh, &
59575968
areaCell(:) = areaCell(:) * sphere_radius**2
59585969
areaTriangle(:) = areaTriangle(:) * sphere_radius**2
59595970
kiteAreasOnVertex(:,:) = kiteAreasOnVertex(:,:) * sphere_radius**2
5971+
nominalMinDc = nominalMinDc * sphere_radius
59605972

59615973

59625974
!

src/core_init_atmosphere/mpas_init_atm_static.F

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ subroutine init_atm_static(mesh, dims, configs)
165165
real (kind=RKIND), dimension(:), pointer :: latVertex, lonVertex
166166
real (kind=RKIND), dimension(:), pointer :: latEdge, lonEdge
167167
real (kind=RKIND), dimension(:), pointer :: fEdge, fVertex
168+
real (kind=RKIND), pointer :: nominalMinDc
168169
169170
integer (kind=I8KIND), dimension(:,:), pointer :: greenfrac_int
170171
real (kind=RKIND), dimension(:), pointer :: snoalb
@@ -274,6 +275,8 @@ subroutine init_atm_static(mesh, dims, configs)
274275
call mpas_pool_get_dimension(dims, 'nVertices', nVertices)
275276
call mpas_pool_get_dimension(dims, 'maxEdges', maxEdges)
276277
278+
call mpas_pool_get_array(mesh, 'nominalMinDc', nominalMinDc)
279+
277280
xCell = xCell * sphere_radius
278281
yCell = yCell * sphere_radius
279282
zCell = zCell * sphere_radius
@@ -289,6 +292,8 @@ subroutine init_atm_static(mesh, dims, configs)
289292
areaTriangle = areaTriangle * sphere_radius**2.0
290293
kiteAreasOnVertex = kiteAreasOnVertex * sphere_radius**2.0
291294
295+
nominalMinDc = nominalMinDc * sphere_radius
296+
292297
!
293298
! Set max squared distance for k-d tree search to twice the squared cell diameter
294299
! The factor of two is simply a safety factor to account for possible inaccuracies

0 commit comments

Comments
 (0)