-
Notifications
You must be signed in to change notification settings - Fork 0
Fixes for PUMAS bfb with QPC7 and FHISTC_LTso CAM snapshot #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| ! Stub for heterogeneous freezing by classical nucleation theory (hetfrz_classnuc). | ||
| ! | ||
| ! This scheme exists to read the use_hetfrz_classnuc namelist flag and expose it | ||
| ! via its CCPP standard name so downstream schemes (e.g. nucleate_ice_ccpp, | ||
| ! eventually PUMAS) can see the flag. It performs no heterogeneous-freezing | ||
| ! computation -- the real hetfrz_classnuc_ccpp is not yet ported to CAM-SIMA. | ||
| ! | ||
| ! Safe to use with use_hetfrz_classnuc=.true. for snapshot-testing flows where | ||
| ! the flag must propagate downstream; a warning is printed at init time. | ||
| module hetfrz_classnuc_stub | ||
| use ccpp_kinds, only: kind_phys | ||
|
|
||
| implicit none | ||
| private | ||
|
|
||
| public :: hetfrz_classnuc_stub_init | ||
|
|
||
| contains | ||
|
|
||
| !> \section arg_table_hetfrz_classnuc_stub_init Argument Table | ||
| !! \htmlinclude hetfrz_classnuc_stub_init.html | ||
| subroutine hetfrz_classnuc_stub_init( & | ||
| amIRoot, iulog, & | ||
| use_hetfrz_classnuc, & | ||
| errmsg, errflg) | ||
|
|
||
| logical, intent(in) :: amIRoot | ||
| integer, intent(in) :: iulog | ||
| logical, intent(in) :: use_hetfrz_classnuc | ||
|
|
||
| character(len=*), intent(out) :: errmsg | ||
| integer, intent(out) :: errflg | ||
|
|
||
| errmsg = '' | ||
| errflg = 0 | ||
|
|
||
| if (amIRoot) then | ||
| if (use_hetfrz_classnuc) then | ||
| write(iulog, '(A)') 'WARNING: hetfrz_classnuc_stub: use_hetfrz_classnuc=.true., but ' // & | ||
| 'heterogeneous freezing by classical nucleation theory is not yet ' // & | ||
| 'implemented in CAM-SIMA (stub scheme).' | ||
| write(iulog, '(A)') 'WARNING: hetfrz_classnuc_stub: The flag is still propagated to ' // & | ||
| 'downstream schemes (e.g. nucleate_ice_ccpp) via its CCPP standard ' // & | ||
| 'name, but no hetfrz_classnuc computation will occur.' | ||
|
|
||
| ! this is not intended to error out for now as the flag needs to be passed to downstream schemes | ||
| ! (e.g., PUMAS) and modifies their behavior | ||
| else | ||
| write(iulog, '(A)') 'hetfrz_classnuc_stub: use_hetfrz_classnuc=.false. (stub scheme, ' // & | ||
| 'no-op).' | ||
| end if | ||
| end if | ||
|
|
||
| end subroutine hetfrz_classnuc_stub_init | ||
|
|
||
| end module hetfrz_classnuc_stub |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| [ccpp-table-properties] | ||
| name = hetfrz_classnuc_stub | ||
| type = scheme | ||
|
|
||
| [ccpp-arg-table] | ||
| name = hetfrz_classnuc_stub_init | ||
| type = scheme | ||
| [ amIRoot ] | ||
| standard_name = flag_for_mpi_root | ||
| units = flag | ||
| type = logical | ||
| dimensions = () | ||
| intent = in | ||
| [ iulog ] | ||
| standard_name = log_output_unit | ||
| units = 1 | ||
| type = integer | ||
| dimensions = () | ||
| intent = in | ||
| [ use_hetfrz_classnuc ] | ||
| standard_name = do_heterogeneous_ice_nucleation | ||
| units = flag | ||
| type = logical | ||
| dimensions = () | ||
| intent = in | ||
| [ errmsg ] | ||
| standard_name = ccpp_error_message | ||
| units = none | ||
| type = character | kind = len=* | ||
| dimensions = () | ||
| intent = out | ||
| [ errflg ] | ||
| standard_name = ccpp_error_code | ||
| units = 1 | ||
| type = integer | ||
| dimensions = () | ||
| intent = out |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| <?xml version="1.0"?> | ||
|
|
||
| <?xml-stylesheet type="text/xsl"?> | ||
|
|
||
| <entry_id_pg version="2.0"> | ||
|
|
||
| <entry id="use_hetfrz_classnuc"> | ||
| <type>logical</type> | ||
| <category>microphys</category> | ||
| <group>hetfrz_classnuc_nl</group> | ||
| <standard_name>do_heterogeneous_ice_nucleation</standard_name> | ||
| <units>flag</units> | ||
| <desc> | ||
| Switch to turn on heterogeneous freezing by classical nucleation theory. | ||
| Currently a stub in CAM-SIMA: the flag is propagated to downstream schemes | ||
| (nucleate_ice_ccpp, eventually PUMAS) but no hetfrz computation is performed. | ||
| Setting this to TRUE is supported for snapshot-testing flows where the flag | ||
| must match CAM; a warning is emitted at init time. | ||
| Default: FALSE; TRUE for CAM6 and CAM7. | ||
| </desc> | ||
| <values> | ||
| <value>.false.</value> | ||
| <value phys_suite="cam6">.true.</value> | ||
| <value phys_suite="cam7">.true.</value> | ||
| </values> | ||
| </entry> | ||
|
|
||
| </entry_id_pg> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -62,8 +62,8 @@ subroutine micro_pumas_ccpp_dimensions_pre_run(ncol, nlev, nlevp1, | |
| pdel_in, pumas_pdel, & | ||
| pint_in, pumas_pint, & | ||
| strat_cldfrc_in, pumas_strat_cldfrc, & | ||
| strat_liq_cldfrc_in, pumas_strat_liq_cldfrc, & | ||
| strat_ice_cldfrc_in, pumas_strat_ice_cldfrc, & | ||
| pumas_strat_liq_cldfrc, & | ||
| pumas_strat_ice_cldfrc, & | ||
| qsatfac_in, pumas_qsatfac, & | ||
| naai_in, pumas_naai, & | ||
| npccn_in, pumas_npccn, & | ||
|
|
@@ -147,10 +147,8 @@ subroutine micro_pumas_ccpp_dimensions_pre_run(ncol, nlev, nlevp1, | |
| real(kind_phys), intent(in) :: strat_cldfrc_in(:, :) | ||
| real(pumas_r8), intent(out) :: pumas_strat_cldfrc(:, :) | ||
| ! Stratiform cloud liquid area fraction (fraction) | ||
| real(kind_phys), intent(in) :: strat_liq_cldfrc_in(:, :) | ||
| real(pumas_r8), intent(out) :: pumas_strat_liq_cldfrc(:, :) | ||
| ! Stratiform cloud ice area fraction (fraction) | ||
| real(kind_phys), intent(in) :: strat_ice_cldfrc_in(:, :) | ||
| real(pumas_r8), intent(out) :: pumas_strat_ice_cldfrc(:, :) | ||
| ! Subgrid cloud water saturation scaling factor (1) | ||
| real(kind_phys), intent(in) :: qsatfac_in(:, :) | ||
|
|
@@ -218,8 +216,10 @@ subroutine micro_pumas_ccpp_dimensions_pre_run(ncol, nlev, nlevp1, | |
| pumas_pdel(:ncol,:) = real(pdel_in(:,:), pumas_r8) | ||
| pumas_pint(:ncol,:) = real(pint_in(:,:micro_nlevp1), pumas_r8) | ||
| pumas_strat_cldfrc(:ncol,:) = real(strat_cldfrc_in(:,:), pumas_r8) | ||
| pumas_strat_liq_cldfrc(:ncol,:) = real(strat_liq_cldfrc_in(:,:), pumas_r8) | ||
| pumas_strat_ice_cldfrc(:ncol,:) = real(strat_ice_cldfrc_in(:,:), pumas_r8) | ||
| ! PUMAS uses total stratiform fraction for both liquid and ice stratus. | ||
| ! Mirrors CAM micro_pumas_cam.F90: alst_mic => ast; aist_mic => ast. | ||
| pumas_strat_liq_cldfrc(:ncol,:) = real(strat_cldfrc_in(:,:), pumas_r8) | ||
| pumas_strat_ice_cldfrc(:ncol,:) = real(strat_cldfrc_in(:,:), pumas_r8) | ||
| pumas_qsatfac(:ncol,:) = real(qsatfac_in(:,:), pumas_r8) | ||
| pumas_naai(:ncol,:) = real(naai_in(:,:), pumas_r8) | ||
| pumas_npccn(:ncol,:) = real(npccn_in(:,:), pumas_r8) | ||
|
|
@@ -230,10 +230,7 @@ subroutine micro_pumas_ccpp_dimensions_pre_run(ncol, nlev, nlevp1, | |
| pumas_effi_external(:ncol,:) = real(effi_external_in(:,:), pumas_r8) | ||
| pumas_frzcnt(:ncol,:) = real(frzcnt_in(:,:), pumas_r8) | ||
| pumas_frzdep(:ncol,:) = real(frzdep_in(:,:), pumas_r8) | ||
|
|
||
| pumas_naai(:,:) = 0._pumas_r8 | ||
| pumas_npccn(:,:) = 0._pumas_r8 | ||
| pumas_qsatfac(:,:) = 0._pumas_r8 | ||
| pumas_frzimm(:ncol,:) = real(frzimm_in(:,:), pumas_r8) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did you get rid of these variables being set to zero? I seem to remember needing to do that a while back for a reason.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NAAI, NPCCN, and QSATFAC are required inputs passed in from microp_aero into PUMAS. The first two don't matter for QPC7 but matter for FHISTC_LTso. They're NaNs in QPC7 but that appears to be fine. QSATFAC's default value is ! The null value for qsatfac is 1, not zero
qsatfac(:ncol,:top_lev-1) = 1._r8
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When I get to the diagnostic's step, will the NAAI and NPCCN need to have values if they are written out. I wish I could remember why I needed to add these.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think they are inputs to PUMAS so there's no diagnostic output for NAAI and NPCCN. I don't think microp_aero writes them out either, but I can add that in my PR. Before I lose this in the terminal scrollback, here's the dropsonde output without the fix: it can be seen that SIMA has all these set to zeroes but CAM has values being read in from the snapshot:
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interestingly, this was the section which impacted the numbers the most. |
||
|
|
||
| end subroutine micro_pumas_ccpp_dimensions_pre_run | ||
|
|
||
|
|
||
| +47 −7 | micro_pumas_ccpp.F90 | |
| +57 −10 | micro_pumas_ccpp.meta | |
| +4 −4 | micro_pumas_tempfix.F90 | |
| +1 −1 | micro_pumas_v1.F90 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| ! Post-processing interstitial for PUMAS. | ||
| module pumas_post_main | ||
| implicit none | ||
| private | ||
|
|
||
| public :: pumas_post_main_run | ||
|
|
||
| contains | ||
|
|
||
| !> \section arg_table_pumas_post_main_run Argument Table | ||
| !! \htmlinclude pumas_post_main_run.html | ||
| subroutine pumas_post_main_run(ncol, cldice, numice, strat_cldfrc, effi, errmsg, errcode) | ||
| use ccpp_kinds, only: kind_phys | ||
| use pumas_kinds, only: pumas_r8=>kind_r8 | ||
| use micro_pumas_utils, only: size_dist_param_basic, mg_ice_props, mincld, qsmall | ||
|
|
||
| integer, intent(in) :: ncol | ||
| real(kind_phys), dimension(:,:), intent(in) :: cldice ! updated cloud ice mixing ratio (kg/kg) | ||
| real(kind_phys), dimension(:,:), intent(in) :: numice ! updated cloud ice number concentration (kg-1) | ||
| real(kind_phys), dimension(:,:), intent(in) :: strat_cldfrc! total stratiform cloud area fraction (= ast) | ||
| real(kind_phys), dimension(:,:), intent(out) :: effi ! ice effective radius (micron) | ||
| character(len=512), intent(out) :: errmsg | ||
| integer, intent(out) :: errcode | ||
|
|
||
| integer :: k, nlev | ||
| real(pumas_r8) :: icimrst(ncol, size(cldice,2)) ! in-cloud (grid-mean) ice mixing ratio | ||
| real(pumas_r8) :: niic(ncol, size(cldice,2)) ! in-cloud (grid-mean) ice number conc | ||
| real(pumas_r8) :: rei(ncol, size(cldice,2)) ! ice slope param, then effective radius | ||
|
|
||
| errmsg = ' ' | ||
| errcode = 0 | ||
|
|
||
| nlev = size(cldice, 2) | ||
|
|
||
| ! Ice effective radius is recomputed here from the post-microphysics | ||
| ! grid-mean in-cloud ice, NOT from the raw per-substep value PUMAS returns. | ||
| ! PUMAS uses the total stratiform fraction for ice cloud (icecldf = ast). | ||
| ! Mirrors CAM micro_pumas_cam.F90:2677 (icimrst), :3174 (niic), :3171-3193 (rei). | ||
| icimrst(:,:) = min(real(cldice(:ncol,:), pumas_r8) / & | ||
| max(mincld, real(strat_cldfrc(:ncol,:), pumas_r8)), 0.005_pumas_r8) | ||
| niic(:,:) = real(numice(:ncol,:), pumas_r8) / & | ||
| max(mincld, real(strat_cldfrc(:ncol,:), pumas_r8)) | ||
|
|
||
| rei(:,:) = 25._pumas_r8 | ||
| do k = 1, nlev | ||
| call size_dist_param_basic(mg_ice_props, icimrst(:,k), niic(:,k), rei(:,k), ncol) | ||
| end do | ||
|
|
||
| where (icimrst(:,:) >= qsmall) | ||
| rei(:,:) = 1.5_pumas_r8 / rei(:,:) * 1.e6_pumas_r8 | ||
| elsewhere | ||
| rei(:,:) = 25._pumas_r8 | ||
| end where | ||
|
|
||
| effi(:ncol,:) = real(rei(:,:), kind_phys) | ||
|
|
||
| end subroutine pumas_post_main_run | ||
|
|
||
| end module pumas_post_main |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| [ccpp-table-properties] | ||
| name = pumas_post_main | ||
| type = scheme | ||
| dependencies = pumas/micro_pumas_utils.F90 | ||
|
|
||
| [ccpp-arg-table] | ||
| name = pumas_post_main_run | ||
| type = scheme | ||
| [ncol] | ||
| standard_name = horizontal_loop_extent | ||
| long_name = number of horizontal columns | ||
| units = count | ||
| dimensions = () | ||
| type = integer | ||
| intent = in | ||
| [cldice] | ||
| standard_name = cloud_ice_mixing_ratio_wrt_moist_air_and_condensed_water | ||
| long_name = cloud ice mixing ratio wrt moist air and condensed water | ||
| units = kg kg-1 | ||
| dimensions = (horizontal_loop_extent, vertical_layer_dimension) | ||
| type = real | ||
| kind = kind_phys | ||
| intent = in | ||
| advected = true | ||
| [numice] | ||
| standard_name = mass_number_concentration_of_ice_wrt_moist_air_and_condensed_water | ||
| long_name = mass number concentration of cloud ice wrt moist air and condensed water | ||
| units = kg-1 | ||
| dimensions = (horizontal_loop_extent, vertical_layer_dimension) | ||
| type = real | ||
| kind = kind_phys | ||
| intent = in | ||
| advected = true | ||
| [strat_cldfrc] | ||
| standard_name = stratiform_cloud_area_fraction | ||
| long_name = stratiform cloud area fraction | ||
| units = fraction | ||
| dimensions = (horizontal_loop_extent, vertical_layer_dimension) | ||
| type = real | ||
| kind = kind_phys | ||
| intent = in | ||
| [effi] | ||
| standard_name = effective_radius_of_stratiform_cloud_ice_particle | ||
| long_name = effective radius of stratiform cloud ice particle | ||
| units = micron | ||
| dimensions = (horizontal_loop_extent, vertical_layer_dimension) | ||
| type = real | ||
| kind = kind_phys | ||
| intent = out | ||
| [errmsg] | ||
| standard_name = ccpp_error_message | ||
| long_name = error message for error handling in CCPP | ||
| units = none | ||
| dimensions = () | ||
| type = character | ||
| kind = len=512 | ||
| intent = out | ||
| [errcode] | ||
| standard_name = ccpp_error_code | ||
| long_name = error code for error handling in CCPP | ||
| units = 1 | ||
| dimensions = () | ||
| type = integer | ||
| intent = out |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for finding this one. That was a tricky one!