Skip to content

Commit 183661c

Browse files
committed
Fixes for PUMAS bfb with QPC7 CAM snapshot
Assisted-by: claude-opus:4.8[1m]
1 parent 090416b commit 183661c

12 files changed

Lines changed: 500 additions & 32 deletions
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
! Stub for heterogeneous freezing by classical nucleation theory (hetfrz_classnuc).
2+
!
3+
! This scheme exists to read the use_hetfrz_classnuc namelist flag and expose it
4+
! via its CCPP standard name so downstream schemes (e.g. nucleate_ice_ccpp,
5+
! eventually PUMAS) can see the flag. It performs no heterogeneous-freezing
6+
! computation -- the real hetfrz_classnuc_ccpp is not yet ported to CAM-SIMA.
7+
!
8+
! Safe to use with use_hetfrz_classnuc=.true. for snapshot-testing flows where
9+
! the flag must propagate downstream; a warning is printed at init time.
10+
module hetfrz_classnuc_stub
11+
use ccpp_kinds, only: kind_phys
12+
13+
implicit none
14+
private
15+
16+
public :: hetfrz_classnuc_stub_init
17+
18+
contains
19+
20+
!> \section arg_table_hetfrz_classnuc_stub_init Argument Table
21+
!! \htmlinclude hetfrz_classnuc_stub_init.html
22+
subroutine hetfrz_classnuc_stub_init( &
23+
amIRoot, iulog, &
24+
use_hetfrz_classnuc, &
25+
errmsg, errflg)
26+
27+
logical, intent(in) :: amIRoot
28+
integer, intent(in) :: iulog
29+
logical, intent(in) :: use_hetfrz_classnuc
30+
31+
character(len=*), intent(out) :: errmsg
32+
integer, intent(out) :: errflg
33+
34+
errmsg = ''
35+
errflg = 0
36+
37+
if (amIRoot) then
38+
if (use_hetfrz_classnuc) then
39+
write(iulog, '(A)') 'WARNING: hetfrz_classnuc_stub: use_hetfrz_classnuc=.true., but ' // &
40+
'heterogeneous freezing by classical nucleation theory is not yet ' // &
41+
'implemented in CAM-SIMA (stub scheme).'
42+
write(iulog, '(A)') 'WARNING: hetfrz_classnuc_stub: The flag is still propagated to ' // &
43+
'downstream schemes (e.g. nucleate_ice_ccpp) via its CCPP standard ' // &
44+
'name, but no hetfrz_classnuc computation will occur.'
45+
46+
! this is not intended to error out for now as the flag needs to be passed to downstream schemes
47+
! (e.g., PUMAS) and modifies their behavior
48+
else
49+
write(iulog, '(A)') 'hetfrz_classnuc_stub: use_hetfrz_classnuc=.false. (stub scheme, ' // &
50+
'no-op).'
51+
end if
52+
end if
53+
54+
end subroutine hetfrz_classnuc_stub_init
55+
56+
end module hetfrz_classnuc_stub
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
[ccpp-table-properties]
2+
name = hetfrz_classnuc_stub
3+
type = scheme
4+
5+
[ccpp-arg-table]
6+
name = hetfrz_classnuc_stub_init
7+
type = scheme
8+
[ amIRoot ]
9+
standard_name = flag_for_mpi_root
10+
units = flag
11+
type = logical
12+
dimensions = ()
13+
intent = in
14+
[ iulog ]
15+
standard_name = log_output_unit
16+
units = 1
17+
type = integer
18+
dimensions = ()
19+
intent = in
20+
[ use_hetfrz_classnuc ]
21+
standard_name = do_heterogeneous_ice_nucleation
22+
units = flag
23+
type = logical
24+
dimensions = ()
25+
intent = in
26+
[ errmsg ]
27+
standard_name = ccpp_error_message
28+
units = none
29+
type = character | kind = len=*
30+
dimensions = ()
31+
intent = out
32+
[ errflg ]
33+
standard_name = ccpp_error_code
34+
units = 1
35+
type = integer
36+
dimensions = ()
37+
intent = out
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0"?>
2+
3+
<?xml-stylesheet type="text/xsl"?>
4+
5+
<entry_id_pg version="2.0">
6+
7+
<entry id="use_hetfrz_classnuc">
8+
<type>logical</type>
9+
<category>microphys</category>
10+
<group>hetfrz_classnuc_nl</group>
11+
<standard_name>do_heterogeneous_ice_nucleation</standard_name>
12+
<units>flag</units>
13+
<desc>
14+
Switch to turn on heterogeneous freezing by classical nucleation theory.
15+
Currently a stub in CAM-SIMA: the flag is propagated to downstream schemes
16+
(nucleate_ice_ccpp, eventually PUMAS) but no hetfrz computation is performed.
17+
Setting this to TRUE is supported for snapshot-testing flows where the flag
18+
must match CAM; a warning is emitted at init time.
19+
Default: FALSE; TRUE for CAM6 and CAM7.
20+
</desc>
21+
<values>
22+
<value>.false.</value>
23+
<value phys_suite="cam6">.true.</value>
24+
<value phys_suite="cam7">.true.</value>
25+
</values>
26+
</entry>
27+
28+
</entry_id_pg>

schemes/pumas/micro_pumas_ccpp_dimensions_post.meta

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
kind = pumas_r8
153153
intent = in
154154
[numliq_tend]
155-
standard_name = tendency_of_mass_number_concentration_of_cloud_liquid_water_wrt_moist_air_and_condensed_water
155+
standard_name = tendency_of_mass_number_concentration_of_cloud_liquid_wrt_moist_air_and_condensed_water
156156
long_name = mass number concentration of cloud liquid water wrt moist air and condensed water
157157
units = kg-1 s-1
158158
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
@@ -169,7 +169,7 @@
169169
kind = pumas_r8
170170
intent = in
171171
[numice_tend]
172-
standard_name = tendency_of_mass_number_concentration_of_cloud_ice_wrt_moist_air_and_condensed_water
172+
standard_name = tendency_of_mass_number_concentration_of_ice_wrt_moist_air_and_condensed_water
173173
long_name = mass number concentration of cloud ice wrt moist air and condensed water
174174
units = kg-1 s-1
175175
dimensions = (horizontal_loop_extent, vertical_layer_dimension)

schemes/pumas/micro_pumas_ccpp_dimensions_pre.F90

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ subroutine micro_pumas_ccpp_dimensions_pre_run(ncol, nlev, nlevp1,
6262
pdel_in, pumas_pdel, &
6363
pint_in, pumas_pint, &
6464
strat_cldfrc_in, pumas_strat_cldfrc, &
65-
strat_liq_cldfrc_in, pumas_strat_liq_cldfrc, &
66-
strat_ice_cldfrc_in, pumas_strat_ice_cldfrc, &
65+
pumas_strat_liq_cldfrc, &
66+
pumas_strat_ice_cldfrc, &
6767
qsatfac_in, pumas_qsatfac, &
6868
naai_in, pumas_naai, &
6969
npccn_in, pumas_npccn, &
@@ -147,10 +147,8 @@ subroutine micro_pumas_ccpp_dimensions_pre_run(ncol, nlev, nlevp1,
147147
real(kind_phys), intent(in) :: strat_cldfrc_in(:, :)
148148
real(pumas_r8), intent(out) :: pumas_strat_cldfrc(:, :)
149149
! Stratiform cloud liquid area fraction (fraction)
150-
real(kind_phys), intent(in) :: strat_liq_cldfrc_in(:, :)
151150
real(pumas_r8), intent(out) :: pumas_strat_liq_cldfrc(:, :)
152151
! Stratiform cloud ice area fraction (fraction)
153-
real(kind_phys), intent(in) :: strat_ice_cldfrc_in(:, :)
154152
real(pumas_r8), intent(out) :: pumas_strat_ice_cldfrc(:, :)
155153
! Subgrid cloud water saturation scaling factor (1)
156154
real(kind_phys), intent(in) :: qsatfac_in(:, :)
@@ -218,8 +216,10 @@ subroutine micro_pumas_ccpp_dimensions_pre_run(ncol, nlev, nlevp1,
218216
pumas_pdel(:ncol,:) = real(pdel_in(:,:), pumas_r8)
219217
pumas_pint(:ncol,:) = real(pint_in(:,:micro_nlevp1), pumas_r8)
220218
pumas_strat_cldfrc(:ncol,:) = real(strat_cldfrc_in(:,:), pumas_r8)
221-
pumas_strat_liq_cldfrc(:ncol,:) = real(strat_liq_cldfrc_in(:,:), pumas_r8)
222-
pumas_strat_ice_cldfrc(:ncol,:) = real(strat_ice_cldfrc_in(:,:), pumas_r8)
219+
! PUMAS uses total stratiform fraction for both liquid and ice stratus.
220+
! Mirrors CAM micro_pumas_cam.F90: alst_mic => ast; aist_mic => ast.
221+
pumas_strat_liq_cldfrc(:ncol,:) = real(strat_cldfrc_in(:,:), pumas_r8)
222+
pumas_strat_ice_cldfrc(:ncol,:) = real(strat_cldfrc_in(:,:), pumas_r8)
223223
pumas_qsatfac(:ncol,:) = real(qsatfac_in(:,:), pumas_r8)
224224
pumas_naai(:ncol,:) = real(naai_in(:,:), pumas_r8)
225225
pumas_npccn(:ncol,:) = real(npccn_in(:,:), pumas_r8)
@@ -230,10 +230,7 @@ subroutine micro_pumas_ccpp_dimensions_pre_run(ncol, nlev, nlevp1,
230230
pumas_effi_external(:ncol,:) = real(effi_external_in(:,:), pumas_r8)
231231
pumas_frzcnt(:ncol,:) = real(frzcnt_in(:,:), pumas_r8)
232232
pumas_frzdep(:ncol,:) = real(frzdep_in(:,:), pumas_r8)
233-
234-
pumas_naai(:,:) = 0._pumas_r8
235-
pumas_npccn(:,:) = 0._pumas_r8
236-
pumas_qsatfac(:,:) = 0._pumas_r8
233+
pumas_frzimm(:ncol,:) = real(frzimm_in(:,:), pumas_r8)
237234

238235
end subroutine micro_pumas_ccpp_dimensions_pre_run
239236

schemes/pumas/micro_pumas_ccpp_dimensions_pre.meta

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@
221221
kind = pumas_r8
222222
intent = out
223223
[numliq_in]
224-
standard_name = mass_number_concentration_of_cloud_liquid_water_wrt_moist_air_and_condensed_water
224+
standard_name = mass_number_concentration_of_cloud_liquid_wrt_moist_air_and_condensed_water
225225
long_name = mass number concentration of cloud liquid wrt moist air and condensed water of new state
226226
units = kg-1
227227
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
@@ -238,7 +238,7 @@
238238
kind = pumas_r8
239239
intent = out
240240
[numice_in]
241-
standard_name = mass_number_concentration_of_cloud_ice_wrt_moist_air_and_condensed_water
241+
standard_name = mass_number_concentration_of_ice_wrt_moist_air_and_condensed_water
242242
long_name = mass number concentration of cloud ice wrt moist air and condensed water of new state
243243
units = kg-1
244244
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
@@ -452,14 +452,6 @@
452452
type = real
453453
kind = pumas_r8
454454
intent = out
455-
[strat_liq_cldfrc_in]
456-
standard_name = stratiform_cloud_liquid_area_fraction
457-
long_name = stratiform cloud liquid area fraction
458-
units = fraction
459-
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
460-
type = real
461-
kind = kind_phys
462-
intent = in
463455
[pumas_strat_liq_cldfrc]
464456
standard_name = pumas_stratiform_cloud_liquid_area_fraction
465457
long_name = microphysics stratiform cloud liquid area fraction
@@ -468,14 +460,6 @@
468460
type = real
469461
kind = pumas_r8
470462
intent = out
471-
[strat_ice_cldfrc_in]
472-
standard_name = stratiform_cloud_ice_area_fraction
473-
long_name = stratiform cloud ice area fraction
474-
units = fraction
475-
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
476-
type = real
477-
kind = kind_phys
478-
intent = in
479463
[pumas_strat_ice_cldfrc]
480464
standard_name = pumas_stratiform_cloud_ice_area_fraction
481465
long_name = microphysics stratiform cloud ice area fraction

schemes/pumas/pumas_post_main.F90

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
! Post-processing interstitial for PUMAS.
2+
module pumas_post_main
3+
implicit none
4+
private
5+
6+
public :: pumas_post_main_run
7+
8+
contains
9+
10+
!> \section arg_table_pumas_post_main_run Argument Table
11+
!! \htmlinclude pumas_post_main_run.html
12+
subroutine pumas_post_main_run(ncol, cldice, numice, strat_cldfrc, effi, errmsg, errcode)
13+
use ccpp_kinds, only: kind_phys
14+
use pumas_kinds, only: pumas_r8=>kind_r8
15+
use micro_pumas_utils, only: size_dist_param_basic, mg_ice_props, mincld, qsmall
16+
17+
integer, intent(in) :: ncol
18+
real(kind_phys), dimension(:,:), intent(in) :: cldice ! updated cloud ice mixing ratio (kg/kg)
19+
real(kind_phys), dimension(:,:), intent(in) :: numice ! updated cloud ice number concentration (kg-1)
20+
real(kind_phys), dimension(:,:), intent(in) :: strat_cldfrc! total stratiform cloud area fraction (= ast)
21+
real(kind_phys), dimension(:,:), intent(out) :: effi ! ice effective radius (micron)
22+
character(len=512), intent(out) :: errmsg
23+
integer, intent(out) :: errcode
24+
25+
integer :: k, nlev
26+
real(pumas_r8) :: icimrst(ncol, size(cldice,2)) ! in-cloud (grid-mean) ice mixing ratio
27+
real(pumas_r8) :: niic(ncol, size(cldice,2)) ! in-cloud (grid-mean) ice number conc
28+
real(pumas_r8) :: rei(ncol, size(cldice,2)) ! ice slope param, then effective radius
29+
30+
errmsg = ' '
31+
errcode = 0
32+
33+
nlev = size(cldice, 2)
34+
35+
! Ice effective radius is recomputed here from the post-microphysics
36+
! grid-mean in-cloud ice, NOT from the raw per-substep value PUMAS returns.
37+
! PUMAS uses the total stratiform fraction for ice cloud (icecldf = ast).
38+
! Mirrors CAM micro_pumas_cam.F90:2677 (icimrst), :3174 (niic), :3171-3193 (rei).
39+
icimrst(:,:) = min(real(cldice(:ncol,:), pumas_r8) / &
40+
max(mincld, real(strat_cldfrc(:ncol,:), pumas_r8)), 0.005_pumas_r8)
41+
niic(:,:) = real(numice(:ncol,:), pumas_r8) / &
42+
max(mincld, real(strat_cldfrc(:ncol,:), pumas_r8))
43+
44+
rei(:,:) = 25._pumas_r8
45+
do k = 1, nlev
46+
call size_dist_param_basic(mg_ice_props, icimrst(:,k), niic(:,k), rei(:,k), ncol)
47+
end do
48+
49+
where (icimrst(:,:) >= qsmall)
50+
rei(:,:) = 1.5_pumas_r8 / rei(:,:) * 1.e6_pumas_r8
51+
elsewhere
52+
rei(:,:) = 25._pumas_r8
53+
end where
54+
55+
effi(:ncol,:) = real(rei(:,:), kind_phys)
56+
57+
end subroutine pumas_post_main_run
58+
59+
end module pumas_post_main

schemes/pumas/pumas_post_main.meta

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
[ccpp-table-properties]
2+
name = pumas_post_main
3+
type = scheme
4+
dependencies = pumas/micro_pumas_utils.F90
5+
6+
[ccpp-arg-table]
7+
name = pumas_post_main_run
8+
type = scheme
9+
[ncol]
10+
standard_name = horizontal_loop_extent
11+
long_name = number of horizontal columns
12+
units = count
13+
dimensions = ()
14+
type = integer
15+
intent = in
16+
[cldice]
17+
standard_name = cloud_ice_mixing_ratio_wrt_moist_air_and_condensed_water
18+
long_name = cloud ice mixing ratio wrt moist air and condensed water
19+
units = kg kg-1
20+
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
21+
type = real
22+
kind = kind_phys
23+
intent = in
24+
advected = true
25+
[numice]
26+
standard_name = mass_number_concentration_of_ice_wrt_moist_air_and_condensed_water
27+
long_name = mass number concentration of cloud ice wrt moist air and condensed water
28+
units = kg-1
29+
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
30+
type = real
31+
kind = kind_phys
32+
intent = in
33+
advected = true
34+
[strat_cldfrc]
35+
standard_name = stratiform_cloud_area_fraction
36+
long_name = stratiform cloud area fraction
37+
units = fraction
38+
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
39+
type = real
40+
kind = kind_phys
41+
intent = in
42+
[effi]
43+
standard_name = effective_radius_of_stratiform_cloud_ice_particle
44+
long_name = effective radius of stratiform cloud ice particle
45+
units = micron
46+
dimensions = (horizontal_loop_extent, vertical_layer_dimension)
47+
type = real
48+
kind = kind_phys
49+
intent = out
50+
[errmsg]
51+
standard_name = ccpp_error_message
52+
long_name = error message for error handling in CCPP
53+
units = none
54+
dimensions = ()
55+
type = character
56+
kind = len=512
57+
intent = out
58+
[errcode]
59+
standard_name = ccpp_error_code
60+
long_name = error code for error handling in CCPP
61+
units = 1
62+
dimensions = ()
63+
type = integer
64+
intent = out

0 commit comments

Comments
 (0)