Skip to content

Commit

Permalink
Add new available_output regression test
Browse files Browse the repository at this point in the history
Provides a mechanism to see what output_for_GCM fields are available for a
given configuration. Note that output_for_gcm_registry is now a public member
of the MARBL interface class so the standalone test can access it.
  • Loading branch information
mnlevy1981 committed Feb 23, 2024
1 parent c371b6a commit ef58f3b
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 22 deletions.
6 changes: 6 additions & 0 deletions MARBL_tools/run_test_suite.sh
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,12 @@ if [ "${STATUS}" == "PASS" ]; then
STATUS=$(check_return $?)
print_status "requested_tracers.py" >> ${RESULTS_CACHE}

# Print all output_for_GCM variables
cd ${MARBL_ROOT}/tests/regression_tests/available_output
(set -x ; ./available_output.py)
STATUS=$(check_return $?)
print_status "available_output.py" >> ${RESULTS_CACHE}

# Initialize MARBL (with MPI)
cd ${MARBL_ROOT}/tests/regression_tests/init
(set -x ; ./init.py --mpitasks 2)
Expand Down
23 changes: 12 additions & 11 deletions docs/src/dev-guide/marbl-interface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ The class definition is shown below:
type(marbl_forcing_fields_type), allocatable , public :: interior_tendency_forcings(:) ! input
real (r8), allocatable , public :: interior_tendencies(:,:) ! output
type(marbl_interior_tendency_forcing_indexing_type), public :: interior_tendency_forcing_ind ! FIXME #311: should be private
type(marbl_output_for_GCM_type) , public :: interior_tendency_output ! output
type(marbl_diagnostics_type) , public :: interior_tendency_diags ! output
! public data related to computing surface fluxes
Expand All @@ -43,20 +44,20 @@ The class definition is shown below:
type(marbl_diagnostics_type) , public :: surface_flux_diags ! output
! public data - global averages
real (r8) , public, allocatable :: glo_avg_fields_interior_tendency(:) ! output (nfields)
real (r8) , public, allocatable :: glo_avg_averages_interior_tendency(:) ! input (nfields)
real (r8) , public, allocatable :: glo_avg_fields_surface_flux(:,:) ! output (num_elements,nfields)
real (r8) , public, allocatable :: glo_avg_averages_surface_flux(:) ! input (nfields)
real (r8), public, allocatable :: glo_avg_fields_interior_tendency(:) ! output (nfields)
real (r8), public, allocatable :: glo_avg_averages_interior_tendency(:) ! input (nfields)
real (r8), public, allocatable :: glo_avg_fields_surface_flux(:,:) ! output (num_elements,nfields)
real (r8), public, allocatable :: glo_avg_averages_surface_flux(:) ! input (nfields)
! FIXME #77: for now, running means are being computed in the driver
! they will eventually be moved from the interface to inside MARBL
real (r8) , public, allocatable :: glo_scalar_interior_tendency(:)
real (r8) , public, allocatable :: glo_scalar_surface_flux(:)
real (r8), public, allocatable :: glo_scalar_interior_tendency(:)
real (r8), public, allocatable :: glo_scalar_surface_flux(:)
type(marbl_running_mean_0d_type) , public, allocatable :: glo_avg_rmean_interior_tendency(:)
type(marbl_running_mean_0d_type) , public, allocatable :: glo_avg_rmean_surface_flux(:)
type(marbl_running_mean_0d_type) , public, allocatable :: glo_scalar_rmean_interior_tendency(:)
type(marbl_running_mean_0d_type) , public, allocatable :: glo_scalar_rmean_surface_flux(:)
type(marbl_running_mean_0d_type), public, allocatable :: glo_avg_rmean_interior_tendency(:)
type(marbl_running_mean_0d_type), public, allocatable :: glo_avg_rmean_surface_flux(:)
type(marbl_running_mean_0d_type), public, allocatable :: glo_scalar_rmean_interior_tendency(:)
type(marbl_running_mean_0d_type), public, allocatable :: glo_scalar_rmean_surface_flux(:)
! private data
type(unit_system_type), private :: unit_system
Expand All @@ -80,6 +81,7 @@ The class definition is shown below:
type(marbl_internal_timers_type), private :: timers
type(marbl_timer_indexing_type), private :: timer_ids
type(marbl_settings_type), private :: settings
type(marbl_output_for_GCM_registry_type), private :: output_for_gcm_registry
contains
Expand All @@ -106,7 +108,6 @@ The class definition is shown below:
get_string
procedure, public :: get_settings_var_cnt
procedure, public :: add_output_for_GCM
procedure, public :: get_output_for_GCM
procedure, private :: inquire_settings_metadata_by_name
procedure, private :: inquire_settings_metadata_by_id
procedure, private :: put_real
Expand Down
21 changes: 11 additions & 10 deletions src/marbl_interface.F90
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,16 @@ module marbl_interface
type(marbl_forcing_fields_type), allocatable , public :: interior_tendency_forcings(:) ! input
real (r8), allocatable , public :: interior_tendencies(:,:) ! output
type(marbl_interior_tendency_forcing_indexing_type), public :: interior_tendency_forcing_ind ! FIXME #311: should be private
type(marbl_diagnostics_type) , public :: interior_tendency_diags ! output
type(marbl_output_for_GCM_type) , public :: interior_tendency_output ! output
type(marbl_diagnostics_type) , public :: interior_tendency_diags ! output

! public data related to computing surface fluxes
real (r8) , public, allocatable :: tracers_at_surface(:,:) ! input
type(marbl_forcing_fields_type) , public, allocatable :: surface_flux_forcings(:) ! input
type(marbl_surface_flux_forcing_indexing_type) , public :: surface_flux_forcing_ind ! FIXME #311: should be private
real (r8) , public, allocatable :: surface_fluxes(:,:) ! output
type(marbl_diagnostics_type) , public :: surface_flux_diags ! output
type(marbl_output_for_GCM_type) , public :: surface_flux_output ! output

! public data that the GCM needs to explicitly request
real (r8) , public, allocatable :: tracers_at_surface(:,:) ! input
type(marbl_forcing_fields_type) , public, allocatable :: surface_flux_forcings(:) ! input
type(marbl_surface_flux_forcing_indexing_type) , public :: surface_flux_forcing_ind ! FIXME #311: should be private
real (r8) , public, allocatable :: surface_fluxes(:,:) ! output
type(marbl_output_for_GCM_type) , public :: surface_flux_output ! output
type(marbl_diagnostics_type) , public :: surface_flux_diags ! output

! public data - global averages
real (r8), public, allocatable :: glo_avg_fields_interior_tendency(:) ! output (nfields)
Expand All @@ -114,6 +112,10 @@ module marbl_interface
real (r8), public, allocatable :: glo_scalar_interior_tendency(:)
real (r8), public, allocatable :: glo_scalar_surface_flux(:)

! Registry of available output for the GCM
! (Public so we can provide available_output test in the standalone driver)
type(marbl_output_for_GCM_registry_type), public :: output_for_gcm_registry

type(marbl_running_mean_0d_type), public, allocatable :: glo_avg_rmean_interior_tendency(:)
type(marbl_running_mean_0d_type), public, allocatable :: glo_avg_rmean_surface_flux(:)
type(marbl_running_mean_0d_type), public, allocatable :: glo_scalar_rmean_interior_tendency(:)
Expand Down Expand Up @@ -141,7 +143,6 @@ module marbl_interface
type(marbl_internal_timers_type), private :: timers
type(marbl_timer_indexing_type), private :: timer_ids
type(marbl_settings_type), private :: settings
type(marbl_output_for_GCM_registry_type), private :: output_for_gcm_registry

contains

Expand Down
55 changes: 54 additions & 1 deletion tests/driver_src/marbl.F90
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Program marbl

! Use from libmarbl.a
use marbl_interface, only : marbl_interface_class
use marbl_interface_public_types, only : marbl_output_for_GCM_linked_list_type
use marbl_logging, only : marbl_log_type
use marbl_kinds_mod, only : char_len

Expand Down Expand Up @@ -74,9 +75,10 @@ Program marbl
character(len=char_len) :: namelist_file, settings_file
character(len=3) :: unit_system_opt
integer :: argcnt
logical :: labort_after_argparse, lshow_usage, lfound_file
logical :: labort_after_argparse, lshow_usage, lfound_file, lunavailable_output

type(marbl_interface_class), dimension(:), allocatable :: marbl_instances
type(marbl_output_for_GCM_linked_list_type), pointer :: registered_output
type(marbl_log_type) :: driver_status_log
integer :: n, cnt
character(len=char_len) :: settings_file_line, varname, log_message
Expand Down Expand Up @@ -437,6 +439,57 @@ Program marbl
call marbl_instances(1)%shutdown()
end if

! -- available_output test -- !
case ('available_output')
call verify_single_instance(num_inst, trim(testname))
lprint_marbl_log = .false.
call marbl_init_test(marbl_instances(1), unit_system_opt, lshutdown = .false.)
if (.not. marbl_instances(1)%StatusLog%labort_marbl) then
! Log available output for GCM and note if any output is unavailable
call driver_status_log%log_header('Available output for GCM', subname)
lunavailable_output = .false.
cnt = 0
registered_output => marbl_instances(1)%output_for_gcm_registry%registered_outputs
do while (associated(registered_output))
if (len_trim(registered_output%err_message) == 0) then
cnt = cnt+1
write(log_message, "(I0, 2A)") cnt, '. ', trim(registered_output%long_name)
call driver_status_log%log_noerror(log_message, subname)
write(log_message, "(2A)") ' short name: ', trim(registered_output%short_name)
call driver_status_log%log_noerror(log_message, subname)
write(log_message, "(2A)") ' units: ', trim(registered_output%units)
call driver_status_log%log_noerror(log_message, subname)
write(log_message, "(2A)") ' field_source: ', trim(registered_output%field_source)
call driver_status_log%log_noerror(log_message, subname)
else
lunavailable_output = .true.
end if
registered_output => registered_output%next
end do

if (cnt.eq.0) then
call driver_status_log%log_noerror('No available output for the GCM in this configuration!', subname)
end if

if (lunavailable_output) then
call driver_status_log%log_header('Unavailable output for GCM', subname)
cnt = 0
registered_output => marbl_instances(1)%output_for_gcm_registry%registered_outputs
do while (associated(registered_output))
if (len_trim(registered_output%err_message) > 0) then
cnt = cnt+1
write(log_message, "(I0, 2A)") cnt, '. ', trim(registered_output%long_name)
call driver_status_log%log_noerror(log_message, subname)
write(log_message, "(2A)") ' * ', trim(registered_output%err_message)
call driver_status_log%log_noerror(log_message, subname)
end if
registered_output => registered_output%next
end do
end if
call marbl_instances(1)%shutdown()
end if

! -- call_compute_subroutines test -- !
case ('call_compute_subroutines')
lprint_marbl_log = .false.
call marbl_call_compute_subroutines_test(marbl_instances, hist_file, unit_system_opt, driver_status_log)
Expand Down
15 changes: 15 additions & 0 deletions tests/regression_tests/available_output/available_output.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env python

from sys import path
import os

path.insert(0, os.path.join('..', '..', 'python_for_tests'))
from marbl_testing_class import MARBL_testcase

mt = MARBL_testcase()

mt.parse_args(desc='Run MARBL init and print list of available output for GCM')

mt.build_exe()

mt.run_exe()
3 changes: 3 additions & 0 deletions tests/regression_tests/available_output/test.nml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
&marbl_driver_nml
testname="available_output"
/

0 comments on commit ef58f3b

Please sign in to comment.