From 991e164f8941834c286d67fbf6e10287707c04b3 Mon Sep 17 00:00:00 2001 From: MarionBWeinzierl Date: Wed, 11 Dec 2024 03:15:47 -0700 Subject: [PATCH 01/12] implement energy and water checker for yog --- src/physics/cam/nn_interface_cam.F90 | 41 ++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/physics/cam/nn_interface_cam.F90 b/src/physics/cam/nn_interface_cam.F90 index a8a60231d5..a03d70fec1 100644 --- a/src/physics/cam/nn_interface_cam.F90 +++ b/src/physics/cam/nn_interface_cam.F90 @@ -13,6 +13,9 @@ module nn_interface_CAM fac_cond, fac_sub, fac_fus, & a_bg, a_pr, an, bn, ap, bp, & omegan, check +use physconst, only: gravit, cpairv +use ppgrid, only: pcols, pver, begchunk, endchunk +use cam_logfile, only: iulog implicit none private @@ -20,7 +23,7 @@ module nn_interface_CAM !--------------------------------------------------------------------- ! public interfaces -public nn_convection_flux_CAM, & +public nn_convection_flux_CAM, yog_conservation_check, & nn_convection_flux_CAM_init, nn_convection_flux_CAM_finalize ! Make these routines public for purposes of testing, @@ -71,6 +74,39 @@ subroutine nn_convection_flux_CAM_init(nn_filename, sounding_filename) end subroutine nn_convection_flux_CAM_init + subroutine yog_conservation_check(pdel, t, qv, qc, qi, & + ncol) + + real(8), intent(in) :: pdel(:,:) + real(8), intent(in) :: t(:,:) + real(8), intent(in) :: qv(:,:), qc(:,:), qi(:, :) + real(8) :: se(ncol) ! sum energy + real(8) :: sw(ncol) ! sum water + real(8) :: wv(ncol), wl(ncol), wi(ncol) + +! integer, intent(in) :: lchnk ! chunk identifier + integer, intent(in) :: ncol ! number of atmospheric columns + integer i,k ! column, level indices + + do i = 1, ncol + se(i) = 0 + wv(i) = 0 + wl(i) = 0 + wi(i) = 0 + sw(i) = 0 + do k = 1, pver + se(i) = se(i) + t(i,k) *cpairv(i, k, begchunk)*pdel(i,k)/gravit + wv(i) = wv(i) + qv(i,k) *pdel(i,k)/gravit + wl(i) = wl(i) + qc(i,k) *pdel(i,k)/gravit + wi(i) = wi(i) + qi(i,k) *pdel(i,k)/gravit + sw(i) = wv(i) + wl(i) + wi(i) + end do + end do + + write(iulog, *), "Energy sum: ", se + write(iulog, *), "Water sum: ", sw + + end subroutine yog_conservation_check subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & tabs_cam, qv_cam, qc_cam, qi_cam, & @@ -126,7 +162,8 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & ! Initialise precipitation to 0 if required and at start of cycle if subcycling precsfc(:)=0. - + !----------------------------------------------------- + call yog_conservation_check(pres_cam, tabs_cam, qv_cam, qc_cam, qi_cam, ncol) !----------------------------------------------------- ! Interpolate CAM variables to the SAM pressure levels From d30502355fa76bf2fc38615fda961b19b788d9a7 Mon Sep 17 00:00:00 2001 From: MarionBWeinzierl Date: Fri, 13 Dec 2024 03:34:20 -0700 Subject: [PATCH 02/12] changed cpair and pdel in conservation check and added call --- src/physics/cam/nn_interface_cam.F90 | 31 +++++++++++++++++----------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/physics/cam/nn_interface_cam.F90 b/src/physics/cam/nn_interface_cam.F90 index a03d70fec1..5ebd8a2677 100644 --- a/src/physics/cam/nn_interface_cam.F90 +++ b/src/physics/cam/nn_interface_cam.F90 @@ -13,7 +13,7 @@ module nn_interface_CAM fac_cond, fac_sub, fac_fus, & a_bg, a_pr, an, bn, ap, bp, & omegan, check -use physconst, only: gravit, cpairv +use physconst, only: gravit, cpairv, cpair use ppgrid, only: pcols, pver, begchunk, endchunk use cam_logfile, only: iulog @@ -88,17 +88,20 @@ subroutine yog_conservation_check(pdel, t, qv, qc, qi, & integer, intent(in) :: ncol ! number of atmospheric columns integer i,k ! column, level indices + se = 0.0 + wv = 0.0 + wl = 0.0 + wi = 0.0 + sw = 0.0 + + pdel_c = pdel(:, pver-1) - pdel(:, 2:pver) + do i = 1, ncol - se(i) = 0 - wv(i) = 0 - wl(i) = 0 - wi(i) = 0 - sw(i) = 0 - do k = 1, pver - se(i) = se(i) + t(i,k) *cpairv(i, k, begchunk)*pdel(i,k)/gravit - wv(i) = wv(i) + qv(i,k) *pdel(i,k)/gravit - wl(i) = wl(i) + qc(i,k) *pdel(i,k)/gravit - wi(i) = wi(i) + qi(i,k) *pdel(i,k)/gravit + do k = 1, pver-1 + se(i) = se(i) + t(i,k) *cpair*pdel_c(i,k)/gravit + wv(i) = wv(i) + qv(i,k) *pdel_c(i,k)/gravit + wl(i) = wl(i) + qc(i,k) *pdel_c(i,k)/gravit + wi(i) = wi(i) + qi(i,k) *pdel_c(i,k)/gravit sw(i) = wv(i) + wl(i) + wi(i) end do end do @@ -163,7 +166,8 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & ! Initialise precipitation to 0 if required and at start of cycle if subcycling precsfc(:)=0. !----------------------------------------------------- - call yog_conservation_check(pres_cam, tabs_cam, qv_cam, qc_cam, qi_cam, ncol) + write(iulog, *), "Before conversion:" + call yog_conservation_check(pres_int_cam, tabs_cam, qv_cam, qc_cam, qi_cam, ncol) !----------------------------------------------------- ! Interpolate CAM variables to the SAM pressure levels @@ -234,6 +238,9 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & ! Convert precipitation from kg/m^2 to m by dividing by density (1000) precsfc = precsfc * 1.0D-3 + !----------------------------------------------------- + write(iulog, *), "After conversion:" + call yog_conservation_check(presi, tabs_sam, qv_sam, qc_sam, qi_sam, ncol) !----------------------------------------------------- ! Convert back into CAM variable tendencies (diff div by dtn) on SAM grid From 4e74c88138aa78a4f703919bb901ebad6351b147 Mon Sep 17 00:00:00 2001 From: MarionBWeinzierl Date: Fri, 13 Dec 2024 03:56:19 -0700 Subject: [PATCH 03/12] corrected array stuff --- src/physics/cam/nn_interface_cam.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/physics/cam/nn_interface_cam.F90 b/src/physics/cam/nn_interface_cam.F90 index 5ebd8a2677..927170921a 100644 --- a/src/physics/cam/nn_interface_cam.F90 +++ b/src/physics/cam/nn_interface_cam.F90 @@ -80,6 +80,7 @@ subroutine yog_conservation_check(pdel, t, qv, qc, qi, & real(8), intent(in) :: pdel(:,:) real(8), intent(in) :: t(:,:) real(8), intent(in) :: qv(:,:), qc(:,:), qi(:, :) + real(8) :: pdel_c(ncol, pver-1) real(8) :: se(ncol) ! sum energy real(8) :: sw(ncol) ! sum water real(8) :: wv(ncol), wl(ncol), wi(ncol) @@ -94,7 +95,7 @@ subroutine yog_conservation_check(pdel, t, qv, qc, qi, & wi = 0.0 sw = 0.0 - pdel_c = pdel(:, pver-1) - pdel(:, 2:pver) + pdel_c = pdel(:, :pver-1) - pdel(:, 2:pver) do i = 1, ncol do k = 1, pver-1 From 368ab87d5b756ea2fcea9ce4b2985b8874e0c4d0 Mon Sep 17 00:00:00 2001 From: MarionBWeinzierl Date: Mon, 16 Dec 2024 07:04:02 -0700 Subject: [PATCH 04/12] need to adapt second call to checker, comment out for now --- src/physics/cam/nn_interface_cam.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/physics/cam/nn_interface_cam.F90 b/src/physics/cam/nn_interface_cam.F90 index 927170921a..ffa4fdfaef 100644 --- a/src/physics/cam/nn_interface_cam.F90 +++ b/src/physics/cam/nn_interface_cam.F90 @@ -241,7 +241,8 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & !----------------------------------------------------- write(iulog, *), "After conversion:" - call yog_conservation_check(presi, tabs_sam, qv_sam, qc_sam, qi_sam, ncol) + !!presi has just one dimension + !!call yog_conservation_check(presi, tabs_sam, qv_sam, qc_sam, qi_sam, ncol) !----------------------------------------------------- ! Convert back into CAM variable tendencies (diff div by dtn) on SAM grid From 8166892a2274619534cc59b71f3245753b3fbc8c Mon Sep 17 00:00:00 2001 From: MarionBWeinzierl Date: Wed, 18 Dec 2024 06:15:43 -0700 Subject: [PATCH 05/12] renamed pdel, and created a presi array for the energy checker --- src/physics/cam/nn_interface_cam.F90 | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/physics/cam/nn_interface_cam.F90 b/src/physics/cam/nn_interface_cam.F90 index ffa4fdfaef..4a604ffb5d 100644 --- a/src/physics/cam/nn_interface_cam.F90 +++ b/src/physics/cam/nn_interface_cam.F90 @@ -74,13 +74,13 @@ subroutine nn_convection_flux_CAM_init(nn_filename, sounding_filename) end subroutine nn_convection_flux_CAM_init - subroutine yog_conservation_check(pdel, t, qv, qc, qi, & + subroutine yog_conservation_check(p_int, t, qv, qc, qi, & ncol) - real(8), intent(in) :: pdel(:,:) + real(8), intent(in) :: p_int(:,:) real(8), intent(in) :: t(:,:) real(8), intent(in) :: qv(:,:), qc(:,:), qi(:, :) - real(8) :: pdel_c(ncol, pver-1) + real(8) :: pdel(ncol, pver-1) real(8) :: se(ncol) ! sum energy real(8) :: sw(ncol) ! sum water real(8) :: wv(ncol), wl(ncol), wi(ncol) @@ -95,14 +95,14 @@ subroutine yog_conservation_check(pdel, t, qv, qc, qi, & wi = 0.0 sw = 0.0 - pdel_c = pdel(:, :pver-1) - pdel(:, 2:pver) + pdel = p_int(:, :pver-1) - p_int(:, 2:pver) do i = 1, ncol do k = 1, pver-1 - se(i) = se(i) + t(i,k) *cpair*pdel_c(i,k)/gravit - wv(i) = wv(i) + qv(i,k) *pdel_c(i,k)/gravit - wl(i) = wl(i) + qc(i,k) *pdel_c(i,k)/gravit - wi(i) = wi(i) + qi(i,k) *pdel_c(i,k)/gravit + se(i) = se(i) + t(i,k) *cpair*pdel(i,k)/gravit + wv(i) = wv(i) + qv(i,k) *pdel(i,k)/gravit + wl(i) = wl(i) + qc(i,k) *pdel(i,k)/gravit + wi(i) = wi(i) + qi(i,k) *pdel(i,k)/gravit sw(i) = wv(i) + wl(i) + wi(i) end do end do @@ -161,6 +161,8 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & !! Distance of column from equator (proxy for insolation and sfc albedo) real(8), dimension(ncol) :: precsfc_i !! precipitation at surface from one call to parameterisation + real(8) :: presi_col(ncol, n_sam_lev) + !! presi repeated ncol times along one dimension, for energy and water checker integer :: k @@ -241,8 +243,12 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & !----------------------------------------------------- write(iulog, *), "After conversion:" - !!presi has just one dimension - !!call yog_conservation_check(presi, tabs_sam, qv_sam, qc_sam, qi_sam, ncol) + !!presi has just one dimension, so we need to repeat it ncol times to get the required input for the checker + do i = 1, ncol + presi_col(i, :) = presi(:) + end do + + call yog_conservation_check(presi_col, tabs_sam, qv_sam, qc_sam, qi_sam, ncol) !----------------------------------------------------- ! Convert back into CAM variable tendencies (diff div by dtn) on SAM grid From 61002a3f20af42684af0863404800d8e224aa55a Mon Sep 17 00:00:00 2001 From: MarionBWeinzierl Date: Wed, 18 Dec 2024 08:13:28 -0700 Subject: [PATCH 06/12] use nz_sam instead of n_sam_lev --- src/physics/cam/nn_interface_cam.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/physics/cam/nn_interface_cam.F90 b/src/physics/cam/nn_interface_cam.F90 index 4a604ffb5d..019a8465f6 100644 --- a/src/physics/cam/nn_interface_cam.F90 +++ b/src/physics/cam/nn_interface_cam.F90 @@ -161,10 +161,10 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & !! Distance of column from equator (proxy for insolation and sfc albedo) real(8), dimension(ncol) :: precsfc_i !! precipitation at surface from one call to parameterisation - real(8) :: presi_col(ncol, n_sam_lev) + real(8) :: presi_col(ncol, nz_sam) !! presi repeated ncol times along one dimension, for energy and water checker - integer :: k + integer :: i,k ! Initialise precipitation to 0 if required and at start of cycle if subcycling precsfc(:)=0. From 839baa5c858c368d675337bbfa00b7b6ef5b2c54 Mon Sep 17 00:00:00 2001 From: MarionBWeinzierl Date: Wed, 18 Dec 2024 09:46:16 -0700 Subject: [PATCH 07/12] make vertical level an input parameter --- src/physics/cam/nn_interface_cam.F90 | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/physics/cam/nn_interface_cam.F90 b/src/physics/cam/nn_interface_cam.F90 index 019a8465f6..4bb053a423 100644 --- a/src/physics/cam/nn_interface_cam.F90 +++ b/src/physics/cam/nn_interface_cam.F90 @@ -75,18 +75,19 @@ subroutine nn_convection_flux_CAM_init(nn_filename, sounding_filename) end subroutine nn_convection_flux_CAM_init subroutine yog_conservation_check(p_int, t, qv, qc, qi, & - ncol) + ncol, nver) real(8), intent(in) :: p_int(:,:) real(8), intent(in) :: t(:,:) real(8), intent(in) :: qv(:,:), qc(:,:), qi(:, :) - real(8) :: pdel(ncol, pver-1) + real(8) :: pdel(ncol, nver-1) real(8) :: se(ncol) ! sum energy real(8) :: sw(ncol) ! sum water real(8) :: wv(ncol), wl(ncol), wi(ncol) ! integer, intent(in) :: lchnk ! chunk identifier integer, intent(in) :: ncol ! number of atmospheric columns + integer, intent(in) :: nver ! number of vertical levels integer i,k ! column, level indices se = 0.0 @@ -95,10 +96,10 @@ subroutine yog_conservation_check(p_int, t, qv, qc, qi, & wi = 0.0 sw = 0.0 - pdel = p_int(:, :pver-1) - p_int(:, 2:pver) + pdel = p_int(:, :nver-1) - p_int(:, 2:nver) do i = 1, ncol - do k = 1, pver-1 + do k = 1, nver-1 se(i) = se(i) + t(i,k) *cpair*pdel(i,k)/gravit wv(i) = wv(i) + qv(i,k) *pdel(i,k)/gravit wl(i) = wl(i) + qc(i,k) *pdel(i,k)/gravit @@ -170,7 +171,7 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & precsfc(:)=0. !----------------------------------------------------- write(iulog, *), "Before conversion:" - call yog_conservation_check(pres_int_cam, tabs_cam, qv_cam, qc_cam, qi_cam, ncol) + call yog_conservation_check(pres_int_cam, tabs_cam, qv_cam, qc_cam, qi_cam, ncol, pver) !----------------------------------------------------- ! Interpolate CAM variables to the SAM pressure levels @@ -248,7 +249,7 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & presi_col(i, :) = presi(:) end do - call yog_conservation_check(presi_col, tabs_sam, qv_sam, qc_sam, qi_sam, ncol) + call yog_conservation_check(presi_col, tabs_sam, qv_sam, qc_sam, qi_sam, ncol, nz_sam) !----------------------------------------------------- ! Convert back into CAM variable tendencies (diff div by dtn) on SAM grid From a38ebb6135f40d5ddd3b6d0c76f7b3a6e3e29b57 Mon Sep 17 00:00:00 2001 From: MarionBWeinzierl Date: Fri, 20 Dec 2024 03:59:45 -0700 Subject: [PATCH 08/12] nrf instead of nz_sam as input/array size --- src/physics/cam/nn_interface_cam.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/physics/cam/nn_interface_cam.F90 b/src/physics/cam/nn_interface_cam.F90 index 4bb053a423..781918a2fe 100644 --- a/src/physics/cam/nn_interface_cam.F90 +++ b/src/physics/cam/nn_interface_cam.F90 @@ -249,7 +249,7 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & presi_col(i, :) = presi(:) end do - call yog_conservation_check(presi_col, tabs_sam, qv_sam, qc_sam, qi_sam, ncol, nz_sam) + call yog_conservation_check(presi_col, tabs_sam, qv_sam, qc_sam, qi_sam, ncol, nrf) !----------------------------------------------------- ! Convert back into CAM variable tendencies (diff div by dtn) on SAM grid From 6e1b04ab703048222115a0d6246665d57f03337c Mon Sep 17 00:00:00 2001 From: MarionBWeinzierl Date: Fri, 20 Dec 2024 09:07:41 -0700 Subject: [PATCH 09/12] add some comments for better understanding --- src/physics/cam/nn_interface_cam.F90 | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/physics/cam/nn_interface_cam.F90 b/src/physics/cam/nn_interface_cam.F90 index 781918a2fe..c4b75d7b2a 100644 --- a/src/physics/cam/nn_interface_cam.F90 +++ b/src/physics/cam/nn_interface_cam.F90 @@ -76,16 +76,17 @@ end subroutine nn_convection_flux_CAM_init subroutine yog_conservation_check(p_int, t, qv, qc, qi, & ncol, nver) + ! Use this function to check the energy and water conversation by outputting the + ! respective sums. + + real(8), intent(in) :: p_int(:,:) ! pressure on grid + real(8), intent(in) :: t(:,:) ! temperature + real(8), intent(in) :: qv(:,:), qc(:,:), qi(:, :) ! moisture components: water vapor, cloud water, cloud ice + real(8) :: pdel(ncol, nver-1) ! pressure in grid cell + real(8) :: se(ncol) ! sum of energy + real(8) :: sw(ncol) ! sum of water + real(8) :: wv(ncol), wl(ncol), wi(ncol) ! water components: vapor, liquid, ice - real(8), intent(in) :: p_int(:,:) - real(8), intent(in) :: t(:,:) - real(8), intent(in) :: qv(:,:), qc(:,:), qi(:, :) - real(8) :: pdel(ncol, nver-1) - real(8) :: se(ncol) ! sum energy - real(8) :: sw(ncol) ! sum water - real(8) :: wv(ncol), wl(ncol), wi(ncol) - -! integer, intent(in) :: lchnk ! chunk identifier integer, intent(in) :: ncol ! number of atmospheric columns integer, intent(in) :: nver ! number of vertical levels integer i,k ! column, level indices @@ -96,10 +97,11 @@ subroutine yog_conservation_check(p_int, t, qv, qc, qi, & wi = 0.0 sw = 0.0 + ! get the values in the grid cell from those on the edges pdel = p_int(:, :nver-1) - p_int(:, 2:nver) - do i = 1, ncol - do k = 1, nver-1 + do i = 1, ncol ! run over the columns + do k = 1, nver-1 ! run over the vertical levels se(i) = se(i) + t(i,k) *cpair*pdel(i,k)/gravit wv(i) = wv(i) + qv(i,k) *pdel(i,k)/gravit wl(i) = wl(i) + qc(i,k) *pdel(i,k)/gravit From 1cf5d9c84146c42421211b35c59ec25625352e1c Mon Sep 17 00:00:00 2001 From: MarionBWeinzierl Date: Wed, 8 Jan 2025 09:50:48 -0700 Subject: [PATCH 10/12] convert presi from hPa to Pa --- src/physics/cam/nn_interface_cam.F90 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/physics/cam/nn_interface_cam.F90 b/src/physics/cam/nn_interface_cam.F90 index c4b75d7b2a..145f9e1a59 100644 --- a/src/physics/cam/nn_interface_cam.F90 +++ b/src/physics/cam/nn_interface_cam.F90 @@ -246,9 +246,10 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & !----------------------------------------------------- write(iulog, *), "After conversion:" - !!presi has just one dimension, so we need to repeat it ncol times to get the required input for the checker + !!presi has just one dimension, so we need to repeat it ncol times to get the required input for the checker. + !!Also, convert from hPa to Pa do i = 1, ncol - presi_col(i, :) = presi(:) + presi_col(i, :) = presi(:)*100.0 end do call yog_conservation_check(presi_col, tabs_sam, qv_sam, qc_sam, qi_sam, ncol, nrf) From 292fbfdcc9d24088b76c1c47bd62363661434396 Mon Sep 17 00:00:00 2001 From: jatkinson1000 Date: Thu, 9 Jan 2025 03:49:34 -0700 Subject: [PATCH 11/12] Add code to apply tendencies from YOG to CAM inputs and check energy/mass conservation on CAM grid after YOG. --- src/physics/cam/nn_interface_cam.F90 | 36 +++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/physics/cam/nn_interface_cam.F90 b/src/physics/cam/nn_interface_cam.F90 index 145f9e1a59..e3a256c1ba 100644 --- a/src/physics/cam/nn_interface_cam.F90 +++ b/src/physics/cam/nn_interface_cam.F90 @@ -167,6 +167,14 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & real(8) :: presi_col(ncol, nz_sam) !! presi repeated ncol times along one dimension, for energy and water checker + + ! Variables for the energy checker calculations at the end of the code + real(8), dimension(:,:), allocatable :: tabs_cam_out + !! absolute temperature [K] to the CAM model + real(8), dimension(:,:), allocatable :: qv_cam_out, qc_cam_out, qi_cam_out + !! moisture content [kg/kg] to the CAM model + integer :: ncol_chnk, nver_chnk + integer :: i,k ! Initialise precipitation to 0 if required and at start of cycle if subcycling @@ -245,7 +253,7 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & precsfc = precsfc * 1.0D-3 !----------------------------------------------------- - write(iulog, *), "After conversion:" + write(iulog, *), "After YOG NN:" !!presi has just one dimension, so we need to repeat it ncol times to get the required input for the checker. !!Also, convert from hPa to Pa do i = 1, ncol @@ -274,6 +282,32 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & call interp_to_cam(pres_cam(1:ncol, :), pres_int_cam(1:ncol, :), pres_sfc_cam(1:ncol), dqi_sam, dqi(1:ncol, :)) call interp_to_cam(pres_cam(1:ncol, :), pres_int_cam(1:ncol, :), pres_sfc_cam(1:ncol), ds_sam, ds(1:ncol, :)) + !----------------------------------------------------- + ! For purposes of investigating energy conservation apply the tendencies on the + ! CAM grid to the CAM inputs, and apply the Marion conservation checker to see + ! if values are consistent with the inputs before the parameterisation. + ncol_chnk = size(tabs_cam, 1) + nver_chnk = size(tabs_cam, 2) + allocate(tabs_cam_out(ncol_chnk,nver_chnk)) + allocate(qv_cam_out(ncol_chnk,nver_chnk)) + allocate(qc_cam_out(ncol_chnk,nver_chnk)) + allocate(qi_cam_out(ncol_chnk,nver_chnk)) + + tabs_cam_out = tabs_cam + dtn * ds / cp_cam + qv_cam_out = qv_cam + dtn * dqv + qc_cam_out = qc_cam + dtn * dqc + qi_cam_out = qi_cam + dtn * dqi + + write(iulog, *), "After conversion back:" + call yog_conservation_check(pres_int_cam, tabs_cam_out, qv_cam_out, qc_cam_out, qi_cam_out, ncol, pver) + + deallocate(tabs_cam_out) + deallocate(qv_cam_out) + deallocate(qc_cam_out) + deallocate(qi_cam_out) + + + end subroutine nn_convection_flux_CAM From 34c0ab36a8d67987b71df50a2bf24ac0d385c865 Mon Sep 17 00:00:00 2001 From: jatkinson1000 Date: Thu, 9 Jan 2025 08:21:36 -0700 Subject: [PATCH 12/12] Include precipitation in the YOG conservation check. --- src/physics/cam/nn_interface_cam.F90 | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/physics/cam/nn_interface_cam.F90 b/src/physics/cam/nn_interface_cam.F90 index e3a256c1ba..0832e524ee 100644 --- a/src/physics/cam/nn_interface_cam.F90 +++ b/src/physics/cam/nn_interface_cam.F90 @@ -74,7 +74,7 @@ subroutine nn_convection_flux_CAM_init(nn_filename, sounding_filename) end subroutine nn_convection_flux_CAM_init - subroutine yog_conservation_check(p_int, t, qv, qc, qi, & + subroutine yog_conservation_check(p_int, t, qv, qc, qi, prec, & ncol, nver) ! Use this function to check the energy and water conversation by outputting the ! respective sums. @@ -82,6 +82,7 @@ subroutine yog_conservation_check(p_int, t, qv, qc, qi, & real(8), intent(in) :: p_int(:,:) ! pressure on grid real(8), intent(in) :: t(:,:) ! temperature real(8), intent(in) :: qv(:,:), qc(:,:), qi(:, :) ! moisture components: water vapor, cloud water, cloud ice + real(8), intent(in) :: prec(:) !! precipitation that has come out of the column real(8) :: pdel(ncol, nver-1) ! pressure in grid cell real(8) :: se(ncol) ! sum of energy real(8) :: sw(ncol) ! sum of water @@ -112,6 +113,7 @@ subroutine yog_conservation_check(p_int, t, qv, qc, qi, & write(iulog, *), "Energy sum: ", se write(iulog, *), "Water sum: ", sw + write(iulog, *), "Water + prec: ", sw + prec end subroutine yog_conservation_check @@ -171,6 +173,8 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & ! Variables for the energy checker calculations at the end of the code real(8), dimension(:,:), allocatable :: tabs_cam_out !! absolute temperature [K] to the CAM model + real(8), dimension(:), allocatable :: prec_cam_out + !! precipitation to the CAM model real(8), dimension(:,:), allocatable :: qv_cam_out, qc_cam_out, qi_cam_out !! moisture content [kg/kg] to the CAM model integer :: ncol_chnk, nver_chnk @@ -181,7 +185,7 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & precsfc(:)=0. !----------------------------------------------------- write(iulog, *), "Before conversion:" - call yog_conservation_check(pres_int_cam, tabs_cam, qv_cam, qc_cam, qi_cam, ncol, pver) + call yog_conservation_check(pres_int_cam, tabs_cam, qv_cam, qc_cam, qi_cam, precsfc, ncol, pver) !----------------------------------------------------- ! Interpolate CAM variables to the SAM pressure levels @@ -260,7 +264,7 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & presi_col(i, :) = presi(:)*100.0 end do - call yog_conservation_check(presi_col, tabs_sam, qv_sam, qc_sam, qi_sam, ncol, nrf) + call yog_conservation_check(presi_col, tabs_sam, qv_sam, qc_sam, qi_sam, precsfc, ncol, nrf) !----------------------------------------------------- ! Convert back into CAM variable tendencies (diff div by dtn) on SAM grid @@ -292,19 +296,22 @@ subroutine nn_convection_flux_CAM(pres_cam, pres_int_cam, pres_sfc_cam, & allocate(qv_cam_out(ncol_chnk,nver_chnk)) allocate(qc_cam_out(ncol_chnk,nver_chnk)) allocate(qi_cam_out(ncol_chnk,nver_chnk)) + allocate(prec_cam_out(ncol_chnk)) tabs_cam_out = tabs_cam + dtn * ds / cp_cam qv_cam_out = qv_cam + dtn * dqv qc_cam_out = qc_cam + dtn * dqc qi_cam_out = qi_cam + dtn * dqi + prec_cam_out = dtn * precsfc write(iulog, *), "After conversion back:" - call yog_conservation_check(pres_int_cam, tabs_cam_out, qv_cam_out, qc_cam_out, qi_cam_out, ncol, pver) + call yog_conservation_check(pres_int_cam, tabs_cam_out, qv_cam_out, qc_cam_out, qi_cam_out, prec_cam_out, ncol, pver) deallocate(tabs_cam_out) deallocate(qv_cam_out) deallocate(qc_cam_out) deallocate(qi_cam_out) + deallocate(prec_cam_out)