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

Move MOM_diag_manager_infra.F90 code changes to FMS2_MP #82

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
455 changes: 455 additions & 0 deletions config_src/infra/FMS2_MP/MOM_coms_infra.F90

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions config_src/infra/FMS2_MP/MOM_constants.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
!> Provides a few physical constants
module MOM_constants

! This file is part of MOM6. See LICENSE.md for the license.

use constants_mod, only : HLV, HLF

implicit none ; private

!> The constant offset for converting temperatures in Kelvin to Celsius
real, public, parameter :: CELSIUS_KELVIN_OFFSET = 273.15
public :: HLV, HLF

end module MOM_constants
503 changes: 503 additions & 0 deletions config_src/infra/FMS2_MP/MOM_couplertype_infra.F90

Large diffs are not rendered by default.

93 changes: 93 additions & 0 deletions config_src/infra/FMS2_MP/MOM_cpu_clock_infra.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
!> Wraps the MPP cpu clock functions
!!
!! The functions and constants should be accessed via mom_cpu_clock
module MOM_cpu_clock_infra

! This file is part of MOM6. See LICENSE.md for the license.

! These interfaces and constants from MPP/FMS will not be directly exposed outside of this module
use fms_mod, only : clock_flag_default
use mpp_mod, only : mpp_clock_begin
use mpp_mod, only : mpp_clock_end, mpp_clock_id
use mpp_mod, only : MPP_CLOCK_COMPONENT => CLOCK_COMPONENT
use mpp_mod, only : MPP_CLOCK_SUBCOMPONENT => CLOCK_SUBCOMPONENT
use mpp_mod, only : MPP_CLOCK_MODULE_DRIVER => CLOCK_MODULE_DRIVER
use mpp_mod, only : MPP_CLOCK_MODULE => CLOCK_MODULE
use mpp_mod, only : MPP_CLOCK_ROUTINE => CLOCK_ROUTINE
use mpp_mod, only : MPP_CLOCK_LOOP => CLOCK_LOOP
use mpp_mod, only : MPP_CLOCK_INFRA => CLOCK_INFRA

implicit none ; private

! Public entities
public :: cpu_clock_id, cpu_clock_begin, cpu_clock_end
public :: CLOCK_COMPONENT, CLOCK_SUBCOMPONENT, CLOCK_MODULE_DRIVER, CLOCK_MODULE
public :: CLOCK_ROUTINE, CLOCK_LOOP, CLOCK_INFRA

!> A granularity value to passed to cpu_clock_id() to indicate the clock is for a
!! component, e.g. the entire MOM6 model
integer, parameter :: CLOCK_COMPONENT = MPP_CLOCK_COMPONENT

!> A granularity value to passed to cpu_clock_id() to indicate the clock is for a
!! sub-component, e.g. dynamics or thermodynamics
integer, parameter :: CLOCK_SUBCOMPONENT = MPP_CLOCK_SUBCOMPONENT

!> A granularity value to passed to cpu_clock_id() to indicate the clock is for a
!! module driver, e.g. a routine that calls multiple other routines
integer, parameter :: CLOCK_MODULE_DRIVER = MPP_CLOCK_MODULE_DRIVER

!> A granularity value to passed to cpu_clock_id() to indicate the clock is for a
!! module, e.g. the main entry routine for a module
integer, parameter :: CLOCK_MODULE = MPP_CLOCK_MODULE

!> A granularity value to passed to cpu_clock_id() to indicate the clock is for a
!! subroutine or function
integer, parameter :: CLOCK_ROUTINE = MPP_CLOCK_ROUTINE

!> A granularity value to passed to cpu_clock_id() to indicate the clock is for a
!! section with in a routine, e.g. around a loop
integer, parameter :: CLOCK_LOOP = MPP_CLOCK_LOOP

!> A granularity value to passed to cpu_clock_id() to indicate the clock is for an
!! infrastructure operation, e.g. a halo update
integer, parameter :: CLOCK_INFRA = MPP_CLOCK_INFRA

contains

!> Turns on clock with handle "id"
subroutine cpu_clock_begin(id)
integer, intent(in) :: id !< Handle for clock

call mpp_clock_begin(id)

end subroutine cpu_clock_begin

!> Turns off clock with handle "id"
subroutine cpu_clock_end(id)
integer, intent(in) :: id !< Handle for clock

call mpp_clock_end(id)

end subroutine cpu_clock_end

!> Returns the integer handle for a named CPU clock.
integer function cpu_clock_id( name, synchro_flag, grain )
character(len=*), intent(in) :: name !< The unique name of the CPU clock
integer, optional, intent(in) :: synchro_flag !< An integer flag that controls whether the PEs
!! are synchronized before the cpu clocks start counting.
!! Synchronization occurs before the start of a clock if this
!! is odd, while additional (expensive) statistics can set
!! for other values. If absent, the default is taken from the
!! settings for FMS.
integer, optional, intent(in) :: grain !< The timing granularity for this clock, usually set to
!! the values of CLOCK_COMPONENT, CLOCK_ROUTINE, CLOCK_LOOP, etc.

if (present(synchro_flag)) then
cpu_clock_id = mpp_clock_id(name, flags=synchro_flag, grain=grain)
else
cpu_clock_id = mpp_clock_id(name, flags=clock_flag_default, grain=grain)
endif

end function cpu_clock_id

end module MOM_cpu_clock_infra
105 changes: 105 additions & 0 deletions config_src/infra/FMS2_MP/MOM_data_override_infra.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
!> These interfaces allow for ocean or sea-ice variables to be replaced with data.
module MOM_data_override_infra

! This file is part of MOM6. See LICENSE.md for the license.

use MOM_domain_infra, only : MOM_domain_type, domain2d
use MOM_domain_infra, only : get_simple_array_i_ind, get_simple_array_j_ind
use MOM_time_manager, only : time_type
use data_override_mod, only : data_override_init
use data_override_mod, only : data_override
use data_override_mod, only : data_override_unset_domains

implicit none ; private

public :: impose_data_init, impose_data, impose_data_unset_domains

!> Potentially override the values of a field in the model with values from a dataset.
interface impose_data
module procedure data_override_MD, data_override_2d
end interface

contains

!> Initialize the data override capability and set the domains for the ocean and ice components.
!> There should be a call to impose_data_init before impose_data is called.
subroutine impose_data_init(MOM_domain_in, Ocean_domain_in, Ice_domain_in)
type (MOM_domain_type), intent(in), optional :: MOM_domain_in
type (domain2d), intent(in), optional :: Ocean_domain_in
type (domain2d), intent(in), optional :: Ice_domain_in

if (present(MOM_domain_in)) then
call data_override_init(Ocean_domain_in=MOM_domain_in%mpp_domain, Ice_domain_in=Ice_domain_in)
else
call data_override_init(Ocean_domain_in=Ocean_domain_in, Ice_domain_in=Ice_domain_in)
endif
end subroutine impose_data_init


!> Potentially override a 2-d field on a MOM6 domain with values from a dataset.
subroutine data_override_MD(domain, fieldname, data_2D, time, scale, override, is_ice)
type(MOM_domain_type), intent(in) :: domain !< MOM domain from which to extract information
character(len=*), intent(in) :: fieldname !< Name of the field to override
real, dimension(:,:), intent(inout) :: data_2D !< Data that may be modified by this call.
type(time_type), intent(in) :: time !< The model time, and the time for the data
real, optional, intent(in) :: scale !< A scaling factor that an overridden field is
!! multiplied by before it is returned. However,
!! if there is no override, there is no rescaling.
logical, optional, intent(out) :: override !< True if the field has been overridden successfully
logical, optional, intent(in) :: is_ice !< If present and true, use the ice domain.

logical :: overridden, is_ocean
integer :: i, j, is, ie, js, je

overridden = .false.
is_ocean = .true. ; if (present(is_ice)) is_ocean = .not.is_ice
if (is_ocean) then
call data_override('OCN', fieldname, data_2D, time, override=overridden)
else
call data_override('ICE', fieldname, data_2D, time, override=overridden)
endif

if (overridden .and. present(scale)) then ; if (scale /= 1.0) then
! Rescale data in the computational domain if the data override has occurred.
call get_simple_array_i_ind(domain, size(data_2D,1), is, ie)
call get_simple_array_j_ind(domain, size(data_2D,2), js, je)
do j=js,je ; do i=is,ie
data_2D(i,j) = scale*data_2D(i,j)
enddo ; enddo
endif ; endif

if (present(override)) override = overridden

end subroutine data_override_MD


!> Potentially override a 2-d field with values from a dataset.
subroutine data_override_2d(gridname, fieldname, data_2D, time, override)
character(len=3), intent(in) :: gridname !< String identifying the model component, in MOM6
!! and SIS this may be either 'OCN' or 'ICE'
character(len=*), intent(in) :: fieldname !< Name of the field to override
real, dimension(:,:), intent(inout) :: data_2D !< Data that may be modified by this call
type(time_type), intent(in) :: time !< The model time, and the time for the data
logical, optional, intent(out) :: override !< True if the field has been overridden successfully

call data_override(gridname, fieldname, data_2D, time, override)

end subroutine data_override_2d

!> Unset domains that had previously been set for use by data_override.
subroutine impose_data_unset_domains(unset_Ocean, unset_Ice, must_be_set)
logical, intent(in), optional :: unset_Ocean !< If present and true, unset the ocean domain for overrides
logical, intent(in), optional :: unset_Ice !< If present and true, unset the sea-ice domain for overrides
logical, intent(in), optional :: must_be_set !< If present and true, it is a fatal error to unset
!! a domain that is not set.

call data_override_unset_domains(unset_Ocean=unset_Ocean, unset_Ice=unset_Ice, &
must_be_set=must_be_set)
end subroutine impose_data_unset_domains

end module MOM_data_override_infra

!> \namespace MOM_data_override_infra
!!
!! The routines here wrap routines from the FMS module data_override_mod, which potentially replace
!! model values with values read from a data file.
Loading