Skip to content
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

Implementation of CCPP-ized tropopause_find #112

Merged
merged 33 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ebe25e3
Merge pull request #106 from ESCOMP/development
nusbaume Jul 25, 2024
a0fa36a
Setup Test SDF, copy existing tropopause.F90
jimmielin Aug 13, 2024
bf224a5
Initial updates for CCPP-ization:
jimmielin Aug 13, 2024
6e11a3b
Continue CCPP-ization of fields; split into diagnostics; read_file sp…
jimmielin Aug 14, 2024
d37246a
Add metadata and namelist for test build
jimmielin Aug 15, 2024
72ed07d
Remove incompatible hardcoded dimension; fix dimension for tropp_p_lo…
jimmielin Aug 15, 2024
bbf785b
Fix wrong intents and types
jimmielin Aug 15, 2024
cd76504
Add scheme_name for tropopause_find_run
jimmielin Aug 15, 2024
fd91d53
Delete tropopause_nl from scheme and move to CAM
jimmielin Aug 15, 2024
1d4f92a
Remove USE statements and replace with CCPP-ized error handling
jimmielin Aug 15, 2024
2a1b626
Fix compile type mismatches, duplicate local variable decls from phys…
jimmielin Aug 15, 2024
a6d9967
Removal of POINTERs per CCPP-convention
jimmielin Aug 15, 2024
b38715b
Prepare for multiple scheme calculation; setup for History diagnostics
jimmielin Aug 19, 2024
1cc3e24
Add history diagnostics for tropopause_find (initial)
jimmielin Aug 19, 2024
470ad75
Add metadata to tropopause_diagnostics
jimmielin Aug 19, 2024
b37c251
Fixes for building tropopause_diagnostics
jimmielin Aug 20, 2024
177b6e5
Correctly support findChemTrop using the new CHEMTROP option
jimmielin Aug 20, 2024
948d4da
Fix tropp_days is fraction day-of-year
jimmielin Aug 20, 2024
ac9a461
Merge branch 'development' into hplin/tropopause_find
jimmielin Aug 22, 2024
8498efc
Update with metadata in preparation for pull request
jimmielin Aug 22, 2024
56415e8
Add TROPP (primary only) output; fix intents in tropopause_diagnostic…
jimmielin Aug 23, 2024
f3838c4
Add TROPP (primary only) history field definition
jimmielin Aug 23, 2024
2b1d98e
Remove geopotential_temp from test SDF for tropopause_find
jimmielin Aug 23, 2024
4ea57ff
First batch of updates for review comments, including standard name u…
jimmielin Sep 3, 2024
113d041
Update CCPP standard names
jimmielin Sep 3, 2024
5355723
Cleanup: Remove unused variables in tropopause_find
jimmielin Sep 3, 2024
5d4a18d
Make 'fillvalue' an input argument instead of a local parameter.
nusbaume Sep 6, 2024
d400fb2
Update tropopause_find/tropopause_find.F90
jimmielin Sep 10, 2024
d9a5686
Update in response to code review comments
jimmielin Sep 12, 2024
b9e485b
Update standard name to tropopause_air_pressure_from_climatology_data…
jimmielin Sep 18, 2024
391c114
Remove recursive call to findUsing from findChemTrop
jimmielin Sep 23, 2024
7e73d8a
Make findWithBackup (not CCPP-run routine) optional arguments again
jimmielin Sep 24, 2024
886c895
Changes to findChemTrop to propagate OPTIONAL arguments
jimmielin Sep 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
220 changes: 220 additions & 0 deletions cam_diagnostics/tropopause_diagnostics.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
module tropopause_diagnostics
! ... output tropopause diagnostics within CAM-SIMA
use ccpp_kinds, only: kind_phys

implicit none
private

! CCPP-compliant subroutines
public :: tropopause_diagnostics_init
public :: tropopause_diagnostics_run

! Parameters consistent with tropopause_find - can they be imported?
cacraigucar marked this conversation as resolved.
Show resolved Hide resolved
integer, parameter :: NOTFOUND = -1

contains
! Initialize the output history fields.
!> \section arg_table_tropopause_diagnostics_init Argument Table
!! \htmlinclude tropopause_diagnostics_init.html
subroutine tropopause_diagnostics_init(errmsg, errflg)

use cam_history, only: history_add_field
use cam_history_support, only: horiz_only

character(len=512), intent(out) :: errmsg
integer, intent(out) :: errflg

errmsg = ' '
errflg = 0

! Define the output fields.

! Primary (Lapse rate) + backup (climatology) method
call history_add_field('TROP_P', 'tropopause_air_pressure', horiz_only, 'avg', 'Pa')
cacraigucar marked this conversation as resolved.
Show resolved Hide resolved
call history_add_field('TROP_T', 'tropopause_air_temperature', horiz_only, 'avg', 'K' )
call history_add_field('TROP_Z', 'tropopause_geopotential_height_wrt_surface', horiz_only, 'avg', 'm' )
call history_add_field('TROP_DZ', 'geopotential_height_difference_between_atmosphere_layer_and_tropopause', 'lev', 'avg', 'm')
call history_add_field('TROP_PD', 'probability_distribution_of_tropopause_vertical_layer_index', 'lev', 'avg', 'probability')
call history_add_field('TROP_FD', 'tropopause_found', horiz_only, 'avg', 'probability')

! Primary (Lapse rate) only
call history_add_field('TROPP_P', 'tropopause_air_pressure_from_lapse_rate_method', horiz_only, 'avg', 'Pa')
call history_add_field('TROPP_T', 'tropopause_air_temperature_from_lapse_rate_method', horiz_only, 'avg', 'K' )
call history_add_field('TROPP_Z', 'tropopause_geopotential_height_wrt_surface_from_lapse_rate_method', horiz_only, 'avg', 'm' )
call history_add_field('TROPP_DZ', 'geopotential_height_difference_between_atmosphere_layer_and_tropopause_from_lapse_rate_method', 'lev', 'avg', 'm')
call history_add_field('TROPP_PD', 'probability_distribution_of_tropopause_vertical_layer_index_from_lapse_rate_method', 'lev', 'avg', 'probability')
call history_add_field('TROPP_FD', 'tropopause_found_from_lapse_rate_method', horiz_only, 'avg', 'probability')

! Cold point (CPP) only
call history_add_field('TROPF_P', 'tropopause_air_pressure_from_cold_point_method', horiz_only, 'avg', 'Pa')
call history_add_field('TROPF_T', 'tropopause_air_temperature_from_cold_point_method', horiz_only, 'avg', 'K' )
call history_add_field('TROPF_Z', 'tropopause_geopotential_height_wrt_surface_from_cold_point_method', horiz_only, 'avg', 'm' )
call history_add_field('TROPF_DZ', 'geopotential_height_difference_between_atmosphere_layer_and_tropopause_from_cold_point_method', 'lev', 'avg', 'm')
call history_add_field('TROPF_PD', 'probability_distribution_of_tropopause_vertical_layer_index_from_cold_point_method', 'lev', 'avg', 'probability')
call history_add_field('TROPF_FD', 'tropopause_found_from_cold_point_method', horiz_only, 'avg', 'probability')

! Climatology only - will never fail
cacraigucar marked this conversation as resolved.
Show resolved Hide resolved
call history_add_field('TROPC_P', 'tropopause_air_pressure_from_climatological_method', horiz_only, 'avg', 'Pa')
call history_add_field('TROPC_T', 'tropopause_air_temperature_from_climatological_method', horiz_only, 'avg', 'K' )
call history_add_field('TROPC_Z', 'tropopause_geopotential_height_wrt_surface_from_climatological_method', horiz_only, 'avg', 'm' )
call history_add_field('TROPC_DZ', 'geopotential_height_difference_between_atmosphere_layer_and_tropopause_from_climatological_method', 'lev', 'avg', 'm')
call history_add_field('TROPC_PD', 'probability_distribution_of_tropopause_vertical_layer_index_from_climatological_method', 'lev', 'avg', 'probability')
call history_add_field('TROPC_FD', 'tropopause_found_from_climatological_method', horiz_only, 'avg', 'probability')
cacraigucar marked this conversation as resolved.
Show resolved Hide resolved

! Hybridstobie output fields
call history_add_field('hstobie_trop', 'vertical_layer_index_lower_bound_from_hybrid_stobie_linoz_with_climatological_backup_method_for_stratospheric_chemistry', 'lev', 'inst', 'fraction of model time')
call history_add_field('hstobie_linoz', 'vertical_layer_index_lower_bound_from_hybrid_stobie_linoz_with_climatological_backup_method_for_linearized_ozone_chemistry', 'lev', 'inst', 'fraction of model time')
call history_add_field('hstobie_tropop', 'tropopause_vertical_layer_index_from_hybrid_stobie_linoz_with_climatological_backup_method_for_chemistry', 'lev', 'inst', 'fraction of model time')

end subroutine tropopause_diagnostics_init

! Output the tropopause pressure and temperature to the history files. Two sets
! of output will be generated, one for the default algorithm and another one
! using the default routine, but backed by a climatology when the default
! algorithm fails.
!> \section arg_table_tropopause_diagnostics_run Argument Table
!! \htmlinclude tropopause_diagnostics_run.html
subroutine tropopause_diagnostics_run(ncol, pver, &
zm, &
tropLev, tropP, tropT, tropZ, & ! Default primary+backup (twmo+climate)
tropLev_twmo, tropP_twmo, tropT_twmo, tropZ_twmo, & ! Primary only (twmo)
tropLev_clim, tropP_clim, tropT_clim, tropZ_clim, & ! Climate-only
tropLev_hybstob, tropP_hybstob, tropT_hybstob, tropZ_hybstob, & ! Hybridstobie + climate backup
tropLev_cpp, tropP_cpp, tropT_cpp, tropZ_cpp, & ! Cold point only
hstobie_trop, hstobie_linoz, hstobie_tropop, & ! Hybridstobie only for chemistry diagnostics
errmsg, errflg)
use cam_history, only: history_out_field
use cam_history_support, only: fillvalue

integer, intent(in) :: ncol ! Number of atmospheric columns
integer, intent(in) :: pver ! Number of vertical levels

real(kind_phys), intent(in) :: zm(:,:) ! Geopotential height above surface at midpoints (m), pver

integer, intent(in) :: tropLev(:) ! tropopause level index
real(kind_phys), intent(in) :: tropP(:) ! tropopause pressure (Pa)
real(kind_phys), intent(in) :: tropT(:) ! tropopause temperature (K)
real(kind_phys), intent(in) :: tropZ(:) ! tropopause height (m)

integer, intent(in) :: tropLev_twmo(:) ! lapse-rate tropopause level index
real(kind_phys), intent(in) :: tropP_twmo(:) ! lapse-rate tropopause pressure (Pa)
real(kind_phys), intent(in) :: tropT_twmo(:) ! lapse-rate tropopause temperature (K)
real(kind_phys), intent(in) :: tropZ_twmo(:) ! lapse-rate tropopause height (m)

integer, intent(in) :: tropLev_clim(:) ! climatology-backed tropopause level index
real(kind_phys), intent(in) :: tropP_clim(:) ! climatology-backed tropopause pressure (Pa)
real(kind_phys), intent(in) :: tropT_clim(:) ! climatology-backed tropopause temperature (K)
real(kind_phys), intent(in) :: tropZ_clim(:) ! climatology-backed tropopause height (m)

integer, intent(in) :: tropLev_hybstob(:) ! hybridstobie climatology-backed tropopause level index
real(kind_phys), intent(in) :: tropP_hybstob(:) ! hybridstobie climatology-backed tropopause pressure (Pa)
real(kind_phys), intent(in) :: tropT_hybstob(:) ! hybridstobie climatology-backed tropopause temperature (K)
real(kind_phys), intent(in) :: tropZ_hybstob(:) ! hybridstobie climatology-backed tropopause height (m)

integer, intent(in) :: tropLev_cpp(:) ! cold point tropopause level index
real(kind_phys), intent(in) :: tropP_cpp(:) ! cold point tropopause pressure (Pa)
real(kind_phys), intent(in) :: tropT_cpp(:) ! cold point tropopause temperature (K)
real(kind_phys), intent(in) :: tropZ_cpp(:) ! cold point tropopause height (m)

! Optional output arguments for hybridstobie with chemistry
real(kind_phys), intent(in) :: hstobie_trop(:,:) ! Lowest level with strat. chem
real(kind_phys), intent(in) :: hstobie_linoz(:,:) ! Lowest possible Linoz level
real(kind_phys), intent(in) :: hstobie_tropop(:,:) ! Troposphere boundary calculated in chem.

character(len=512), intent(out) :: errmsg
integer, intent(out) :: errflg

! Local Variables
integer :: i
integer :: alg
real(kind_phys) :: tropFound(ncol) ! tropopause found
real(kind_phys) :: tropDZ(ncol, pver) ! relative tropopause height (m)
real(kind_phys) :: tropPdf(ncol, pver) ! tropopause probability distribution

errmsg = ' '
errflg = 0

! Default algorithm output
tropPdf(:,:) = 0._kind_phys
tropFound(:) = 0._kind_phys
tropDZ(:,:) = fillvalue
do i = 1, ncol
if (tropLev(i) /= NOTFOUND) then
tropPdf(i, tropLev(i)) = 1._kind_phys
tropFound(i) = 1._kind_phys
tropDZ(i,:) = zm(i,:) - tropZ(i)
end if
end do

call history_out_field('TROP_P', tropP)
call history_out_field('TROP_T', tropT)
call history_out_field('TROP_Z', tropZ)
call history_out_field('TROP_DZ', tropDZ)
call history_out_field('TROP_PD', tropPdf)
call history_out_field('TROP_FD', tropFound)

! Primary-only (currently TWMO) algorithm output
tropPdf(:,:) = 0._kind_phys
tropFound(:) = 0._kind_phys
tropDZ(:,:) = fillvalue
do i = 1, ncol
if (tropLev_twmo(i) /= NOTFOUND) then
tropPdf(i, tropLev_twmo(i)) = 1._kind_phys
tropFound(i) = 1._kind_phys
tropDZ(i,:) = zm(i,:) - tropZ(i)
end if
end do

call history_out_field('TROPP_P', tropP_twmo)
call history_out_field('TROPP_T', tropT_twmo)
call history_out_field('TROPP_Z', tropZ_twmo)
call history_out_field('TROPP_DZ', tropDZ)
call history_out_field('TROPP_PD', tropPdf)
call history_out_field('TROPP_FD', tropFound)

! Cold point output
tropPdf(:,:) = 0._kind_phys
tropFound(:) = 0._kind_phys
tropDZ(:,:) = fillvalue
do i = 1, ncol
if (tropLev_cpp(i) /= NOTFOUND) then
tropPdf(i, tropLev_cpp(i)) = 1._kind_phys
tropFound(i) = 1._kind_phys
tropDZ(i,:) = zm(i,:) - tropZ_cpp(i)
end if
end do

call history_out_field('TROPF_P', tropP_cpp)
call history_out_field('TROPF_T', tropT_cpp)
call history_out_field('TROPF_Z', tropZ_cpp)
call history_out_field('TROPF_DZ', tropDZ)
call history_out_field('TROPF_PD', tropPdf)
call history_out_field('TROPF_FD', tropFound)

! Climatology output
tropPdf(:,:) = 0._kind_phys
tropFound(:) = 0._kind_phys
tropDZ(:,:) = fillvalue
do i = 1, ncol
if (tropLev_clim(i) /= NOTFOUND) then
tropPdf(i, tropLev_clim(i)) = 1._kind_phys
tropFound(i) = 1._kind_phys
tropDZ(i,:) = zm(i,:) - tropZ_clim(i)
end if
end do

call history_out_field('TROPC_P', tropP_clim)
call history_out_field('TROPC_T', tropT_clim)
call history_out_field('TROPC_Z', tropZ_clim)
call history_out_field('TROPC_DZ', tropDZ)
call history_out_field('TROPC_PD', tropPdf)
call history_out_field('TROPC_FD', tropFound)

! Hybridstobie outputs for chemistry
call history_out_field('hstobie_trop', hstobie_trop)
call history_out_field('hstobie_linoz', hstobie_linoz)
call history_out_field('hstobie_tropop', hstobie_tropop)

return
nusbaume marked this conversation as resolved.
Show resolved Hide resolved
cacraigucar marked this conversation as resolved.
Show resolved Hide resolved
end subroutine tropopause_diagnostics_run
end module tropopause_diagnostics
cacraigucar marked this conversation as resolved.
Show resolved Hide resolved
Loading