diff --git a/config_src/coupled_driver/ocean_model_MOM.F90 b/config_src/coupled_driver/ocean_model_MOM.F90 index 774201ddb5..c4bd543bfd 100644 --- a/config_src/coupled_driver/ocean_model_MOM.F90 +++ b/config_src/coupled_driver/ocean_model_MOM.F90 @@ -48,7 +48,6 @@ module ocean_model_mod use MOM_verticalGrid, only : verticalGrid_type use MOM_ice_shelf, only : initialize_ice_shelf, shelf_calc_flux, ice_shelf_CS use MOM_ice_shelf, only : add_shelf_forces, ice_shelf_end, ice_shelf_save_restart -use MOM_IS_diag_mediator, only : diag_IS_ctrl => diag_ctrl, diag_mediator_IS_end=>diag_mediator_end use coupler_types_mod, only : coupler_1d_bc_type, coupler_2d_bc_type use coupler_types_mod, only : coupler_type_spawn, coupler_type_write_chksums use coupler_types_mod, only : coupler_type_initialized, coupler_type_copy_data @@ -182,13 +181,13 @@ module ocean_model_mod !! processes before time stepping the dynamics. type(directories) :: dirs !< A structure containing several relevant directory paths. - type(mech_forcing), pointer :: forces => NULL() !< A structure with the driving mechanical surface forces - type(forcing), pointer :: fluxes => NULL() !< A structure containing pointers to + type(mech_forcing) :: forces !< A structure with the driving mechanical surface forces + type(forcing) :: fluxes !< A structure containing pointers to !! the thermodynamic ocean forcing fields. - type(forcing), pointer :: flux_tmp => NULL() !< A secondary structure containing pointers to the + type(forcing) :: flux_tmp !< A secondary structure containing pointers to the !! ocean forcing fields for when multiple coupled !! timesteps are taken per thermodynamic step. - type(surface), pointer :: sfc_state => NULL() !< A structure containing pointers to + type(surface) :: sfc_state !< A structure containing pointers to !! the ocean surface state fields. type(ocean_grid_type), pointer :: & grid => NULL() !< A pointer to a grid structure containing metrics @@ -217,9 +216,6 @@ module ocean_model_mod !! that will be used for MOM restart files. type(diag_ctrl), pointer :: & diag => NULL() !< A pointer to the diagnostic regulatory structure - type(diag_IS_ctrl), pointer :: & - diag_IS => NULL() !< A pointer to the diagnostic regulatory structure - !! for the ice shelf module. end type ocean_state_type contains @@ -273,9 +269,9 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, wind_stagger, gas endif allocate(OS) - allocate(OS%fluxes) - allocate(OS%forces) - allocate(OS%flux_tmp) +! allocate(OS%fluxes) +! allocate(OS%forces) +! allocate(OS%flux_tmp) OS%is_ocean_pe = Ocean_sfc%is_ocean_pe if (.not.OS%is_ocean_pe) return @@ -365,7 +361,7 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, wind_stagger, gas use_melt_pot=.false. endif - allocate(OS%sfc_state) + !allocate(OS%sfc_state) call allocate_surface_state(OS%sfc_state, OS%grid, use_temperature, do_integrals=.true., & gas_fields_ocn=gas_fields_ocn, use_meltpot=use_melt_pot) @@ -379,7 +375,7 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, wind_stagger, gas if (OS%use_ice_shelf) then call initialize_ice_shelf(param_file, OS%grid, OS%Time, OS%ice_shelf_CSp, & - OS%diag_IS, OS%forces, OS%fluxes) + OS%diag, OS%forces, OS%fluxes) endif if (OS%icebergs_alter_ocean) then call marine_ice_init(OS%Time, OS%grid, param_file, OS%diag, OS%marine_ice_CSp) @@ -728,8 +724,6 @@ subroutine ocean_model_end(Ocean_sfc, Ocean_state, Time) call ocean_model_save_restart(Ocean_state, Time) call diag_mediator_end(Time, Ocean_state%diag) - if (Ocean_state%use_ice_shelf) & - call diag_mediator_IS_end(Time, Ocean_state%diag_IS) call MOM_end(Ocean_state%MOM_CSp) if (Ocean_state%use_ice_shelf) call ice_shelf_end(Ocean_state%Ice_shelf_CSp) end subroutine ocean_model_end diff --git a/config_src/solo_driver/MOM_driver.F90 b/config_src/solo_driver/MOM_driver.F90 index 9981f291b1..9726aa1281 100644 --- a/config_src/solo_driver/MOM_driver.F90 +++ b/config_src/solo_driver/MOM_driver.F90 @@ -28,7 +28,6 @@ program MOM_main use MOM_cpu_clock, only : CLOCK_COMPONENT use MOM_diag_mediator, only : enable_averaging, disable_averaging, diag_mediator_end use MOM_diag_mediator, only : diag_ctrl, diag_mediator_close_registration - use MOM_IS_diag_mediator, only : diag_IS_ctrl=>diag_ctrl, diag_mediator_IS_end=>diag_mediator_end use MOM, only : initialize_MOM, step_MOM, MOM_control_struct, MOM_end use MOM, only : extract_surface_state, finish_MOM_initialization use MOM, only : get_MOM_state_elements, MOM_state_is_synchronized @@ -71,6 +70,7 @@ program MOM_main use MOM_ice_shelf, only : initialize_ice_shelf, ice_shelf_end, ice_shelf_CS use MOM_ice_shelf, only : shelf_calc_flux, add_shelf_forces, ice_shelf_save_restart + use MOM_ice_shelf, only : initialize_ice_shelf_fluxes, initialize_ice_shelf_forces use MOM_wave_interface, only: wave_parameters_CS, MOM_wave_interface_init use MOM_wave_interface, only: MOM_wave_interface_init_lite, Update_Surface_Waves @@ -80,13 +80,12 @@ program MOM_main #include ! A structure with the driving mechanical surface forces - type(mech_forcing), pointer :: forces => NULL() + type(mech_forcing) :: forces ! A structure containing pointers to the thermodynamic forcing fields ! at the ocean surface. - type(forcing), pointer :: fluxes => NULL() - + type(forcing) :: fluxes ! A structure containing pointers to the ocean surface state fields. - type(surface), pointer :: sfc_state => NULL() + type(surface) :: sfc_state ! A pointer to a structure containing metrics and related information. type(ocean_grid_type), pointer :: grid => NULL() @@ -200,8 +199,6 @@ program MOM_main !! that will be used for MOM restart files. type(diag_ctrl), pointer :: & diag => NULL() !< A pointer to the diagnostic regulatory structure - type(diag_IS_ctrl), pointer :: & - diag_IS => NULL() !< A pointer to the diagnostic regulatory structure !----------------------------------------------------------------------- character(len=4), parameter :: vers_num = 'v2.0' @@ -221,7 +218,7 @@ program MOM_main call MOM_infra_init() ; call io_infra_init() - allocate(forces,fluxes,sfc_state) + !allocate(forces,fluxes,sfc_state) ! Initialize the ensemble manager. If there are no settings for ensemble_size ! in input.nml(ensemble.nml), these should not do anything. In coupled @@ -307,32 +304,29 @@ program MOM_main Time = Start_time endif - ! Read paths and filenames from namelist and store in "dirs". - ! Also open the parsed input parameter file(s) and setup param_file. - call get_MOM_input(param_file, dirs) - - call get_param(param_file, mod_name, "ICE_SHELF", use_ice_shelf, & - "If true, enables the ice shelf model.", default=.false.) - if (use_ice_shelf) then - ! These arrays are not initialized in most solo cases, but are needed - ! when using an ice shelf - call initialize_ice_shelf(param_file, grid, Time, ice_shelf_CSp, & - diag_IS, forces, fluxes, sfc_state) - endif - call close_param_file(param_file) - + ! Call initialize MOM with an optional Ice Shelf CS which, if present triggers + ! initialization of ice shelf parameters and arrays. if (sum(date) >= 0) then call initialize_MOM(Time, Start_time, param_file, dirs, MOM_CSp, restart_CSp, & segment_start_time, offline_tracer_mode=offline_tracer_mode, & - diag_ptr=diag, tracer_flow_CSp=tracer_flow_CSp,ice_shelf_CSp=ice_shelf_CSp) + diag_ptr=diag, tracer_flow_CSp=tracer_flow_CSp, ice_shelf_CSp=ice_shelf_CSp) else call initialize_MOM(Time, Start_time, param_file, dirs, MOM_CSp, restart_CSp, & offline_tracer_mode=offline_tracer_mode, diag_ptr=diag, & - tracer_flow_CSp=tracer_flow_CSp,ice_shelf_CSp=ice_shelf_CSp) + tracer_flow_CSp=tracer_flow_CSp, ice_shelf_CSp=ice_shelf_CSp) endif call get_MOM_state_elements(MOM_CSp, G=grid, GV=GV, US=US, C_p_scaled=fluxes%C_p) Master_Time = Time + use_ice_shelf = associated(ice_shelf_CSp) + + if (use_ice_shelf) then + ! These arrays are not initialized in most solo cases, but are needed + ! when using an ice shelf + call initialize_ice_shelf_fluxes(ice_shelf_CSp, grid, US, fluxes) + call initialize_ice_shelf_forces(ice_shelf_CSp, grid, US, forces) + endif + call callTree_waypoint("done initialize_MOM") @@ -665,14 +659,13 @@ program MOM_main endif call callTree_waypoint("End MOM_main") + if (use_ice_shelf) call ice_shelf_end(ice_shelf_CSp) call diag_mediator_end(Time, diag, end_diag_manager=.true.) - if (use_ice_shelf) call diag_mediator_IS_end(Time, diag_IS) if (cpu_steps > 0) call write_cputime(Time, ns-1, write_CPU_CSp, call_end=.true.) call cpu_clock_end(termClock) call io_infra_end ; call MOM_infra_end call MOM_end(MOM_CSp) - if (use_ice_shelf) call ice_shelf_end(ice_shelf_CSp) end program MOM_main diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index 3f4507f546..fa7c3ca565 100644 --- a/src/core/MOM.F90 +++ b/src/core/MOM.F90 @@ -141,7 +141,7 @@ module MOM use MOM_offline_main, only : offline_fw_fluxes_into_ocean, offline_fw_fluxes_out_ocean use MOM_offline_main, only : offline_advection_layer, offline_transport_end use MOM_ALE, only : ale_offline_tracer_final, ALE_main_offline -use MOM_ice_shelf, only : ice_shelf_CS, ice_shelf_query +use MOM_ice_shelf, only : ice_shelf_CS, ice_shelf_query, initialize_ice_shelf implicit none ; private @@ -2037,7 +2037,8 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, restart_CSp, & use_ice_shelf=.false. if (present(ice_shelf_CSp)) then - if (associated(ice_shelf_CSp)) use_ice_shelf=.true. + call get_param(param_file, "MOM", "ICE_SHELF", use_ice_shelf, & + "If true, enables the ice shelf model.", default=.false.) endif CS%ensemble_ocean=.false. @@ -2381,6 +2382,10 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, restart_CSp, & endif if (use_ice_shelf) then + ! These arrays are not initialized in most solo cases, but are needed + ! when using an ice shelf. Passing the ice shelf diagnostics CS from MOM + ! for legacy reasons. The actual ice shelf diag CS is internal to the ice shelf + call initialize_ice_shelf(param_file, G_in, Time, ice_shelf_CSp, diag_ptr) allocate(frac_shelf_in(G_in%isd:G_in%ied, G_in%jsd:G_in%jed)) frac_shelf_in(:,:) = 0.0 allocate(CS%frac_shelf_h(isd:ied, jsd:jed)) @@ -2431,10 +2436,10 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, restart_CSp, & deallocate(frac_shelf_in) else if (use_ice_shelf) then + call initialize_ice_shelf(param_file, G, Time, ice_shelf_CSp, diag_ptr) allocate(CS%frac_shelf_h(isd:ied, jsd:jed)) CS%frac_shelf_h(:,:) = 0.0 call ice_shelf_query(ice_shelf_CSp,G,CS%frac_shelf_h) - call MOM_initialize_state(CS%u, CS%v, CS%h, CS%tv, Time, G, GV, US, & param_file, dirs, restart_CSp, CS%ALE_CSp, CS%tracer_Reg, & CS%sponge_CSp, CS%ALE_sponge_CSp, CS%OBC, Time_in, & diff --git a/src/ice_shelf/MOM_ice_shelf.F90 b/src/ice_shelf/MOM_ice_shelf.F90 index 92545d6dc4..335db29ccb 100644 --- a/src/ice_shelf/MOM_ice_shelf.F90 +++ b/src/ice_shelf/MOM_ice_shelf.F90 @@ -9,9 +9,10 @@ module MOM_ice_shelf use MOM_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end use MOM_cpu_clock, only : CLOCK_COMPONENT, CLOCK_ROUTINE use MOM_coms, only : num_PEs +use MOM_diag_mediator, only : MOM_diag_ctrl=>diag_ctrl use MOM_IS_diag_mediator, only : post_data, register_diag_field=>register_MOM_IS_diag_field, safe_alloc_ptr -use MOM_IS_diag_mediator, only : set_axes_info -use MOM_IS_diag_mediator, only : diag_mediator_init, set_diag_mediator_grid, diag_ctrl, time_type +use MOM_IS_diag_mediator, only : set_axes_info, diag_ctrl, time_type +use MOM_IS_diag_mediator, only : diag_mediator_init, diag_mediator_end, set_diag_mediator_grid use MOM_IS_diag_mediator, only : enable_averages, enable_averaging, disable_averaging use MOM_IS_diag_mediator, only : diag_mediator_infrastructure_init, diag_mediator_close_registration use MOM_domains, only : MOM_domains_init, clone_MOM_domain @@ -69,6 +70,7 @@ module MOM_ice_shelf public shelf_calc_flux, initialize_ice_shelf, ice_shelf_end, ice_shelf_query public ice_shelf_save_restart, solo_step_ice_shelf, add_shelf_forces +public initialize_ice_shelf_fluxes, initialize_ice_shelf_forces ! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional ! consistency testing. These are noted in comments with units like Z, H, L, and T, along with @@ -80,7 +82,7 @@ module MOM_ice_shelf ! Parameters type(MOM_restart_CS), pointer :: restart_CSp => NULL() !< A pointer to the restart control !! structure for the ice shelves - type(ocean_grid_type) :: Grid_in !< un-rotated input grid metric + type(ocean_grid_type), pointer :: Grid_in => NULL() !< un-rotated input grid metric type(hor_index_type), pointer :: HI_in => NULL() !< Pointer to a horizontal indexing structure for !! incoming data which has not been rotated. type(hor_index_type), pointer :: HI => NULL() !< Pointer to a horizontal indexing structure for @@ -103,6 +105,8 @@ module MOM_ice_shelf utide => NULL() !< An unresolved tidal velocity [L T-1 ~> m s-1] real :: ustar_bg !< A minimum value for ustar under ice shelves [Z T-1 ~> m s-1]. + real :: ustar_max !< A maximum value for ustar under ice shelves, or a negative value to + !! have no limit [Z T-1 ~> m s-1]. real :: cdrag !< drag coefficient under ice shelves [nondim]. real :: g_Earth !< The gravitational acceleration [L2 Z-1 T-2 ~> m s-2] real :: Cp !< The heat capacity of sea water [Q degC-1 ~> J kg-1 degC-1]. @@ -124,6 +128,8 @@ module MOM_ice_shelf real :: col_mass_melt_threshold !< An ocean column mass below the iceshelf below which melting !! does not occur [R Z ~> kg m-2] logical :: mass_from_file !< Read the ice shelf mass from a file every dt + logical :: ustar_shelf_from_vel !< If true, use the surface velocities, and not the previous + !! values of the stresses to set ustar. !!!! PHYSICAL AND NUMERICAL PARAMETERS FOR ICE DYNAMICS !!!!!! @@ -386,9 +392,14 @@ subroutine shelf_calc_flux(sfc_state_in, fluxes_in, Time, time_step, CS) u2_av = (asu1 * sfc_state%u(I-1,j)**2 + asu2 * sfc_state%u(I,j)**2) * I_au v2_av = (asv1 * sfc_state%v(i,J-1)**2 + asu2 * sfc_state%v(i,J)**2) * I_av - if (taux2 + tauy2 > 0.0) then - fluxes%ustar_shelf(i,j) = MAX(CS%ustar_bg, US%L_to_Z * & - sqrt(Irho0 * sqrt(taux2 + tauy2) + CS%cdrag*CS%utide(i,j)**2)) + if ((taux2 + tauy2 > 0.0) .and. .not.CS%ustar_shelf_from_vel) then + if (CS%ustar_max >= 0.0) then + fluxes%ustar_shelf(i,j) = MIN(CS%ustar_max, MAX(CS%ustar_bg, US%L_to_Z * & + sqrt(Irho0 * sqrt(taux2 + tauy2) + CS%cdrag*CS%utide(i,j)**2))) + else + fluxes%ustar_shelf(i,j) = MAX(CS%ustar_bg, US%L_to_Z * & + sqrt(Irho0 * sqrt(taux2 + tauy2) + CS%cdrag*CS%utide(i,j)**2)) + endif else ! Take care of the cases when taux_shelf is not set or not allocated. fluxes%ustar_shelf(i,j) = MAX(CS%ustar_bg, US%L_TO_Z * & sqrt(CS%cdrag*((u2_av + v2_av) + CS%utide(i,j)**2))) @@ -806,18 +817,18 @@ end subroutine change_thickness_using_melt !> This subroutine adds the mechanical forcing fields and perhaps shelf areas, based on !! the ice state in ice_shelf_CS. -subroutine add_shelf_forces(Ocn_grid, US, CS, forces_in, do_shelf_area, external_call) +subroutine add_shelf_forces(Ocn_grid, US, CS, forces, do_shelf_area, external_call) type(ocean_grid_type), intent(in) :: Ocn_grid !< The ocean's grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(ice_shelf_CS), pointer :: CS !< This module's control structure. - type(mech_forcing),target, intent(inout) :: forces_in !< A structure with the + type(mech_forcing), intent(inout) :: forces !< A structure with the !! driving mechanical forces logical, optional, intent(in) :: do_shelf_area !< If true find the shelf-covered areas. logical, optional, intent(in) :: external_call !< If true the incoming forcing type !! is using the input grid metric and needs !! to be rotated. type(ocean_grid_type), pointer :: G => NULL() !< A pointer to the ocean grid metric. - type(mech_forcing), pointer :: forces => NULL() !< A structure with the driving mechanical forces +! type(mech_forcing), target :: forces !< A structure with the driving mechanical forces real :: kv_rho_ice ! The viscosity of ice divided by its density [L4 T-1 R-1 Z-2 ~> m5 kg-1 s-1]. real :: press_ice ! The pressure of the ice shelf per unit area of ocean (not ice) [R L2 T-2 ~> Pa]. logical :: find_area ! If true find the shelf areas at u & v points. @@ -829,20 +840,21 @@ subroutine add_shelf_forces(Ocn_grid, US, CS, forces_in, do_shelf_area, external if (present(external_call)) rotate=external_call - if (CS%rotate_index .and. rotate) then - if ((Ocn_grid%isc /= CS%Grid_in%isc) .or. (Ocn_grid%iec /= CS%Grid_in%iec) .or. & - (Ocn_grid%jsc /= CS%Grid_in%jsc) .or. (Ocn_grid%jec /= CS%Grid_in%jec)) & - call MOM_error(FATAL,"add_shelf_forces: Incompatible Ocean and Ice shelf grids.") - - allocate(forces) - call allocate_mech_forcing(forces_in, CS%Grid, forces) - call rotate_mech_forcing(forces_in, CS%turns, forces) - else - if ((Ocn_grid%isc /= CS%Grid%isc) .or. (Ocn_grid%iec /= CS%Grid%iec) .or. & - (Ocn_grid%jsc /= CS%Grid%jsc) .or. (Ocn_grid%jec /= CS%Grid%jec)) & - call MOM_error(FATAL,"add_shelf_forces: Incompatible Ocean and Ice shelf grids.") + if ((Ocn_grid%isc /= CS%Grid_in%isc) .or. (Ocn_grid%iec /= CS%Grid_in%iec) .or. & + (Ocn_grid%jsc /= CS%Grid_in%jsc) .or. (Ocn_grid%jec /= CS%Grid_in%jec)) & + call MOM_error(FATAL,"add_shelf_forces: Incompatible Ocean and Ice shelf grids.") - forces=>forces_in + if (CS%rotate_index .and. rotate) then + call MOM_error(FATAL,"add_shelf_forces: Rotation not implemented for ice shelves.") + ! allocate(forces) + ! call allocate_mech_forcing(forces_in, CS%Grid, forces) + ! call rotate_mech_forcing(forces_in, CS%turns, forces) + ! else + ! if ((Ocn_grid%isc /= CS%Grid%isc) .or. (Ocn_grid%iec /= CS%Grid%iec) .or. & + ! (Ocn_grid%jsc /= CS%Grid%jsc) .or. (Ocn_grid%jec /= CS%Grid%jec)) & + ! call MOM_error(FATAL,"add_shelf_forces: Incompatible Ocean and Ice shelf grids.") + + ! forces=>forces_in endif G=>CS%Grid @@ -910,10 +922,10 @@ subroutine add_shelf_forces(Ocn_grid, US, CS, forces_in, do_shelf_area, external scalar_pair=.true.) endif - if (CS%rotate_index .and. rotate) then - call rotate_mech_forcing(forces, -CS%turns, forces_in) - ! TODO: deallocate mech forcing? - endif + ! if (CS%rotate_index .and. rotate) then + ! call rotate_mech_forcing(forces, -CS%turns, forces_in) + ! ! TODO: deallocate mech forcing? + ! endif end subroutine add_shelf_forces @@ -922,7 +934,7 @@ subroutine add_shelf_pressure(Ocn_grid, US, CS, fluxes) type(ocean_grid_type), intent(in) :: Ocn_grid !< The ocean's grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(ice_shelf_CS), intent(in) :: CS !< This module's control structure. - type(forcing), pointer :: fluxes !< A structure of surface fluxes that may be updated. + type(forcing), intent(inout) :: fluxes !< A structure of surface fluxes that may be updated. type(ocean_grid_type), pointer :: G => NULL() ! A pointer to ocean's grid structure. real :: press_ice !< The pressure of the ice shelf per unit area of ocean (not ice) [R L2 T-2 ~> Pa]. @@ -956,7 +968,7 @@ subroutine add_shelf_flux(G, US, CS, sfc_state, fluxes) type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(ice_shelf_CS), pointer :: CS !< This module's control structure. type(surface), intent(inout) :: sfc_state !< Surface ocean state - type(forcing), pointer :: fluxes !< A structure of surface fluxes that may be used/updated. + type(forcing), intent(inout) :: fluxes !< A structure of surface fluxes that may be used/updated. ! local variables real :: frac_shelf !< The fractional area covered by the ice shelf [nondim]. @@ -1156,7 +1168,9 @@ subroutine initialize_ice_shelf(param_file, ocn_grid, Time, CS, diag, forces_in, type(ocean_grid_type), pointer :: ocn_grid !< The calling ocean model's horizontal grid structure type(time_type), intent(inout) :: Time !< The clock that that will indicate the model time type(ice_shelf_CS), pointer :: CS !< A pointer to the ice shelf control structure - type(diag_ctrl), pointer :: diag !< A structure that is used to regulate the diagnostic output. + type(MOM_diag_ctrl), pointer :: diag !< This is a pointer to the MOM diag CS + !! which will be discarded + type(mech_forcing), optional, target, intent(inout) :: forces_in !< A structure with the driving mechanical forces type(forcing), optional, target, intent(inout) :: fluxes_in !< A structure containing pointers to any !! possible thermodynamic or mass-flux forcing fields. @@ -1235,60 +1249,62 @@ subroutine initialize_ice_shelf(param_file, ocn_grid, Time, CS, diag, forces_in, ! Set up the ice-shelf domain and grid wd_halos(:)=0 - !allocate(CS%Grid_in) - call MOM_domains_init(CS%Grid_in%domain, param_file, min_halo=wd_halos, symmetric=GRID_SYM_,& + allocate(CS%Grid) + call MOM_domains_init(CS%Grid%domain, param_file, min_halo=wd_halos, symmetric=GRID_SYM_,& domain_name='MOM_Ice_Shelf_in') ! allocate(CS%Grid_in%HI) - call hor_index_init(CS%Grid_in%Domain, CS%Grid_in%HI, param_file, & - local_indexing=.not.global_indexing) - call MOM_grid_init(CS%Grid_in, param_file, CS%US, CS%Grid_in%HI) - - if (CS%rotate_index) then - ! TODO: Index rotation currently only works when index rotation does not - ! change the MPI rank of each domain. Resolving this will require a - ! modification to FMS PE assignment. - ! For now, we only permit single-core runs. - - if (num_PEs() /= 1) & - call MOM_error(FATAL, "Index rotation is only supported on one PE.") - - call get_param(param_file, mdl, "INDEX_TURNS", CS%turns, & - "Number of counterclockwise quarter-turn index rotations.", & - default=1, debuggingParam=.true.) - ! NOTE: If indices are rotated, then CS%Grid and CS%Grid_in must both be initialized. - ! If not rotated, then CS%Grid_in and CS%Ggrid are the same grid. - allocate(CS%Grid) - !allocate(CS%HI) - call clone_MOM_domain(CS%Grid_in%Domain, CS%Grid%Domain,turns=CS%turns) - call rotate_hor_index(CS%Grid_in%HI, CS%turns, CS%Grid%HI) - call MOM_grid_init(CS%Grid, param_file, CS%US, CS%HI) - call create_dyn_horgrid(dG, CS%Grid%HI) - call create_dyn_horgrid(dG_in, CS%Grid_in%HI) - call clone_MOM_domain(CS%Grid_in%Domain, dG_in%Domain) - ! Set up the bottom depth, G%D either analytically or from file - call set_grid_metrics(dG_in,param_file,CS%US) - call MOM_initialize_topography(dG_in%bathyT, CS%Grid_in%max_depth, dG_in, param_file) - call rescale_dyn_horgrid_bathymetry(dG_in, CS%US%Z_to_m) - call rotate_dyngrid(dG_in, dG, CS%US, CS%turns) - call copy_dyngrid_to_MOM_grid(dG,CS%Grid,CS%US) - else - CS%Grid=>CS%Grid_in - !CS%Grid%HI=>CS%Grid_in%HI - call create_dyn_horgrid(dG, CS%Grid%HI) - call clone_MOM_domain(CS%Grid%Domain,dG%Domain) - call set_grid_metrics(dG,param_file,CS%US) - ! Set up the bottom depth, G%D either analytically or from file - call MOM_initialize_topography(dG%bathyT, CS%Grid%max_depth, dG, param_file) - call rescale_dyn_horgrid_bathymetry(dG, CS%US%Z_to_m) - call copy_dyngrid_to_MOM_grid(dG,CS%Grid,CS%US) - endif - G=>CS%Grid - - allocate(diag) - call diag_mediator_init(G, param_file,diag,component='MOM_IceShelf') + !call hor_index_init(CS%Grid%Domain, CS%Grid%HI, param_file, & + ! local_indexing=.not.global_indexing) + call MOM_grid_init(CS%Grid, param_file, CS%US) + + ! if (CS%rotate_index) then + ! ! TODO: Index rotation currently only works when index rotation does not + ! ! change the MPI rank of each domain. Resolving this will require a + ! ! modification to FMS PE assignment. + ! ! For now, we only permit single-core runs. + + ! if (num_PEs() /= 1) & + ! call MOM_error(FATAL, "Index rotation is only supported on one PE.") + + ! call get_param(param_file, mdl, "INDEX_TURNS", CS%turns, & + ! "Number of counterclockwise quarter-turn index rotations.", & + ! default=1, debuggingParam=.true.) + ! ! NOTE: If indices are rotated, then CS%Grid and CS%Grid_in must both be initialized. + ! ! If not rotated, then CS%Grid_in and CS%Ggrid are the same grid. + ! allocate(CS%Grid) + ! !allocate(CS%HI) + ! call clone_MOM_domain(CS%Grid_in%Domain, CS%Grid%Domain,turns=CS%turns) + ! call rotate_hor_index(CS%Grid_in%HI, CS%turns, CS%Grid%HI) + ! call MOM_grid_init(CS%Grid, param_file, CS%US, CS%HI) + ! call create_dyn_horgrid(dG, CS%Grid%HI) + ! call create_dyn_horgrid(dG_in, CS%Grid_in%HI) + ! call clone_MOM_domain(CS%Grid_in%Domain, dG_in%Domain) + ! ! Set up the bottom depth, G%D either analytically or from file + ! call set_grid_metrics(dG_in,param_file,CS%US) + ! call MOM_initialize_topography(dG_in%bathyT, CS%Grid_in%max_depth, dG_in, param_file) + ! call rescale_dyn_horgrid_bathymetry(dG_in, CS%US%Z_to_m) + ! call rotate_dyngrid(dG_in, dG, CS%US, CS%turns) + ! call copy_dyngrid_to_MOM_grid(dG,CS%Grid,CS%US) + ! else + !CS%Grid=>CS%Grid_in + dG => NULL() + !CS%Grid%HI=>CS%Grid_in%HI + call create_dyn_horgrid(dG, CS%Grid%HI) + call clone_MOM_domain(CS%Grid%Domain,dG%Domain) + call set_grid_metrics(dG,param_file,CS%US) + ! Set up the bottom depth, G%D either analytically or from file + call MOM_initialize_topography(dG%bathyT, CS%Grid%max_depth, dG, param_file) + call rescale_dyn_horgrid_bathymetry(dG, CS%US%Z_to_m) + call copy_dyngrid_to_MOM_grid(dG,CS%Grid,CS%US) + call destroy_dyn_horgrid(dG) +! endif + G => CS%Grid ; CS%Grid_in => CS%Grid + + allocate(CS%diag) + call diag_mediator_init(G, param_file, CS%diag, component='MOM_IceShelf') ! This call sets up the diagnostic axes. These are needed, ! e.g. to generate the target grids below. - call set_axes_info(G, param_file, diag) + call set_axes_info(G, param_file, CS%diag) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -1302,7 +1318,6 @@ subroutine initialize_ice_shelf(param_file, ocn_grid, Time, CS, diag, forces_in, ! Convenience pointers OG => CS%ocn_grid US => CS%US - CS%diag=>diag ! Are we being called from the solo ice-sheet driver? When called by the ocean ! model solo_ice_sheet_in is not preset. @@ -1485,7 +1500,6 @@ subroutine initialize_ice_shelf(param_file, ocn_grid, Time, CS, diag, forces_in, call safe_alloc_ptr(CS%utide,isd,ied,jsd,jed) ; CS%utide(:,:) = 0.0 - if (read_TIDEAMP) then call get_param(param_file, mdl, "TIDEAMP_FILE", TideAmp_file, & "The path to the file containing the spatially varying "//& @@ -1548,103 +1562,19 @@ subroutine initialize_ice_shelf(param_file, ocn_grid, Time, CS, diag, forces_in, "velocity magnitude.", units="m s-1", default=0.0, scale=US%m_to_Z*US%T_to_s) if (CS%cdrag*drag_bg_vel > 0.0) CS%ustar_bg = sqrt(CS%cdrag)*drag_bg_vel endif + call get_param(param_file, mdl, "USTAR_SHELF_FROM_VEL", CS%ustar_shelf_from_vel, & + "If true, use the surface velocities to set the friction velocity under ice "//& + "shelves instead of using the previous values of the stresses.", & + default=.true.) + call get_param(param_file, mdl, "USTAR_SHELF_MAX", CS%ustar_max, & + "The maximum value of ustar under ice shelves, or a negative value for no limit.", & + units="m s-1", default=-1.0, scale=US%m_to_Z*US%T_to_s, & + do_not_log=CS%ustar_shelf_from_vel) ! Allocate and initialize state variables to default values call ice_shelf_state_init(CS%ISS, CS%grid) ISS => CS%ISS - ! Allocate the arrays for passing ice-shelf data through the forcing type. - if (.not. CS%solo_ice_sheet) then - call MOM_mesg("MOM_ice_shelf.F90, initialize_ice_shelf: allocating fluxes.") - ! GMM: the following assures that water/heat fluxes are just allocated - ! when SHELF_THERMO = True. These fluxes are necessary if one wants to - ! use either ENERGETICS_SFC_PBL (ALE mode) or BULKMIXEDLAYER (layer mode). - if (present(fluxes_in)) then - call allocate_forcing_type(CS%Grid_in, fluxes_in, ustar=.true., shelf=.true., & - press=.true., water=CS%isthermo, heat=CS%isthermo) - if (CS%rotate_index) then - allocate(fluxes) - call allocate_forcing_type(fluxes_in, CS%Grid, fluxes) - call rotate_forcing(fluxes_in, fluxes, CS%turns) - else - fluxes=>fluxes_in - endif - endif - if (present(forces_in)) then - call allocate_mech_forcing(CS%Grid_in, forces_in, ustar=.true., shelf=.true., press=.true.) - if (CS%rotate_index) then - allocate(forces) - call allocate_mech_forcing(forces_in, CS%Grid, forces) - call rotate_mech_forcing(forces_in, CS%turns, forces) - else - forces=>forces_in - endif - endif - else - call MOM_mesg("MOM_ice_shelf.F90, initialize_ice_shelf: allocating fluxes in solo mode.") - if (present(fluxes_in)) then - call allocate_forcing_type(CS%Grid_in, fluxes_in, ustar=.true., shelf=.true., press=.true.) - if (CS%rotate_index) then - allocate(fluxes) - call allocate_forcing_type(fluxes_in, CS%Grid, fluxes) - call rotate_forcing(fluxes_in, fluxes, CS%turns) - endif - endif - if (present(forces_in)) then - call allocate_mech_forcing(CS%Grid_in, forces_in, ustar=.true., shelf=.true., press=.true.) - if (CS%rotate_index) then - allocate(forces) - call allocate_mech_forcing(forces_in, CS%Grid, forces) - call rotate_mech_forcing(forces_in, CS%turns, forces) - endif - endif - endif - - ! Set up the restarts. - call restart_init(param_file, CS%restart_CSp, "Shelf.res") - call register_restart_field(ISS%mass_shelf, "shelf_mass", .true., CS%restart_CSp, & - "Ice shelf mass", "kg m-2") - call register_restart_field(ISS%area_shelf_h, "shelf_area", .true., CS%restart_CSp, & - "Ice shelf area in cell", "m2") - call register_restart_field(ISS%h_shelf, "h_shelf", .true., CS%restart_CSp, & - "ice sheet/shelf thickness", "m") - if (PRESENT(sfc_state_in)) then - if (allocated(sfc_state%taux_shelf) .and. allocated(sfc_state%tauy_shelf)) then - u_desc = var_desc("taux_shelf", "Pa", "the zonal stress on the ocean under ice shelves", & - hor_grid='Cu',z_grid='1') - v_desc = var_desc("tauy_shelf", "Pa", "the meridional stress on the ocean under ice shelves", & - hor_grid='Cv',z_grid='1') - call register_restart_pair(sfc_state%taux_shelf, sfc_state%tauy_shelf, u_desc,v_desc, & - .false., CS%restart_CSp) - endif - endif - - call register_restart_field(ISS%h_shelf, "_shelf", .true., CS%restart_CSp, & - "ice sheet/shelf thickness", "m") - call register_restart_field(US%m_to_Z_restart, "m_to_Z", .false., CS%restart_CSp, & - "Height unit conversion factor", "Z meter-1") - call register_restart_field(US%m_to_L_restart, "m_to_L", .false., CS%restart_CSp, & - "Length unit conversion factor", "L meter-1") - call register_restart_field(US%kg_m3_to_R_restart, "kg_m3_to_R", .false., CS%restart_CSp, & - "Density unit conversion factor", "R m3 kg-1") - if (CS%active_shelf_dynamics) then - call register_restart_field(ISS%hmask, "h_mask", .true., CS%restart_CSp, & - "ice sheet/shelf thickness mask" ,"none") - endif - - if (CS%active_shelf_dynamics) then - ! Allocate CS%dCS and specify additional restarts for ice shelf dynamics - call register_ice_shelf_dyn_restarts(CS%Grid_in, param_file, CS%dCS, CS%restart_CSp) - endif - - !GMM - I think we do not need to save ustar_shelf and iceshelf_melt in the restart file - !if (.not. CS%solo_ice_sheet) then - ! call register_restart_field(fluxes%ustar_shelf, "ustar_shelf", .false., CS%restart_CSp, & - ! "Friction velocity under ice shelves", "m s-1") - !endif - - CS%restart_output_dir = dirs%restart_output_dir - new_sim = .false. if ((dirs%input_filename(1:1) == 'n') .and. & (LEN_TRIM(dirs%input_filename) == 1)) new_sim = .true. @@ -1738,8 +1668,6 @@ subroutine initialize_ice_shelf(param_file, ocn_grid, Time, CS, diag, forces_in, ! ISS%area_shelf_h(i,j) = ISS%area_shelf_h(i,j)*G%mask2dT(i,j) ! enddo; enddo - CS%Time = Time - id_clock_shelf = cpu_clock_id('Ice shelf', grain=CLOCK_COMPONENT) id_clock_pass = cpu_clock_id(' Ice shelf halo updates', grain=CLOCK_ROUTINE) @@ -1751,33 +1679,71 @@ subroutine initialize_ice_shelf(param_file, ocn_grid, Time, CS, diag, forces_in, call pass_var(G%bathyT, G%domain) call cpu_clock_end(id_clock_pass) - do j=jsd,jed ; do i=isd,ied if (ISS%area_shelf_h(i,j) > G%areaT(i,j)) then call MOM_error(WARNING,"Initialize_ice_shelf: area_shelf_h exceeds G%areaT.") ISS%area_shelf_h(i,j) = G%areaT(i,j) endif enddo ; enddo - if (present(fluxes_in)) then ; do j=jsd,jed ; do i=isd,ied - if (G%areaT(i,j)>0.) fluxes%frac_shelf_h(i,j) = ISS%area_shelf_h(i,j) / G%areaT(i,j) - enddo ; enddo ; endif if (CS%debug) then - call hchksum(fluxes%frac_shelf_h, "IS init: frac_shelf_h", G%HI, haloshift=0) call hchksum(ISS%area_shelf_h, "IS init: area_shelf_h", G%HI, haloshift=0, scale=US%L_to_m*US%L_to_m) endif - if (present(forces_in)) & - call add_shelf_forces(G, US, CS, forces, do_shelf_area=.not.CS%solo_ice_sheet) - if (present(fluxes_in)) call add_shelf_pressure(ocn_grid, US, CS, fluxes) + ! Set up the restarts. + + call restart_init(param_file, CS%restart_CSp, "Shelf.res") + call register_restart_field(ISS%mass_shelf, "shelf_mass", .true., CS%restart_CSp, & + "Ice shelf mass", "kg m-2") + call register_restart_field(ISS%area_shelf_h, "shelf_area", .true., CS%restart_CSp, & + "Ice shelf area in cell", "m2") + call register_restart_field(ISS%h_shelf, "h_shelf", .true., CS%restart_CSp, & + "ice sheet/shelf thickness", "m") + if (PRESENT(sfc_state_in)) then + if (allocated(sfc_state%taux_shelf) .and. allocated(sfc_state%tauy_shelf)) then + u_desc = var_desc("taux_shelf", "Pa", "the zonal stress on the ocean under ice shelves", & + hor_grid='Cu',z_grid='1') + v_desc = var_desc("tauy_shelf", "Pa", "the meridional stress on the ocean under ice shelves", & + hor_grid='Cv',z_grid='1') + call register_restart_pair(sfc_state%taux_shelf, sfc_state%tauy_shelf, u_desc,v_desc, & + .false., CS%restart_CSp) + endif + endif + + call register_restart_field(US%m_to_Z_restart, "m_to_Z", .false., CS%restart_CSp, & + "Height unit conversion factor", "Z meter-1") + call register_restart_field(US%m_to_L_restart, "m_to_L", .false., CS%restart_CSp, & + "Length unit conversion factor", "L meter-1") + call register_restart_field(US%kg_m3_to_R_restart, "kg_m3_to_R", .false., CS%restart_CSp, & + "Density unit conversion factor", "R m3 kg-1") + if (CS%active_shelf_dynamics) then + call register_restart_field(ISS%hmask, "h_mask", .true., CS%restart_CSp, & + "ice sheet/shelf thickness mask" ,"none") + endif + + if (CS%active_shelf_dynamics) then + ! Allocate CS%dCS and specify additional restarts for ice shelf dynamics + call register_ice_shelf_dyn_restarts(CS%Grid_in, param_file, CS%dCS, CS%restart_CSp) + endif + + !GMM - I think we do not need to save ustar_shelf and iceshelf_melt in the restart file + !if (.not. CS%solo_ice_sheet) then + ! call register_restart_field(fluxes%ustar_shelf, "ustar_shelf", .false., CS%restart_CSp, & + ! "Friction velocity under ice shelves", "m s-1") + !endif + + CS%restart_output_dir = dirs%restart_output_dir + + CS%Time = Time + if (CS%active_shelf_dynamics .and. .not.CS%isthermo) then ISS%water_flux(:,:) = 0.0 endif if (shelf_mass_is_dynamic) & - call initialize_ice_shelf_dyn(param_file, Time, ISS, CS%dCS, G, US, diag, new_sim, solo_ice_sheet_in) + call initialize_ice_shelf_dyn(param_file, Time, ISS, CS%dCS, G, US, CS%diag, new_sim, solo_ice_sheet_in) call fix_restart_unit_scaling(US) @@ -1838,14 +1804,83 @@ subroutine initialize_ice_shelf(param_file, ocn_grid, Time, CS, diag, forces_in, endif call diag_mediator_close_registration(CS%diag) - - if (present(fluxes_in) .and. CS%rotate_index) & - call rotate_forcing(fluxes, fluxes_in, -CS%turns) - if (present(forces_in) .and. CS%rotate_index) & - call rotate_mech_forcing(forces, -CS%turns, forces_in) + if (present(fluxes_in)) call initialize_ice_shelf_fluxes(CS, ocn_grid, US, fluxes_in) + if (present(forces_in)) call initialize_ice_shelf_forces(CS, ocn_grid, US, forces_in) end subroutine initialize_ice_shelf +subroutine initialize_ice_shelf_fluxes(CS, ocn_grid, US, fluxes_in) + type(ice_shelf_CS), pointer :: CS !< A pointer to the ice shelf control structure + type(ocean_grid_type), pointer :: ocn_grid !< The calling ocean model's horizontal grid structure + type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type + type(forcing), target, intent(inout) :: fluxes_in !< A structure containing pointers to any + !! possible thermodynamic or mass-flux forcing fields. + + ! Local variables + type(ocean_grid_type), pointer :: G => NULL() ! Pointers to grids for convenience. + type(forcing), pointer :: fluxes => NULL() + integer :: i, j, isd, ied, jsd, jed + + G => CS%Grid + isd = G%isd ; jsd = G%jsd ; ied = G%ied ; jed = G%jed + + ! Allocate the arrays for passing ice-shelf data through the forcing type. + if (.not. CS%solo_ice_sheet) then + call MOM_mesg("MOM_ice_shelf.F90, initialize_ice_shelf: allocating fluxes.") + ! GMM: the following assures that water/heat fluxes are just allocated + ! when SHELF_THERMO = True. These fluxes are necessary if one wants to + ! use either ENERGETICS_SFC_PBL (ALE mode) or BULKMIXEDLAYER (layer mode). + call allocate_forcing_type(CS%Grid_in, fluxes_in, ustar=.true., shelf=.true., & + press=.true., water=CS%isthermo, heat=CS%isthermo) + else + call MOM_mesg("MOM_ice_shelf.F90, initialize_ice_shelf: allocating fluxes in solo mode.") + call allocate_forcing_type(CS%Grid_in, fluxes_in, ustar=.true., shelf=.true., press=.true.) + endif + if (CS%rotate_index) then + allocate(fluxes) + call allocate_forcing_type(fluxes_in, CS%Grid, fluxes) + call rotate_forcing(fluxes_in, fluxes, CS%turns) + else + fluxes=>fluxes_in + endif + + do j=jsd,jed ; do i=isd,ied + if (G%areaT(i,j)>0.) fluxes%frac_shelf_h(i,j) = CS%ISS%area_shelf_h(i,j) / G%areaT(i,j) + enddo ; enddo + if (CS%debug) call hchksum(fluxes%frac_shelf_h, "IS init: frac_shelf_h", G%HI, haloshift=0) + call add_shelf_pressure(ocn_grid, US, CS, fluxes) + + if (CS%rotate_index) & + call rotate_forcing(fluxes, fluxes_in, -CS%turns) + +end subroutine initialize_ice_shelf_fluxes + +subroutine initialize_ice_shelf_forces(CS, ocn_grid, US, forces_in) + type(ice_shelf_CS), pointer :: CS !< A pointer to the ice shelf control structure + type(ocean_grid_type), pointer :: ocn_grid !< The calling ocean model's horizontal grid structure + type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type + type(mech_forcing), target, intent(inout) :: forces_in !< A structure with the driving mechanical forces + + ! Local variables + type(mech_forcing), pointer :: forces => NULL() + + call MOM_mesg("MOM_ice_shelf.F90, initialize_ice_shelf: allocating forces.") + call allocate_mech_forcing(CS%Grid_in, forces_in, ustar=.true., shelf=.true., press=.true.) + if (CS%rotate_index) then + allocate(forces) + call allocate_mech_forcing(forces_in, CS%Grid, forces) + call rotate_mech_forcing(forces_in, CS%turns, forces) + else + forces=>forces_in + endif + + call add_shelf_forces(ocn_grid, US, CS, forces, do_shelf_area=.not.CS%solo_ice_sheet) + + if (CS%rotate_index) & + call rotate_mech_forcing(forces, -CS%turns, forces_in) + +end subroutine initialize_ice_shelf_forces + !> Initializes shelf mass based on three options (file, zero and user) subroutine initialize_shelf_mass(G, param_file, CS, ISS, new_sim) @@ -1930,7 +1965,7 @@ end subroutine initialize_shelf_mass !> Updates the ice shelf mass using data from a file. subroutine update_shelf_mass(G, US, CS, ISS, Time) type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. - type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type + type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(ice_shelf_CS), intent(in) :: CS !< A pointer to the ice shelf control structure type(ice_shelf_state), intent(inout) :: ISS !< The ice shelf state type that is being updated type(time_type), intent(in) :: Time !< The current model time @@ -2039,6 +2074,7 @@ subroutine ice_shelf_end(CS) if (CS%active_shelf_dynamics) call ice_shelf_dyn_end(CS%dCS) + call diag_mediator_end(CS%diag) deallocate(CS) end subroutine ice_shelf_end diff --git a/src/ice_shelf/MOM_ice_shelf_diag_mediator.F90 b/src/ice_shelf/MOM_ice_shelf_diag_mediator.F90 index ab4245bd83..5db9646dae 100644 --- a/src/ice_shelf/MOM_ice_shelf_diag_mediator.F90 +++ b/src/ice_shelf/MOM_ice_shelf_diag_mediator.F90 @@ -304,11 +304,15 @@ subroutine post_data(diag_field_id, field, diag_cs, is_static, mask) used = send_data(fms_diag_id, locfield, & is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, mask=mask) elseif(i_data .and. associated(diag%mask2d)) then +! used = send_data(fms_diag_id, locfield, & +! is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, rmask=diag%mask2d) used = send_data(fms_diag_id, locfield, & - is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, rmask=diag%mask2d) + is_in=isv, js_in=jsv, ie_in=iev, je_in=jev) elseif((.not.i_data) .and. associated(diag%mask2d_comp)) then +! used = send_data(fms_diag_id, locfield, & +! is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, rmask=diag%mask2d_comp) used = send_data(fms_diag_id, locfield, & - is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, rmask=diag%mask2d_comp) + is_in=isv, js_in=jsv, ie_in=iev, je_in=jev) else used = send_data(fms_diag_id, locfield, & is_in=isv, js_in=jsv, ie_in=iev, je_in=jev) @@ -318,14 +322,23 @@ subroutine post_data(diag_field_id, field, diag_cs, is_static, mask) used = send_data(fms_diag_id, locfield, diag_cs%time_end, & is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, & weight=diag_cs%time_int, mask=mask) +! used = send_data(fms_diag_id, locfield, diag_cs%time_end, & +! is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, & +! weight=diag_cs%time_int) elseif(i_data .and. associated(diag%mask2d)) then +! used = send_data(fms_diag_id, locfield, diag_cs%time_end, & +! is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, & +! weight=diag_cs%time_int, rmask=diag%mask2d) used = send_data(fms_diag_id, locfield, diag_cs%time_end, & is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, & - weight=diag_cs%time_int, rmask=diag%mask2d) + weight=diag_cs%time_int) elseif((.not.i_data) .and. associated(diag%mask2d_comp)) then +! used = send_data(fms_diag_id, locfield, diag_cs%time_end, & +! is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, & +! weight=diag_cs%time_int, rmask=diag%mask2d_comp) used = send_data(fms_diag_id, locfield, diag_cs%time_end, & is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, & - weight=diag_cs%time_int, rmask=diag%mask2d_comp) + weight=diag_cs%time_int) else used = send_data(fms_diag_id, locfield, diag_cs%time_end, & is_in=isv, js_in=jsv, ie_in=iev, je_in=jev, & @@ -483,7 +496,6 @@ function register_MOM_IS_diag_field(module_name, field_name, axes, init_time, & !Decide what mask to use based on the axes info if (primary_id > 0) then - !3d masks !2d masks if (axes%rank == 2) then diag%mask2d => null() ; diag%mask2d_comp => null() @@ -682,7 +694,7 @@ subroutine diag_masks_set(G, missing_value, diag_cs) type(diag_ctrl), intent(inout) :: diag_cs !< A structure that is used to regulate diagnostic output ! Local variables - integer :: i, j, k, NkIce, CatIce + integer :: i, j diag_cs%mask2dT => G%mask2dT @@ -711,8 +723,7 @@ subroutine diag_mediator_close_registration(diag_CS) end subroutine diag_mediator_close_registration !> Deallocate memory associated with the MOM_IS diag mediator -subroutine diag_mediator_end(time, diag_CS) - type(time_type), intent(in) :: time !< The current model time +subroutine diag_mediator_end(diag_CS) type(diag_ctrl), intent(inout) :: diag_CS !< A structure that is used to regulate diagnostic output if (diag_CS%doc_unit > -1) then