diff --git a/applications/lfric_atm/metadata/field_def_diags.xml b/applications/lfric_atm/metadata/field_def_diags.xml
index 5a6a6a360..36f092c6d 100644
--- a/applications/lfric_atm/metadata/field_def_diags.xml
+++ b/applications/lfric_atm/metadata/field_def_diags.xml
@@ -331,6 +331,7 @@
+
diff --git a/interfaces/physics_schemes_interface/source/diagnostics/cld_diags_mod.x90 b/interfaces/physics_schemes_interface/source/diagnostics/cld_diags_mod.x90
index 6b6eb9a40..08e956dd6 100644
--- a/interfaces/physics_schemes_interface/source/diagnostics/cld_diags_mod.x90
+++ b/interfaces/physics_schemes_interface/source/diagnostics/cld_diags_mod.x90
@@ -39,6 +39,7 @@ module cld_diags_mod
cld_amount_maxrnd_flag, &
ceil_cld_amount_maxrnd_flag, &
cld_base_altitude_flag, &
+ cld_top_altitude_flag, &
low_cld_base_altitude_flag, &
very_low_cld_amount_flag, &
low_cld_amount_flag, &
@@ -124,6 +125,7 @@ contains
type( field_type ) :: cld_amount_maxrnd
type( field_type ) :: ceil_cld_amount_maxrnd
type( field_type ) :: cld_base_altitude
+ type( field_type ) :: cld_top_altitude
type( field_type ) :: low_cld_base_altitude
type( field_type ) :: very_low_cld_amount
type( field_type ) :: low_cld_amount
@@ -156,6 +158,7 @@ contains
cld_amount_maxrnd_flag = init_diag(cld_amount_maxrnd, 'cloud__cloud_amount_maxrnd')
ceil_cld_amount_maxrnd_flag = init_diag(ceil_cld_amount_maxrnd, 'cloud__ceilometer_cloud_amount_maxrnd')
cld_base_altitude_flag = init_diag(cld_base_altitude, 'cloud__cloud_base_altitude')
+ cld_top_altitude_flag = init_diag(cld_top_altitude, 'cloud__cloud_top_altitude')
low_cld_base_altitude_flag = init_diag(low_cld_base_altitude, 'cloud__low_cloud_base_altitude')
very_low_cld_amount_flag = init_diag(very_low_cld_amount, 'cloud__very_low_type_cloud_amount')
low_cld_amount_flag = init_diag(low_cld_amount, 'cloud__low_type_cloud_amount')
@@ -176,6 +179,7 @@ contains
cld_amount_maxrnd_flag .or. &
ceil_cld_amount_maxrnd_flag .or. &
cld_base_altitude_flag .or. &
+ cld_top_altitude_flag .or. &
low_cld_base_altitude_flag .or. &
very_low_cld_amount_flag .or. &
low_cld_amount_flag .or. &
@@ -196,6 +200,7 @@ contains
cld_amount_maxrnd_flag .or. &
ceil_cld_amount_maxrnd_flag .or. &
cld_base_altitude_flag .or. &
+ cld_top_altitude_flag .or. &
low_cld_base_altitude_flag .or. &
very_low_cld_amount_flag .or. &
low_cld_amount_flag .or. &
@@ -235,6 +240,7 @@ contains
cld_amount_maxrnd_flag .or. &
ceil_cld_amount_maxrnd_flag .or. &
cld_base_altitude_flag .or. &
+ cld_top_altitude_flag .or. &
low_cld_base_altitude_flag .or. &
very_low_cld_amount_flag .or. &
low_cld_amount_flag .or. &
@@ -256,6 +262,7 @@ contains
cld_amount_maxrnd, &
ceil_cld_amount_maxrnd, &
cld_base_altitude, &
+ cld_top_altitude, &
low_cld_base_altitude, &
very_low_cld_amount, &
low_cld_amount, &
@@ -355,6 +362,7 @@ contains
if (cld_amount_maxrnd_flag) call cld_amount_maxrnd%write_field()
if (ceil_cld_amount_maxrnd_flag) call ceil_cld_amount_maxrnd%write_field()
if (cld_base_altitude_flag) call cld_base_altitude%write_field()
+ if (cld_top_altitude_flag) call cld_top_altitude%write_field()
if (low_cld_base_altitude_flag) call low_cld_base_altitude%write_field()
if (very_low_cld_amount_flag) call very_low_cld_amount%write_field()
if (low_cld_amount_flag) call low_cld_amount%write_field()
diff --git a/interfaces/physics_schemes_interface/source/kernel/cld_diags_kernel_mod.F90 b/interfaces/physics_schemes_interface/source/kernel/cld_diags_kernel_mod.F90
index 9083258ec..20373add8 100644
--- a/interfaces/physics_schemes_interface/source/kernel/cld_diags_kernel_mod.F90
+++ b/interfaces/physics_schemes_interface/source/kernel/cld_diags_kernel_mod.F90
@@ -26,13 +26,14 @@ module cld_diags_kernel_mod
!>
type, public, extends(kernel_type) :: cld_diags_kernel_type
private
- type(arg_type) :: meta_args(20) = (/ &
+ type(arg_type) :: meta_args(21) = (/ &
arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & ! combined_cld_amount_wth
arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1), & ! cld_amount_max
arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1), & ! cld_amount_rnd
arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1), & ! cld_amount_maxrnd
arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1), & ! ceil_cld_amount_maxrnd
arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1), & ! cld_base_altitude
+ arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1), & ! cld_top_altitude
arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1), & ! low_cld_base_altitude
arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1), & ! very_low_cld_amount
arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1), & ! low_cld_amount
@@ -67,6 +68,7 @@ module cld_diags_kernel_mod
!> @param[in,out] cld_amount_maxrnd Cloud amount maximum-random overlap
!> @param[in,out] ceil_cld_amount_maxrnd Ceilometer filtered cloud amount maximum-random overlap
!> @param[in,out] cld_base_altitude Cloud base altitude wrt sea level
+ !> @param[in,out] cld_top_altitude Cloud top altitude wrt sea level
!> @param[in,out] low_cld_base_altitude Cloud base altitude wrt sea level for very low amount of cloud
!> @param[in,out] very_low_cld_amount Maximum cloud amount below 111m
!> @param[in,out] low_cld_amount Maximum cloud amount between 111 and 1949m above sea level
@@ -102,6 +104,7 @@ subroutine cld_diags_code( nlayers, &
cld_amount_maxrnd, &
ceil_cld_amount_maxrnd, &
cld_base_altitude, &
+ cld_top_altitude, &
low_cld_base_altitude, &
very_low_cld_amount, &
low_cld_amount, &
@@ -127,6 +130,7 @@ subroutine cld_diags_code( nlayers, &
map_w3 )
use science_conversions_mod, only: feet_to_metres
+ use missing_data_mod, only: rmdi
implicit none
@@ -145,6 +149,7 @@ subroutine cld_diags_code( nlayers, &
real(kind=r_def), pointer, intent(inout) :: cld_amount_maxrnd(:)
real(kind=r_def), pointer, intent(inout) :: ceil_cld_amount_maxrnd(:)
real(kind=r_def), pointer, intent(inout) :: cld_base_altitude(:)
+ real(kind=r_def), pointer, intent(inout) :: cld_top_altitude(:)
real(kind=r_def), pointer, intent(inout) :: low_cld_base_altitude(:)
real(kind=r_def), pointer, intent(inout) :: very_low_cld_amount(:)
real(kind=r_def), pointer, intent(inout) :: low_cld_amount(:)
@@ -181,8 +186,8 @@ subroutine cld_diags_code( nlayers, &
real(kind=r_def), parameter :: medium_to_high = 5574.0_r_def ! metres
! ... 150 hPa:
real(kind=r_def), parameter :: high_to_very_high = 13608.0_r_def ! metres
- ! When looking for cloud base: how much cloud cover defines cloud base.
- real(kind=r_def), parameter :: cld_cover_for_cld_base = 2.5_r_def/8.0_r_def
+ ! When looking for cloud base or top: how much cloud cover defines cloud boundary.
+ real(kind=r_def), parameter :: cld_cover_for_cld_bdry = 2.5_r_def/8.0_r_def
! When looking for cloud base sometimes want much smaller amount of cloud.
real(kind=r_def), parameter :: low_cld_cover_for_cld_base = 0.05_r_def
! For tracking whether cloud has been found.
@@ -306,6 +311,7 @@ subroutine cld_diags_code( nlayers, &
! Find heights above sea level (asl) if required.
if (.not. associated(cld_base_altitude, empty_real_data) .or. &
+ .not. associated(cld_top_altitude, empty_real_data) .or. &
.not. associated(low_cld_base_altitude, empty_real_data) .or. &
.not. associated(very_low_cld_amount, empty_real_data) .or. &
.not. associated(low_cld_amount, empty_real_data) .or. &
@@ -331,13 +337,26 @@ subroutine cld_diags_code( nlayers, &
m_to_kfeet
do k = 1, nlayers
- if ( combined_cld_amount(k) >= cld_cover_for_cld_base ) then
+ if ( combined_cld_amount(k) >= cld_cover_for_cld_bdry ) then
cld_base_altitude(map_2d(1)) = z_asl_base_of_levels(k) * m_to_kfeet
exit
end if
end do
end if
+ ! cld_top_altitude (in kilofeet)
+ if (.not. associated(cld_top_altitude, empty_real_data) ) then
+ ! As a default, set cloud-top to missing data
+ cld_top_altitude(map_2d(1)) = rmdi
+
+ do k = nlayers-1, 1, -1
+ if ( combined_cld_amount(k) >= cld_cover_for_cld_bdry ) then
+ cld_top_altitude(map_2d(1)) = z_asl_base_of_levels(k+1) * m_to_kfeet
+ exit
+ end if
+ end do
+ end if
+
! low_cld_base_altitude (in feet) for low threshold cloud amounts
if (.not. associated(low_cld_base_altitude, empty_real_data) ) then
! As a default, set cloud-base to beyond top of model