From d5e788396e6c51aa71528f0b199a276c3584b954 Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Fri, 29 May 2020 10:58:32 -0400 Subject: [PATCH] +Added TRANSMUTE_ICE option Added the option, controlled by the new TRANSMUTE_ICE runtime parameter, to transform ice and snow directly into seawater with a spatially variable rate, read from the file specified by TRANSMUTATION_RATE_FILE, as a form of simple outflow boundary condition on the sea ice. This commit includes the addition of two new allocatable arrays in the ice_ocean_flux_type to facilitate monitoring of pseudo-conservation of heat and salt (bearing in mind that the transmutation itself causes non-conservation of heat and salt). There is also a new optional argument to alloc_ice_ocean_flux. Also replaced calls to mpp_clock with calls to cpu_clock from the MOM_cpu_clock module, and replaced calls to file_exist from FMS_io_mod with calls to file_exists from MOM_io, both in the modules that are already being modified for this commit. All answers in the MOM6-examples test suite are bitwise identical, but there are new entries in the SIS_parameter_doc files, and there are two new elements in a public type and a new optional argument in a public subroutine interface. --- src/SIS_slow_thermo.F90 | 161 ++++++++++++++++++++++++++++++---------- src/SIS_sum_output.F90 | 6 ++ src/SIS_types.F90 | 54 +++++++++----- src/ice_model.F90 | 67 +++++++++-------- 4 files changed, 200 insertions(+), 88 deletions(-) diff --git a/src/SIS_slow_thermo.F90 b/src/SIS_slow_thermo.F90 index 3c480b6c..1264b8f6 100644 --- a/src/SIS_slow_thermo.F90 +++ b/src/SIS_slow_thermo.F90 @@ -33,15 +33,15 @@ module SIS_slow_thermo use MOM_error_handler, only : callTree_enter, callTree_leave, callTree_waypoint use MOM_file_parser, only : get_param, log_param, log_version, param_file_type use MOM_hor_index, only : hor_index_type +use MOM_io, only : file_exists, MOM_read_data, slasher use MOM_unit_scaling, only : unit_scale_type use MOM_EOS, only : EOS_type, calculate_density_derivs use coupler_types_mod, only : coupler_type_spawn, coupler_type_initialized use coupler_types_mod, only : coupler_type_increment_data, coupler_type_rescale_data use coupler_types_mod, only : coupler_type_send_data -use fms_mod, only : clock_flag_default -use mpp_mod, only : mpp_clock_id, mpp_clock_begin, mpp_clock_end -use mpp_mod, only : CLOCK_COMPONENT, CLOCK_LOOP, CLOCK_ROUTINE +use MOM_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end +use MOM_cpu_clock, only : CLOCK_COMPONENT, CLOCK_LOOP, CLOCK_ROUTINE use MOM_time_manager, only : time_type, time_type_to_real ! use MOM_time_manager, only : operator(+), operator(-) @@ -110,8 +110,8 @@ module SIS_slow_thermo logical :: do_ice_limit !< Limit the sea ice thickness to max_ice_limit. real :: max_ice_limit !< The maximum sea ice thickness [Z ~> m], when do_ice_limit is true. - logical :: nudge_sea_ice = .false. !< If true, nudge sea ice concentrations towards observations. - real :: nudge_sea_ice_rate = 0.0 !< The rate of cooling of ice-free water that should be ice + logical :: nudge_sea_ice !< If true, nudge sea ice concentrations towards observations. + real :: nudge_sea_ice_rate !< The rate of cooling of ice-free water that should be ice !! covered in order to constrained the ice concentration to track !! observations [Q R Z T-1 ~> W m-2]. A suggested value is of order 10000 W m-2. real :: nudge_stab_fac !< A factor that determines whether the buoyancy flux associated with @@ -120,6 +120,10 @@ module SIS_slow_thermo !! The default is 1. real :: nudge_conc_tol !< The tolerance for mismatch in the sea ice concentations !! before nudging begins to be applied. + logical :: transmute_ice !< If true, allow ice to be transmuted directly into seawater with a + !! spatially varying rate as a form of outflow open boundary condition. + real, allocatable, dimension(:,:) :: transmutation_rate !< A spatially varying rate with which + !! sea ice and snow are converted into sea-water [T-1 ~> s-1] logical :: debug !< If true, write verbose checksums for debugging purposes. logical :: column_check !< If true, enable the heat check column by column. @@ -351,12 +355,12 @@ subroutine slow_thermodynamics(IST, dt_slow, CS, OSS, FIA, XSF, IOF, G, US, IG) ! ! conservation checks: top fluxes ! - call mpp_clock_begin(iceClock7) + call cpu_clock_begin(iceClock7) call accumulate_input_1(IST, FIA, OSS, dt_slow, G, US, IG, CS%sum_output_CSp) if (CS%column_check) & call write_ice_statistics(IST, CS%Time, CS%n_calls, G, US, IG, CS%sum_output_CSp, & message=" SIS_slow_thermo", check_column=.true.) - call mpp_clock_end(iceClock7) + call cpu_clock_end(iceClock7) ! ! Thermodynamics @@ -390,15 +394,14 @@ subroutine slow_thermodynamics(IST, dt_slow, CS, OSS, FIA, XSF, IOF, G, US, IG) call coupler_type_rescale_data(IOF%tr_flux_ocn_top, 0.0) call coupler_type_increment_data(FIA%tr_flux, IST%part_size, IOF%tr_flux_ocn_top) - ! No other thermodynamics need to be done for ice that is specified, + ! No other thermodynamics need to be done for ice that is specified. if (CS%specified_ice) then if (associated(XSF)) call add_excess_fluxes(IOF, XSF, G, US) return endif - ! Otherwise, Continue with the remainder of the prognostic slow thermodynamics !TOM> Store old ice mass per unit area for calculating partial ice growth. - mi_old = IST%mH_ice + mi_old(:,:,:) = IST%mH_ice(:,:,:) !TOM> derive ridged ice fraction prior to thermodynamic changes of ice thickness ! in order to subtract ice melt proportionally from ridged ice volume (see below) @@ -433,7 +436,7 @@ subroutine slow_thermodynamics(IST, dt_slow, CS, OSS, FIA, XSF, IOF, G, US, IG) if (CS%do_ridging) then ! ice growth (IST%mH_ice > mi_old) does not affect ridged ice volume ! ice melt (IST%mH_ice < mi_old) reduces ridged ice volume proportionally -!$OMP parallel do default(none) shared(isc,iec,jsc,jec,ncat,IST,mi_old,rdg_frac) + !$OMP parallel do default(none) shared(isc,iec,jsc,jec,ncat,IST,mi_old,rdg_frac) do j=jsc,jec ; do k=1,ncat ; do i=isc,iec if (IST%mH_ice(i,j,k) < mi_old(i,j,k)) & IST%rdg_mice(i,j,k) = IST%rdg_mice(i,j,k) + rdg_frac(i,j,k) * & @@ -625,11 +628,17 @@ subroutine SIS2_thermodynamics(IST, dt_slow, CS, OSS, FIA, IOF, G, US, IG) real :: Idt_slow ! The inverse of the thermodynamic step [T-1 ~> s-1]. real :: yr_dtslow ! The ratio of 1 year to the thermodyamic time step times some scaling ! factors, used to change the units of several diagnostics to rate yr-1. - real :: heat_to_ocn ! The heat passed from the ice to the ocean [Q R Z ~> J m-2] + real :: heat_to_ocn ! The heat passed from the ice to the ocean [Q R Z ~> J m-2] + real :: water_to_ocn ! The water passed to the ocean [R Z ~> kg m-2] + real :: salt_to_ocn ! The salt passed to the ocean [R Z gSalt kg-1 ~> gSalt m-2] + real :: heat_from_ice ! The heat extracted from the ice [Q R Z ~> J m-2] + real :: water_from_ice ! The water extracted from the ice [R Z ~> kg m-2] + real :: salt_from_ice ! The salt extracted from the ice [R Z gSalt kg-1 ~> gSalt m-2] + real :: ice_loss ! The loss of ice mass from transmutation [R Z ~> kg m-2] + real :: snow_loss ! The loss of snow mass from transmutation [R Z ~> kg m-2] real :: h2o_ice_to_ocn ! The downward water flux from the ice to the ocean [R Z ~> kg m-2] real :: h2o_ocn_to_ice ! The upward water flux from the ocean to the ice [R Z ~> kg m-2] real :: evap_from_ocn ! The evaporation from the ocean [R Z ~> kg m-2] - real :: sn2ic real :: bablt ! The bottom ablation ice loss [R Z ~> kg m-2] real :: salt_to_ice ! The flux of salt from the ocean to the ice [R Z gSalt kg-1 ~> gSalt m-2]. ! This may be of either sign; in some places it is an @@ -650,12 +659,12 @@ subroutine SIS2_thermodynamics(IST, dt_slow, CS, OSS, FIA, IOF, G, US, IG) real :: enth_to_melt ! The enthalpy addition required to melt the excess ice ! and snow [Q R Z ~> J m-2]. real :: I_Nk ! The inverse of the number of layers in the ice [nondim]. - real :: part_sum ! A running sum of partition sizes. - real :: part_ocn ! A slightly modified ocean part size. + real :: part_sum ! A running sum of partition sizes [nondim]. + real :: part_ocn ! A slightly modified ocean part size [nondim]. real :: d_enth ! The change in enthalpy between categories [Q R Z ~> J m-2]. real :: fill_frac ! The fraction of the difference between the thicknesses ! in thin categories that will be removed within a single - ! timestep with filling_frazil. + ! timestep with filling_frazil [nondim]. real :: sw_tot ! The total shortwave radiation incident on a category [Q R Z T-1 ~> W m-2]. integer :: i, j, k, l, m, n, b, nb, isc, iec, jsc, jec, ncat, NkIce, tr, npassive integer :: k_merge @@ -681,7 +690,7 @@ subroutine SIS2_thermodynamics(IST, dt_slow, CS, OSS, FIA, IOF, G, US, IG) if (.not.spec_thermo_sal) call SIS_error(FATAL, "SIS2_thermodynamics is not "//& "prepared for SPECIFIED_THERMO_SALINITY to be false.") - call mpp_clock_begin(iceClock6) + call cpu_clock_begin(iceClock6) ! Add any heat fluxes to restore the sea-ice properties toward a prescribed ! state, potentially including freshwater fluxes to avoid driving oceanic ! convection. @@ -777,7 +786,7 @@ subroutine SIS2_thermodynamics(IST, dt_slow, CS, OSS, FIA, IOF, G, US, IG) endif enddo ; enddo endif - call mpp_clock_end(iceClock6) + call cpu_clock_end(iceClock6) if (CS%column_check) then @@ -814,7 +823,7 @@ subroutine SIS2_thermodynamics(IST, dt_slow, CS, OSS, FIA, IOF, G, US, IG) enddo endif - call mpp_clock_begin(iceClock5) + call cpu_clock_begin(iceClock5) snow_to_ice(:,:,:) = 0.0 ; net_melt(:,:) = 0.0 bsnk(:,:) = 0.0 @@ -883,7 +892,7 @@ subroutine SIS2_thermodynamics(IST, dt_slow, CS, OSS, FIA, IOF, G, US, IG) !$OMP heat_mass_in,mass_in,mass_here,enth_here, & !$OMP tot_heat_in,enth_imb,mass_imb,norm_enth_imb, & !$OMP m_lay, mtot_ice, TrLay,sw_tot, & -!$OMP I_part,sn2ic,enth_snowfall) +!$OMP I_part,enth_snowfall) do j=jsc,jec ; do k=1,ncat ; do i=isc,iec if (G%mask2dT(i,j) > 0 .and. IST%part_size(i,j,k) > 0) then ! reshape the ice based on fluxes @@ -1025,7 +1034,7 @@ subroutine SIS2_thermodynamics(IST, dt_slow, CS, OSS, FIA, IOF, G, US, IG) !$OMP heat_input,heat_mass_in,mass_in,mass_here,enth_here, & !$OMP tot_heat_in,enth_imb,mass_imb,norm_enth_imb,m_lay, & !$OMP mtot_ice,frazil_cat,k_merge,part_sum,fill_frac,d_enth, & - !$OMP TrLay,I_part,sn2ic,enth_snowfall) + !$OMP TrLay,I_part,enth_snowfall) do j=jsc,jec ; do i=isc,iec ; if (FIA%frazil_left(i,j)>0.0) then frazil_cat(1:ncat) = 0.0 @@ -1178,18 +1187,14 @@ subroutine SIS2_thermodynamics(IST, dt_slow, CS, OSS, FIA, IOF, G, US, IG) endif ; enddo ; enddo ! frazil>0, i-, and j-loops - call mpp_clock_end(iceClock5) + call cpu_clock_end(iceClock5) - call mpp_clock_begin(iceClock6) + call cpu_clock_begin(iceClock6) if (CS%do_ice_limit) then qflx_lim_ice(:,:) = 0.0 -!$OMP parallel do default(none) shared(isc,iec,jsc,jec,ncat,NkIce,IST,G,US, & -!$OMP spec_thermo_sal,I_Nk,S_col,dt_slow, & -!$OMP snow_to_ice,salt_change,qflx_lim_ice, & -!$OMP Idt_slow,net_melt,IG,CS,IOF,FIA,rho_ice) & -!$OMP private(mtot_ice,frac_keep,frac_melt,salt_to_ice, & -!$OMP h2o_ice_to_ocn,enth_to_melt,enth_ice_to_ocn, & -!$OMP ice_melt_lay,snow_melt,enth_freeze) + !$OMP parallel do default(shared) private(mtot_ice,frac_keep,frac_melt,salt_to_ice, & + !$OMP h2o_ice_to_ocn,enth_to_melt,enth_ice_to_ocn, & + !$OMP ice_melt_lay,snow_melt,enth_freeze) do j=jsc,jec ; do i=isc,iec mtot_ice = 0.0 do k=1,ncat @@ -1234,17 +1239,17 @@ subroutine SIS2_thermodynamics(IST, dt_slow, CS, OSS, FIA, IOF, G, US, IG) enddo ; enddo endif ! End of (CS%do_ice_limit) block - call mpp_clock_end(iceClock6) + call cpu_clock_end(iceClock6) if (CS%column_check) then enth_col(:,:) = 0.0 ! Add back any frazil that has not been used yet. -!$OMP parallel do default(none) shared(isc,iec,jsc,jec,heat_in_col,IST,dt_slow,FIA,IOF) + !$OMP parallel do default(shared) do j=jsc,jec ; do i=isc,iec heat_in_col(i,j) = heat_in_col(i,j) + FIA%frazil_left(i,j) + & IOF%flux_sh_ocn_top(i,j)*dt_slow enddo ; enddo -!$OMP parallel do default(none) shared(isc,iec,jsc,jec,ncat,G,enth_col,IST,I_Nk,NkIce) + !$OMP parallel do default(shared) do j=jsc,jec ; do k=1,ncat ; do i=isc,iec ; if (IST%part_size(i,j,k)*IST%mH_ice(i,j,k) > 0.0) then enth_col(i,j) = enth_col(i,j) + & (IST%mH_snow(i,j,k)*IST%part_size(i,j,k)) * IST%enth_snow(i,j,k,1) @@ -1253,10 +1258,8 @@ subroutine SIS2_thermodynamics(IST, dt_slow, CS, OSS, FIA, IOF, G, US, IG) (IST%mH_ice(i,j,k)*IST%part_size(i,j,k)*I_Nk) * IST%enth_ice(i,j,k,m) enddo endif ; enddo ; enddo ; enddo -!$OMP parallel do default(none) shared(isc,iec,jsc,jec,enth_col,IST, & -!$OMP heat_in_col,enth_mass_in_col,enth_prev_col,IOF,CS) & -!$OMP private(enth_here,tot_heat_in,emic2,tot_heat_in2, & -!$OMP enth_imb,norm_enth_imb,enth_imb2) + !$OMP parallel do default(shared) private(enth_here,tot_heat_in,emic2,tot_heat_in2, & + !$OMP enth_imb,norm_enth_imb,enth_imb2) do j=jsc,jec ; do i=isc,iec enth_here = enth_col(i,j) tot_heat_in = heat_in_col(i,j) + enth_mass_in_col(i,j) @@ -1300,6 +1303,41 @@ subroutine SIS2_thermodynamics(IST, dt_slow, CS, OSS, FIA, IOF, G, US, IG) enddo enddo + ! Optionally cause the ice to be converted into sea-water with the ocean properties at a + ! spatially varying rate by reduction of the part size. The thicknesses do not change. + if (CS%transmute_ice .and. allocated(CS%transmutation_rate)) then + do j=jsc,jec ; do i=isc,iec ; if (CS%transmutation_rate(i,j) > 0.0) then + salt_from_ice = 0.0 ; heat_from_ice = 0.0 ; water_from_ice = 0.0 + + frac_keep = exp(-dt_slow*CS%transmutation_rate(i,j)) + do k=1,ncat ; if (IST%part_size(i,j,k) > 0.0) then + ice_loss = (1.0 - frac_keep) * IST%mH_ice(i,j,k)*IST%part_size(i,j,k) + do m=1,NkIce + salt_from_ice = salt_from_ice + (ice_loss * I_Nk) * IST%sal_ice(i,j,k,m) + heat_from_ice = heat_from_ice + (ice_loss * I_Nk) * IST%enth_ice(i,j,k,m) + enddo + snow_loss = (1.0 - frac_keep) * IST%mH_snow(i,j,k)*IST%part_size(i,j,k) + heat_from_ice = heat_from_ice + snow_loss * IST%enth_snow(i,j,k,1) + + water_from_ice = ice_loss + snow_loss + IST%part_size(i,j,k) = frac_keep * IST%part_size(i,j,k) + endif ; enddo + + water_to_ocn = water_from_ice + heat_to_ocn = water_from_ice * enthalpy_liquid(OSS%SST_C(i,j), OSS%s_surf(i,j), IST%ITV) + salt_to_ocn = water_from_ice * OSS%s_surf(i,j) + + ! With transmuted ice, the ice is non-conservatively changed to match the ocean properties. + IOF%flux_salt(i,j) = IOF%flux_salt(i,j) + salt_to_ocn * (0.001*Idt_slow) + net_melt(i,j) = net_melt(i,j) + water_to_ocn * Idt_slow ! This goes to IOF%lprec_ocn_top. + IOF%Enth_mass_out_ocn(i,j) = IOF%Enth_mass_out_ocn(i,j) + heat_to_ocn + + ! With transmuted ice, the imbalances are stored to close the heat and salt budgets. + IOF%transmutation_salt_flux(i,j) = (salt_from_ice - salt_to_ocn) * (0.001*Idt_slow) + IOF%transmutation_enth(i,j) = (heat_from_ice - heat_to_ocn) + endif ; enddo ; enddo + endif + ! The remainder of this routine deals with any thermodynamics diagnostic ! output that has been requested. call enable_SIS_averaging(US%T_to_s*dt_slow, CS%Time, CS%diag) @@ -1370,6 +1408,10 @@ subroutine SIS_slow_thermo_init(Time, G, US, IG, param_file, diag, CS, tracer_fl #include "version_variable.h" character(len=40) :: mdl = "SIS_slow_thermo" ! This module's name. logical :: debug + real :: transmute_scale ! A scaling factor to use when reading the transmutation rate. + character(len=64) :: transmute_var ! Transmutation rate variable name in file + character(len=200) :: filename, transmute_file, inputdir ! Strings for file/path + integer :: i, j real, parameter :: missing = -1e34 call callTree_enter("SIS_slow_thermo_init(), SIS_slow_thermo.F90") @@ -1440,7 +1482,8 @@ subroutine SIS_slow_thermo_init(Time, G, US, IG, param_file, diag, CS, tracer_fl "The rate of cooling of ice-free water that should be ice "//& "covered in order to constrained the ice concentration to "//& "track observations. A suggested value is ~10000 W m-2.", & - units = "W m-2", default=0.0, scale=US%W_m2_to_QRZ_T, do_not_log=.not.CS%nudge_sea_ice) + units = "W m-2", default=0.0, scale=US%W_m2_to_QRZ_T, & + do_not_log=.not.CS%nudge_sea_ice) call get_param(param_file, mdl, "NUDGE_SEA_ICE_TOLERANCE", CS%nudge_conc_tol, & "The tolerance for mismatch in the sea ice concentations "//& "before nudging begins to be applied. Values of order 0.1 "//& @@ -1453,6 +1496,42 @@ subroutine SIS_slow_thermo_init(Time, G, US, IG, param_file, diag, CS, tracer_fl "stabilizing (>1), or neutral (=1).", units="nondim", & default=1.0, do_not_log=.not.CS%nudge_sea_ice) + call get_param(param_file, mdl, "TRANSMUTE_SEA_ICE", CS%transmute_ice, & + "If true, allow ice to be transmuted directly into seawater with a spatially "//& + "spatially varying rate as a form of outflow open boundary condition.", & + default=.false.) + if (CS%transmute_ice) then + + allocate(CS%transmutation_rate(SZI_(G), SZJ_(G))) ; CS%transmutation_rate(:,:) = 0.0 + call get_param(param_file, mdl, "INPUTDIR", inputdir, default=".") + call get_param(param_file, mdl, "TRANSMUTATION_RATE_FILE", transmute_file, & + "The file from which the transmutation rate should be read.", & + fail_if_missing=.true.) + filename = trim(slasher(inputdir))//trim(transmute_file) + call log_param(param_file, mdl, "INPUTDIR/TRANSMUTATION_RATE_FILE", filename) + call get_param(param_file, mdl, "TRANSMUTATION_RATE_VAR", transmute_var, & + "The variable with the map of sea-ice transmutation rate. No transmutation "//& + "occurs where this field is 0.", default="transmute_rate") + call get_param(param_file, mdl, "TRANSMUTATION_RATE_RESCALE", transmute_scale, & + "A rescaling factor to use when reading the transmutation rate to scale it "//& + "to units of [s-1]. If this factor is negative, the field that is being read "//& + "is a timescale, so the rate is the Adcroft reciprocal of the field that is "//& + "read times this scaling factor", default=1.0, units="nondim") + + if (.not.file_exists(filename, G%Domain)) call SIS_error(FATAL, & + " SIS_slow_thermo_init: Unable to open transmutation rate file "//trim(filename)) + if (transmute_scale >= 0.0) then + call MOM_read_data(filename, transmute_var, CS%transmutation_rate, G%Domain, scale=transmute_scale*US%T_to_s) + else ! When (transmute_scale < 0.0) read the scaled timescales, then take their Adcroft reciprocal. + call MOM_read_data(filename, transmute_var, CS%transmutation_rate, G%Domain, scale=(-transmute_scale)*US%s_to_T) + do j=G%jsc,G%jec ; do i=G%isc,G%iec + if (abs(CS%transmutation_rate(i,j)) > 0.0) & + CS%transmutation_rate(i,j) = 1.0 / (abs(CS%transmutation_rate(i,j))) + enddo ; enddo + endif + + endif + call get_param(param_file, mdl, "DEBUG", debug, & "If true, write out verbose debugging data.", & default=.false., debuggingParam=.true.) @@ -1506,9 +1585,9 @@ subroutine SIS_slow_thermo_init(Time, G, US, IG, param_file, diag, CS, tracer_fl call SIS2_ice_thm_init(US, param_file, CS%ice_thm_CSp) - iceClock7 = mpp_clock_id( ' Ice: slow: conservation check', flags=clock_flag_default, grain=CLOCK_LOOP ) - iceClock5 = mpp_clock_id( ' Ice: slow: thermodynamics', flags=clock_flag_default, grain=CLOCK_LOOP ) - iceClock6 = mpp_clock_id( ' Ice: slow: restore/limit', flags=clock_flag_default, grain=CLOCK_LOOP ) + iceClock7 = cpu_clock_id( ' Ice: slow: conservation check', grain=CLOCK_LOOP ) + iceClock5 = cpu_clock_id( ' Ice: slow: thermodynamics', grain=CLOCK_LOOP ) + iceClock6 = cpu_clock_id( ' Ice: slow: restore/limit', grain=CLOCK_LOOP ) call callTree_leave("SIS_slow_thermo_init()") diff --git a/src/SIS_sum_output.F90 b/src/SIS_sum_output.F90 index 8bcfa6bf..4623799d 100644 --- a/src/SIS_sum_output.F90 +++ b/src/SIS_sum_output.F90 @@ -750,6 +750,7 @@ subroutine accumulate_bottom_input(IST, OSS, FIA, IOF, dt, G, US, IG, CS) CS%water_in_col(i,j) = CS%water_in_col(i,j) - dt * & ( ((FIA%runoff(i,j) + FIA%calving(i,j)) + & (IOF%lprec_ocn_top(i,j) + IOF%fprec_ocn_top(i,j))) - IOF%evap_ocn_top(i,j) ) + Flux_SW = 0.0 do b=2,nb,2 ! This sum combines direct and diffuse fluxes to preserve answers. Flux_SW = Flux_SW + (IOF%flux_sw_ocn(i,j,b-1) + IOF%flux_sw_ocn(i,j,b)) @@ -761,7 +762,12 @@ subroutine accumulate_bottom_input(IST, OSS, FIA, IOF, dt, G, US, IG, CS) CS%heat_in_col(i,j) = CS%heat_in_col(i,j) + & ((IOF%Enth_Mass_in_atm(i,j) + IOF%Enth_Mass_in_ocn(i,j)) + & (IOF%Enth_Mass_out_atm(i,j) + IOF%Enth_Mass_out_ocn(i,j)) ) + if (allocated(IOF%transmutation_enth)) & + CS%heat_in_col(i,j) = CS%heat_in_col(i,j) + IOF%transmutation_enth(i,j) + CS%salt_in_col(i,j) = CS%salt_in_col(i,j) + dt * IOF%flux_salt(i,j) + if (allocated(IOF%transmutation_salt_flux)) & + CS%salt_in_col(i,j) = CS%salt_in_col(i,j) + dt * IOF%transmutation_salt_flux(i,j) enddo ; enddo end subroutine accumulate_bottom_input diff --git a/src/SIS_types.F90 b/src/SIS_types.F90 index f5c29a3d..414e9e95 100644 --- a/src/SIS_types.F90 +++ b/src/SIS_types.F90 @@ -367,7 +367,10 @@ module SIS_types stress_mag, & !< The area-weighted time-mean of the magnitude of the stress on the ocean [R Z L T-2 ~> Pa]. melt_nudge, & !< A downward fresh water flux into the ocean that acts to nudge the ocean !! surface salinity to facilitate the retention of sea ice [R Z T-1 ~> kg m-2 s-1]. - flux_salt, & !< The flux of salt out of the ocean [kgSalt kg-1 R Z T-1 ~> kgSalt m-2]. + flux_salt, & !< The flux of salt out of the ocean [kgSalt kg-1 R Z T-1 ~> kgSalt m-2 s-1]. + transmutation_salt_flux, & !< The difference between the salt flux extracted from the ice and the + !! salt flux added to the ocean when the ice is transmuted directly into seawater + !! as a form of open boundary condition [kgSalt kg-1 R Z T-1 ~> kgSalt m-2 s-1]. mass_ice_sn_p, & !< The combined mass per unit ocean area of ice, snow and pond water [R Z ~> kg m-2]. pres_ocn_top !< The hydrostatic pressure at the ocean surface due to the weight of ice, !! snow and ponds, exclusive of atmospheric pressure [R Z L T-2 ~> Pa]. @@ -394,8 +397,11 @@ module SIS_types Enth_Mass_out_atm, & !< Negative of the enthalpy extracted from the ice by water fluxes to !! the atmosphere [Q R Z ~> J m-2]. Enth_Mass_in_ocn , & !< The enthalpy introduced to the ice by water fluxes from the ocean [Q R Z ~> J m-2]. - Enth_Mass_out_ocn !< Negative of the enthalpy extracted from the ice by water fluxes to + Enth_Mass_out_ocn, & !< Negative of the enthalpy extracted from the ice by water fluxes to !! the ocean [Q R Z ~> J m-2]. + transmutation_enth !< The difference between the enthalpy extracted from the ice and the + !! enthalpy added to the ocean when the ice is transmuted directly into + !! seawater as a form of open boundary condition [Q R Z ~> J m-2]. integer :: stress_count !< The number of times that the stresses from the ice to the ocean have been incremented. integer :: flux_uv_stagger = -999 !< The staggering relative to the tracer points of the two wind @@ -1069,7 +1075,7 @@ end subroutine alloc_ice_rad !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! !> alloc_ice_ocean_flux allocates and zeros out the arrays in an ice_ocean_flux_type. -subroutine alloc_ice_ocean_flux(IOF, HI, do_stress_mag, do_iceberg_fields) +subroutine alloc_ice_ocean_flux(IOF, HI, do_stress_mag, do_iceberg_fields, do_transmute) type(ice_ocean_flux_type), pointer :: IOF !< A structure containing fluxes from the ice to !! the ocean that are calculated by the ice model. type(hor_index_type), intent(in) :: HI !< The horizontal index type describing the domain @@ -1077,7 +1083,9 @@ subroutine alloc_ice_ocean_flux(IOF, HI, do_stress_mag, do_iceberg_fields) !! the magnitude of the ice-ocean stress. logical, optional, intent(in) :: do_iceberg_fields !< If true, allocate fields related !! to exchanges with icebergs - + logical, optional, intent(in) :: do_transmute !< If true, allocate fields related to + !! transmuting ice directly into seawater as a form + !! of open boundary condition integer :: CatIce logical :: alloc_bergs, alloc_stress_mag @@ -1087,6 +1095,9 @@ subroutine alloc_ice_ocean_flux(IOF, HI, do_stress_mag, do_iceberg_fields) if (.not.associated(IOF)) allocate(IOF) allocate(IOF%flux_salt(SZI_(HI), SZJ_(HI))) ; IOF%flux_salt(:,:) = 0.0 + if (do_transmute) then + allocate(IOF%transmutation_salt_flux(SZI_(HI), SZJ_(HI))) ; IOF%transmutation_salt_flux(:,:) = 0.0 + endif allocate(IOF%flux_sh_ocn_top(SZI_(HI), SZJ_(HI))) ; IOF%flux_sh_ocn_top(:,:) = 0.0 allocate(IOF%evap_ocn_top(SZI_(HI), SZJ_(HI))) ; IOF%evap_ocn_top(:,:) = 0.0 @@ -1107,7 +1118,9 @@ subroutine alloc_ice_ocean_flux(IOF, HI, do_stress_mag, do_iceberg_fields) allocate(IOF%Enth_Mass_out_atm(SZI_(HI), SZJ_(HI))) ; IOF%Enth_Mass_out_atm(:,:) = 0.0 allocate(IOF%Enth_Mass_in_ocn(SZI_(HI), SZJ_(HI))) ; IOF%Enth_Mass_in_ocn(:,:) = 0.0 allocate(IOF%Enth_Mass_out_ocn(SZI_(HI), SZJ_(HI))) ; IOF%Enth_Mass_out_ocn(:,:) = 0.0 - + if (do_transmute) then + allocate(IOF%transmutation_enth(SZI_(HI), SZJ_(HI))) ; IOF%transmutation_enth(:,:) = 0.0 + endif ! Allocating iceberg fields (only used if pass_iceberg_area_to_ocean=.True.) ! Please note that these are only allocated on the computational domain so that they ! can be passed conveniently to the iceberg code. @@ -2350,9 +2363,11 @@ subroutine dealloc_ice_ocean_flux(IOF) deallocate(IOF%lprec_ocn_top, IOF%fprec_ocn_top, IOF%flux_salt) deallocate(IOF%flux_u_ocn, IOF%flux_v_ocn, IOF%pres_ocn_top, IOF%mass_ice_sn_p) if (allocated(IOF%stress_mag)) deallocate(IOF%stress_mag) + if (allocated(IOF%transmutation_salt_flux)) deallocate(IOF%transmutation_salt_flux) deallocate(IOF%Enth_Mass_in_atm, IOF%Enth_Mass_out_atm) deallocate(IOF%Enth_Mass_in_ocn, IOF%Enth_Mass_out_ocn) + if (allocated(IOF%transmutation_enth)) deallocate(IOF%transmutation_enth) !Deallocating iceberg fields if (associated(IOF%mass_berg)) deallocate(IOF%mass_berg) @@ -2371,25 +2386,30 @@ subroutine IOF_chksum(mesg, IOF, G, US) type(unit_scale_type), intent(in) :: US !< A structure with unit conversion factors call hchksum(IOF%flux_salt, trim(mesg)//" IOF%flux_salt", G%HI, scale=US%RZ_T_to_kg_m2s) + if (allocated(IOF%transmutation_salt_flux)) & + call hchksum(IOF%transmutation_salt_flux, trim(mesg)//" IOF%transmutation_salt_flux", G%HI, scale=US%RZ_T_to_kg_m2s) - call hchksum(IOF%flux_sh_ocn_top, trim(mesg)//" IOF%flux_sh_ocn_top", G%HI, scale=US%QRZ_T_to_W_m2) - call hchksum(IOF%evap_ocn_top, trim(mesg)//" IOF%evap_ocn_top", G%HI, scale=US%RZ_T_to_kg_m2s) + call hchksum(IOF%flux_sh_ocn_top, trim(mesg)//" IOF%flux_sh_ocn_top", G%HI, scale=US%QRZ_T_to_W_m2) call hchksum(IOF%flux_lw_ocn_top, trim(mesg)//" IOF%flux_lw_ocn_top", G%HI, scale=US%QRZ_T_to_W_m2) call hchksum(IOF%flux_lh_ocn_top, trim(mesg)//" IOF%flux_lh_ocn_top", G%HI, scale=US%QRZ_T_to_W_m2) - call hchksum(IOF%flux_sw_ocn, trim(mesg)//" IOF%flux_sw_ocn", G%HI, scale=US%QRZ_T_to_W_m2) - call hchksum(IOF%lprec_ocn_top, trim(mesg)//" IOF%lprec_ocn_top", G%HI, scale=US%RZ_T_to_kg_m2s) - call hchksum(IOF%fprec_ocn_top, trim(mesg)//" IOF%fprec_ocn_top", G%HI, scale=US%RZ_T_to_kg_m2s) - call hchksum(IOF%flux_u_ocn, trim(mesg)//" IOF%flux_u_ocn", G%HI, scale=US%RZ_T_to_kg_m2s*US%L_T_to_m_s) - call hchksum(IOF%flux_v_ocn, trim(mesg)//" IOF%flux_v_ocn", G%HI, scale=US%RZ_T_to_kg_m2s*US%L_T_to_m_s) - call hchksum(IOF%pres_ocn_top, trim(mesg)//" IOF%pres_ocn_top", G%HI, scale=US%RZ_T_to_kg_m2s*US%L_T_to_m_s) - call hchksum(IOF%mass_ice_sn_p, trim(mesg)//" IOF%mass_ice_sn_p", G%HI, scale=US%RZ_to_kg_m2) + call hchksum(IOF%flux_sw_ocn, trim(mesg)//" IOF%flux_sw_ocn", G%HI, scale=US%QRZ_T_to_W_m2) + call hchksum(IOF%evap_ocn_top, trim(mesg)//" IOF%evap_ocn_top", G%HI, scale=US%RZ_T_to_kg_m2s) + call hchksum(IOF%lprec_ocn_top, trim(mesg)//" IOF%lprec_ocn_top", G%HI, scale=US%RZ_T_to_kg_m2s) + call hchksum(IOF%fprec_ocn_top, trim(mesg)//" IOF%fprec_ocn_top", G%HI, scale=US%RZ_T_to_kg_m2s) + call hchksum(IOF%flux_u_ocn, trim(mesg)//" IOF%flux_u_ocn", G%HI, scale=US%RZ_T_to_kg_m2s*US%L_T_to_m_s) + call hchksum(IOF%flux_v_ocn, trim(mesg)//" IOF%flux_v_ocn", G%HI, scale=US%RZ_T_to_kg_m2s*US%L_T_to_m_s) + call hchksum(IOF%pres_ocn_top, trim(mesg)//" IOF%pres_ocn_top", G%HI, scale=US%RZ_T_to_kg_m2s*US%L_T_to_m_s) + call hchksum(IOF%mass_ice_sn_p, trim(mesg)//" IOF%mass_ice_sn_p", G%HI, scale=US%RZ_to_kg_m2) if (allocated(IOF%stress_mag)) & - call hchksum(IOF%stress_mag, trim(mesg)//" IOF%stress_mag", G%HI, scale=US%RZ_T_to_kg_m2s*US%L_T_to_m_s) + call hchksum(IOF%stress_mag, trim(mesg)//" IOF%stress_mag", G%HI, scale=US%RZ_T_to_kg_m2s*US%L_T_to_m_s) - call hchksum(IOF%Enth_Mass_in_atm, trim(mesg)//" IOF%Enth_Mass_in_atm", G%HI, scale=US%QRZ_T_to_W_m2*US%T_to_s) + call hchksum(IOF%Enth_Mass_in_atm, trim(mesg)//" IOF%Enth_Mass_in_atm", G%HI, scale=US%QRZ_T_to_W_m2*US%T_to_s) call hchksum(IOF%Enth_Mass_out_atm, trim(mesg)//" IOF%Enth_Mass_out_atm", G%HI, scale=US%QRZ_T_to_W_m2*US%T_to_s) - call hchksum(IOF%Enth_Mass_in_ocn, trim(mesg)//" IOF%Enth_Mass_in_ocn", G%HI, scale=US%QRZ_T_to_W_m2*US%T_to_s) + call hchksum(IOF%Enth_Mass_in_ocn, trim(mesg)//" IOF%Enth_Mass_in_ocn", G%HI, scale=US%QRZ_T_to_W_m2*US%T_to_s) call hchksum(IOF%Enth_Mass_out_ocn, trim(mesg)//" IOF%Enth_Mass_out_ocn", G%HI, scale=US%QRZ_T_to_W_m2*US%T_to_s) + + if (allocated(IOF%transmutation_enth)) & + call hchksum(IOF%transmutation_enth, trim(mesg)//" IOF%transmutation_enth", G%HI, scale=US%QRZ_T_to_W_m2*US%T_to_s) end subroutine IOF_chksum !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! diff --git a/src/ice_model.F90 b/src/ice_model.F90 index 0f6abb3f..ebf320c4 100644 --- a/src/ice_model.F90 +++ b/src/ice_model.F90 @@ -32,6 +32,8 @@ module ice_model_mod use SIS_sum_output, only : SIS_sum_output_init, write_ice_statistics use SIS_transcribe_grid, only : copy_dyngrid_to_SIS_horgrid, copy_SIS_horgrid_to_dyngrid +use MOM_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end +use MOM_cpu_clock, only : CLOCK_COMPONENT, CLOCK_SUBCOMPONENT use MOM_domains, only : MOM_domain_type use MOM_domains, only : pass_var, pass_vector, AGRID, BGRID_NE, CGRID_NE use MOM_domains, only : fill_symmetric_edges, MOM_domains_init, clone_MOM_domain @@ -41,6 +43,7 @@ module ice_model_mod use MOM_file_parser, only : get_param, log_param, log_version, read_param, param_file_type use MOM_file_parser, only : open_param_file, close_param_file use MOM_hor_index, only : hor_index_type, hor_index_init +use MOM_io, only : file_exists use MOM_obsolete_params, only : obsolete_logical, obsolete_real use MOM_string_functions, only : uppercase use MOM_time_manager, only : time_type, time_type_to_real, real_to_time @@ -52,12 +55,8 @@ module ice_model_mod use coupler_types_mod, only : coupler_1d_bc_type, coupler_2d_bc_type, coupler_3d_bc_type use coupler_types_mod, only : coupler_type_spawn, coupler_type_initialized use coupler_types_mod, only : coupler_type_rescale_data, coupler_type_copy_data -use fms_mod, only : file_exist, clock_flag_default use fms_io_mod, only : set_domain, nullify_domain, restore_state, query_initialized -use fms_io_mod, only : restore_state, query_initialized use fms_io_mod, only : register_restart_field, restart_file_type -use mpp_mod, only : mpp_clock_id, mpp_clock_begin, mpp_clock_end -use mpp_mod, only : CLOCK_COMPONENT, CLOCK_SUBCOMPONENT use mpp_domains_mod, only : mpp_broadcast_domain use astronomy_mod, only : astronomy_init, astronomy_end @@ -186,7 +185,7 @@ subroutine update_ice_slow_thermo(Ice) sIST => Ice%sCS%IST ; sIG => Ice%sCS%IG ; sG => Ice%sCS%G ; FIA => Ice%sCS%FIA Rad => Ice%sCS%Rad ; US => Ice%sCS%US - call mpp_clock_begin(iceClock) ; call mpp_clock_begin(ice_clock_slow) + call cpu_clock_begin(iceClock) ; call cpu_clock_begin(ice_clock_slow) ! Advance the slow PE clock to give the end time of the slow timestep. There ! is a separate clock inside the fCS that is advanced elsewhere. @@ -231,10 +230,10 @@ subroutine update_ice_slow_thermo(Ice) enddo ; enddo endif - call mpp_clock_end(ice_clock_slow) ; call mpp_clock_end(iceClock) + call cpu_clock_end(ice_clock_slow) ; call cpu_clock_end(iceClock) call update_icebergs(sIST, Ice%sCS%OSS, Ice%sCS%IOF, FIA, Ice%icebergs, US%T_to_s*dt_slow, & sG, US, sIG, Ice%sCS%dyn_trans_CSp) - call mpp_clock_begin(iceClock) ; call mpp_clock_begin(ice_clock_slow) + call cpu_clock_begin(iceClock) ; call cpu_clock_begin(ice_clock_slow) if (Ice%sCS%debug) then call FIA_chksum("After update_icebergs", FIA, sG, US) @@ -256,7 +255,7 @@ subroutine update_ice_slow_thermo(Ice) ! Set up the thermodynamic fluxes in the externally visible structure Ice. call set_ocean_top_fluxes(Ice, sIST, Ice%sCS%IOF, FIA, Ice%sCS%OSS, sG, US, sIG, Ice%sCS) - call mpp_clock_end(ice_clock_slow) ; call mpp_clock_end(iceClock) + call cpu_clock_end(ice_clock_slow) ; call cpu_clock_end(iceClock) end subroutine update_ice_slow_thermo @@ -290,7 +289,7 @@ subroutine update_ice_dynamics_trans(Ice, time_step, start_cycle, end_cycle, cyc if (present(time_step)) dt_slow = US%s_to_T*time_type_to_real(time_step) cycle_start = .true. ; if (present(start_cycle)) cycle_start = start_cycle - call mpp_clock_begin(iceClock) ; call mpp_clock_begin(ice_clock_slow) + call cpu_clock_begin(iceClock) ; call cpu_clock_begin(ice_clock_slow) ! Do halo updates on the forcing fields, as necessary. This must occur before ! the call to SIS_dynamics_trans, because update_icebergs does its own halo @@ -344,7 +343,7 @@ subroutine update_ice_dynamics_trans(Ice, time_step, start_cycle, end_cycle, cyc ! call Ice_public_type_bounds_check(Ice, sG, "End update_ice_slow") ! endif - call mpp_clock_end(ice_clock_slow) ; call mpp_clock_end(iceClock) + call cpu_clock_end(ice_clock_slow) ; call cpu_clock_end(iceClock) end subroutine update_ice_dynamics_trans @@ -742,7 +741,7 @@ subroutine exchange_slow_to_fast_ice(Ice) integer :: isc, iec, jsc, jec, isd, ied, jsd, jed - call mpp_clock_begin(iceClock) ; call mpp_clock_begin(ice_clock_exchange) + call cpu_clock_begin(iceClock) ; call cpu_clock_begin(ice_clock_exchange) if (associated(Ice%fCS)) then isc = Ice%fCS%G%isc ; iec = Ice%fCS%G%iec ; jsc = Ice%fCS%G%jsc ; jec = Ice%fCS%G%jec @@ -798,7 +797,7 @@ subroutine exchange_slow_to_fast_ice(Ice) call SIS_error(FATAL, "exchange_slow_to_fast_ice called with an unrecognized Ice%xtype value.") endif - call mpp_clock_end(ice_clock_exchange) ; call mpp_clock_end(iceClock) + call cpu_clock_end(ice_clock_exchange) ; call cpu_clock_end(iceClock) end subroutine exchange_slow_to_fast_ice @@ -849,7 +848,7 @@ subroutine unpack_ocn_ice_bdry(OIB, OSS, ITV, G, US, specified_ice, ocean_fields isd = G%isd ; ied = G%ied ; jsd = G%jsd ; jed = G%jed i_off = LBOUND(OIB%t,1) - G%isc ; j_off = LBOUND(OIB%t,2) - G%jsc - call mpp_clock_begin(iceClock) ; call mpp_clock_begin(ice_clock_slow) + call cpu_clock_begin(iceClock) ; call cpu_clock_begin(ice_clock_slow) ! Pass the ocean state through ice on partition 0, unless using specified ice. if (.not. specified_ice) then @@ -955,7 +954,7 @@ subroutine unpack_ocn_ice_bdry(OIB, OSS, ITV, G, US, specified_ice, ocean_fields (/jsd, jsc, jec, jed/), as_needed=.true. ) call coupler_type_copy_data(OIB%fields, OSS%tr_fields) - call mpp_clock_end(ice_clock_slow) ; call mpp_clock_end(iceClock) + call cpu_clock_end(ice_clock_slow) ; call cpu_clock_end(iceClock) end subroutine unpack_ocn_ice_bdry @@ -966,14 +965,14 @@ subroutine set_ice_surface_fields(Ice) type(ice_data_type), intent(inout) :: Ice !< The publicly visible ice data type whose !! surface properties are being set. - call mpp_clock_begin(iceClock) ; call mpp_clock_begin(ice_clock_fast) + call cpu_clock_begin(iceClock) ; call cpu_clock_begin(ice_clock_fast) if (.not.associated(Ice%fCS)) call SIS_error(FATAL, & "The pointer to Ice%fCS must be associated in set_ice_surface_fields.") call set_ice_surface_state(Ice, Ice%fCS%IST, Ice%fCS%sOSS, Ice%fCS%Rad, & Ice%fCS%FIA, Ice%fCS%G, Ice%fCS%US, Ice%fCS%IG, Ice%fCS ) - call mpp_clock_end(ice_clock_fast) ; call mpp_clock_end(iceClock) + call cpu_clock_end(ice_clock_fast) ; call cpu_clock_end(iceClock) end subroutine set_ice_surface_fields !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! @@ -1212,7 +1211,7 @@ subroutine update_ice_model_fast( Atmos_boundary, Ice ) type(time_type) :: Time_start, Time_end, dT_fast - call mpp_clock_begin(iceClock) ; call mpp_clock_begin(ice_clock_fast) + call cpu_clock_begin(iceClock) ; call cpu_clock_begin(ice_clock_fast) if (Ice%fCS%debug) & call Ice_public_type_chksum("Pre do_update_ice_model_fast", Ice, check_fast=.true.) @@ -1246,7 +1245,7 @@ subroutine update_ice_model_fast( Atmos_boundary, Ice ) if (Ice%fCS%bounds_check) & call Ice_public_type_bounds_check(Ice, Ice%fCS%G, "End update_ice_fast") - call mpp_clock_end(ice_clock_fast) ; call mpp_clock_end(iceClock) + call cpu_clock_end(ice_clock_fast) ; call cpu_clock_end(iceClock) end subroutine update_ice_model_fast @@ -1689,7 +1688,9 @@ subroutine ice_model_init(Ice, Time_Init, Time, Time_step_fast, Time_step_slow, integer :: CatIce, NkIce, isd, ied, jsd, jed integer :: idr, id_sal integer :: write_geom - logical :: nudge_sea_ice + logical :: nudge_sea_ice ! If true, nudge sea ice concentrations towards observations. + logical :: transmute_ice ! If true, allow ice to be transmuted directly into seawater with a + ! spatially varying rate as a form of outflow open boundary condition. logical :: atmos_winds, slp2ocean logical :: do_icebergs, pass_iceberg_area_to_ocean logical :: pass_stress_mag @@ -1953,6 +1954,12 @@ subroutine ice_model_init(Ice, Time_Init, Time, Time_step_fast, Time_step_slow, call get_param(param_file, mdl, "NUDGE_SEA_ICE", nudge_sea_ice, & "If true, constrain the sea ice concentrations using observations.", & default=.false., do_not_log=.true.) ! Defer logging to SIS_slow_thermo. + call get_param(param_file, mdl, "TRANSMUTE_SEA_ICE", transmute_ice, & + "If true, allow ice to be transmuted directly into seawater with a spatially "//& + "spatially varying rate as a form of outflow open boundary condition.", & + default=.false., do_not_log=.true.) ! Defer logging to SIS_slow_thermo. + + nCat_dflt = 5 ; if (slab_ice) nCat_dflt = 1 opm_dflt = 0.0 ; if (redo_fast_update) opm_dflt = 1.0e-40 #ifdef SYMMETRIC_MEMORY_ @@ -2060,7 +2067,7 @@ subroutine ice_model_init(Ice, Time_Init, Time, Time_step_fast, Time_step_slow, call alloc_simple_OSS(Ice%sCS%sOSS, sHI, gas_fields_ocn) call alloc_ice_ocean_flux(Ice%sCS%IOF, sHI, do_stress_mag=Ice%sCS%pass_stress_mag, & - do_iceberg_fields=Ice%sCS%do_icebergs) + do_iceberg_fields=Ice%sCS%do_icebergs, do_transmute=transmute_ice) Ice%sCS%IOF%slp2ocean = slp2ocean Ice%sCS%IOF%flux_uv_stagger = Ice%flux_uv_stagger call alloc_fast_ice_avg(Ice%sCS%FIA, sHI, sIG, interp_fluxes, gas_fluxes) @@ -2261,7 +2268,7 @@ subroutine ice_model_init(Ice, Time_Init, Time, Time_step_fast, Time_step_slow, restart_path = trim(dirs%restart_input_dir)//trim(restart_file) - if (file_exist(restart_path)) then + if (file_exists(restart_path)) then call callTree_enter("ice_model_init():restore_from_restart_files "//trim(restart_file)) ! Set values of IG%H_to_kg_m2 that will permit its absence from the restart ! file to be detected, and its difference from the value in this run to @@ -2336,7 +2343,7 @@ subroutine ice_model_init(Ice, Time_Init, Time, Time_step_fast, Time_step_slow, recategorize_ice = .true. init_coszen = .true. ; init_Tskin = .true. ; init_rough = .true. - endif ! file_exist(restart_path) + endif ! file_exists(restart_path) ! The restart files have now been read or the variables that would have been in the restart ! files have been initialized, although some corrections and halo updates still need to be done. @@ -2498,7 +2505,7 @@ subroutine ice_model_init(Ice, Time_Init, Time, Time_step_fast, Time_step_slow, if ((.not.slow_ice_PE) .or. split_restart_files) then ! Read the fast restart file, if it exists. fast_rest_path = trim(dirs%restart_input_dir)//trim(fast_rest_file) - if (file_exist(fast_rest_path)) then + if (file_exists(fast_rest_path)) then call restore_state(Ice%Ice_fast_restart, directory=dirs%restart_input_dir) init_coszen = .not.query_initialized(Ice%Ice_fast_restart, 'coszen') init_Tskin = .not.query_initialized(Ice%Ice_fast_restart, 'T_skin') @@ -2587,15 +2594,15 @@ subroutine ice_model_init(Ice, Time_Init, Time, Time_step_fast, Time_step_slow, endif if (Ice%shared_slow_fast_PEs) then - iceClock = mpp_clock_id( 'Ice', flags=clock_flag_default, grain=CLOCK_COMPONENT ) - ice_clock_fast = mpp_clock_id('Ice Fast', flags=clock_flag_default, grain=CLOCK_SUBCOMPONENT ) - ice_clock_slow = mpp_clock_id('Ice Slow', flags=clock_flag_default, grain=CLOCK_SUBCOMPONENT ) + iceClock = cpu_clock_id( 'Ice', grain=CLOCK_COMPONENT ) + ice_clock_fast = cpu_clock_id('Ice Fast', grain=CLOCK_SUBCOMPONENT ) + ice_clock_slow = cpu_clock_id('Ice Slow', grain=CLOCK_SUBCOMPONENT ) else iceClock = 0 ! The comprehensive ice clock can not be used with separate fast and slow ice PEs. if (fast_ice_PE) then - ice_clock_fast = mpp_clock_id('Ice Fast', flags=clock_flag_default, grain=CLOCK_COMPONENT ) + ice_clock_fast = cpu_clock_id('Ice Fast', grain=CLOCK_COMPONENT ) elseif (slow_ice_PE) then - ice_clock_slow = mpp_clock_id('Ice Slow', flags=clock_flag_default, grain=CLOCK_COMPONENT ) + ice_clock_slow = cpu_clock_id('Ice Slow', grain=CLOCK_COMPONENT ) endif endif @@ -2627,9 +2634,9 @@ subroutine share_ice_domains(Ice) call mpp_broadcast_domain(Ice%fast_domain) if (Ice%shared_slow_fast_PEs) then - ice_clock_exchange = mpp_clock_id('Ice Fast/Slow Exchange', flags=clock_flag_default, grain=CLOCK_SUBCOMPONENT ) + ice_clock_exchange = cpu_clock_id('Ice Fast/Slow Exchange', grain=CLOCK_SUBCOMPONENT ) else - ice_clock_exchange = mpp_clock_id('Ice Fast/Slow Exchange', flags=clock_flag_default, grain=CLOCK_COMPONENT ) + ice_clock_exchange = cpu_clock_id('Ice Fast/Slow Exchange', grain=CLOCK_COMPONENT ) endif end subroutine share_ice_domains