diff --git a/columnphysics/icepack_intfc.F90 b/columnphysics/icepack_intfc.F90 index 3a0ab2b5e..c92bdc1f4 100644 --- a/columnphysics/icepack_intfc.F90 +++ b/columnphysics/icepack_intfc.F90 @@ -82,6 +82,7 @@ module icepack_intfc use icepack_wavefracspec, only: icepack_init_wave use icepack_wavefracspec, only: icepack_step_wavefracture + use icepack_snow, only: icepack_init_snow use icepack_snow, only: icepack_step_snow use icepack_shortwave, only: icepack_prep_radiation @@ -116,8 +117,6 @@ module icepack_intfc use icepack_mushy_physics , only: icepack_mushy_liquid_fraction use icepack_mushy_physics , only: icepack_mushy_temperature_mush - use icepack_snow, only: icepack_init_snow - use icepack_warnings, only: icepack_warnings_clear use icepack_warnings, only: icepack_warnings_print use icepack_warnings, only: icepack_warnings_flush diff --git a/columnphysics/icepack_snow.F90 b/columnphysics/icepack_snow.F90 index b0952b01b..6b8404b0c 100644 --- a/columnphysics/icepack_snow.F90 +++ b/columnphysics/icepack_snow.F90 @@ -18,6 +18,9 @@ module icepack_snow use icepack_parameters, only: snowage_tau, snowage_kappa, snowage_drdt0 use icepack_parameters, only: snw_aging_table + use icepack_therm_shared, only: icepack_ice_temperature + use icepack_therm_shared, only: adjust_enthalpy + use icepack_warnings, only: icepack_warnings_add, icepack_warnings_setabort use icepack_warnings, only: icepack_warnings_aborted @@ -206,8 +209,6 @@ subroutine icepack_step_snow(dt, nilyr, & fresh, fhocn, & fsloss, fsnow) - use icepack_therm_shared, only: icepack_ice_temperature - integer (kind=int_kind), intent(in) :: & nslyr, & ! number of snow layers nilyr, & ! number of ice layers @@ -357,8 +358,6 @@ end subroutine icepack_step_snow subroutine snow_redist(dt, nslyr, ncat, wind, ain, vin, vsn, zqsn, & alvl, vlvl, fresh, fhocn, fsloss, rhos_cmpn, fsnow) - use icepack_therm_shared, only: adjust_enthalpy - integer (kind=int_kind), intent(in) :: & nslyr , & ! number of snow layers ncat ! number of thickness categories diff --git a/columnphysics/version.txt b/columnphysics/version.txt index fdcceb192..8b51f89e8 100644 --- a/columnphysics/version.txt +++ b/columnphysics/version.txt @@ -1 +1 @@ -ICEPACK 1.3.1 +ICEPACK 1.3.2 diff --git a/configuration/scripts/tests/report_results.csh b/configuration/scripts/tests/report_results.csh index df53cd5e2..b6d190fef 100755 --- a/configuration/scripts/tests/report_results.csh +++ b/configuration/scripts/tests/report_results.csh @@ -25,7 +25,7 @@ set wikirepo = "https://github.com/CICE-Consortium/Test-Results.wiki.git" set wikiname = Test-Results.wiki rm -r -f ${wikiname} -git clone ${wikirepo} ${wikiname} +git clone --depth=1 ${wikirepo} ${wikiname} if ($status != 0) then echo " " echo "${0}: ERROR git clone failed" diff --git a/doc/source/conf.py b/doc/source/conf.py index 73f030db1..d5bf8ee48 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -62,9 +62,9 @@ # built documents. # # The short X.Y version. -version = u'1.3.1' +version = u'1.3.2' # The full version, including alpha/beta/rc tags. -version = u'1.3.1' +version = u'1.3.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/developer_guide/dg_col_phys.rst b/doc/source/developer_guide/dg_col_phys.rst index 375f55b75..8ebc62c59 100755 --- a/doc/source/developer_guide/dg_col_phys.rst +++ b/doc/source/developer_guide/dg_col_phys.rst @@ -19,6 +19,7 @@ The column physics source code contains the following files | **icepack_firstyear.F90** handles most work associated with the first-year ice area tracer | **icepack_flux.F90** fluxes needed/produced by the model | **icepack_fsd.F90** supports floe size distribution +| **icepack_isotope.F90** handles isotopes | **icepack_intfc.F90** interface routines for linking Icepack with a host sea ice model | **icepack_itd.F90** utilities for managing ice thickness distribution | **icepack_kinds.F90** basic definitions of reals, integers, etc. @@ -31,6 +32,7 @@ The column physics source code contains the following files | **icepack_orbital.F90** orbital parameters for Delta-Eddington shortwave parameterization | **icepack_parameters.F90** basic model parameters including physical and numerical constants requried for column package | **icepack_shortwave.F90** shortwave and albedo parameterizations +| **icepack_snow.F90** snow physics | **icepack_therm_0layer.F90** zero-layer thermodynamics of :cite:`Semtner76` | **icepack_therm_bl99.F90** multilayer thermodynamics of :cite:`Bitz99` | **icepack_therm_itd.F90** thermodynamic changes mostly related to ice thickness distribution @@ -127,60 +129,89 @@ Overall, columnphysics changes in the Icepack model should include the following * Variables defined in icepack_kinds, icepack_tracers, icepack_parameters, and icepack_orbital should be accessed within Icepack by Fortran use statements. It's also possible to access some of those variables thru methods that query for the value, but this tends to be a little more cumbersome, so Fortran use statements are recommended within columnphysics. From the icepack driver or other external programs, the columnphysics variables should ALWAYS be access thru the interface methods and icepack_intfc (see also :ref:`calling`). - * Optional arguments are encouraged in the public Icepack interfaces but should generally be avoided in interfaces within the columnphysics. There are several reasons for taking this approach. There is a desire to support backwards compatible Icepack public interfaces as much as possible, so optional arguments will be used for some future extensions. There is also a desire to allow users to pass only the data thru the Icepack interfaces that is needed. To support optional tracers and features, optional arguments are needed. Within the internal columnphysics calling tree, optional arguments are discouraged because they tend to add complexity to deep calling trees and often lead to implementations with many calls to the same interface that only vary by which arguments are passed. In the long term, that approach is not sustainable. As a result, a scheme has been developed to support optional arguments in the public interfaces while minimizing optional arguments within the columphysics. Within the columnphysics, we suggest optional arguments available thru the public interfaces should generally be treated as follows + * Optional arguments are encouraged in the public Icepack interfaces. They allow for easier backwards compatible Icepack public interfaces and support future extensions. There is also a desire to allow users to pass only the data thru the Icepack interfaces that is needed. There are several ways optional arguments can be passed down the calling tree in Icepack. Two options, copying into local data or copying into module data are viable. But the recommended approach is to - * Check whether optional arguments are passed and create temporary data to store the values + * Use universal flags and parameters to turn on/off features. - * The temporary data should be locally name l_${argument_name} + * Have all optional features trigger from the flags and parameters. - * The temporary data should be allocated at runtime if it's not a scalar based on the size of the incoming argument + * Verify that the optional arguments required for any feature are passed in at the top level of each Icepack interface. If not, then abort. - * The optional argument values should be copied into the temporary data + * Pass all optional arguments down the calling tree as optional arguments. - * The temporary data should be passed thru other columnphysics subroutines + * An example of how this might look is - * The temporary data should be deallocated at the end of the method if it was allocated + .. code-block:: fortran - * The temporary data should be copied back to the argument if the argument intent is out or inout + use icepack_parameters, only: flag_arg2, flag_arg3 - * If optional arguments are not passed, temporary data should be created of size 1 with values of c0, and they should be passed thru other columnphysics subroutines + subroutine icepack_public_interface(arg1, arg2, arg3, ...) + real (kind=dbl_kind), intent(inout) :: arg1 + real (kind=dbl_kind), optional, dimension(:), intent(inout) :: arg2 + real (kind=dbl_kind), optional, intent(inout) :: arg3 - * A logical can be instantiated and passed down the columnphysics interface to manage any logic related to whether valid or fake data is being passed down the calling tree. See **closing_flag** and **iso_flag** within the columnphysics as examples. There may also be externally set logicals that can be used to control how the optional features are handles. See **tr_iso** within the columnphysics as an example. + character(len=*), parameter :: subname = '(icepack_public_interface)' - * An example of how this might look is + if (flag_arg2) then + if (.not.present(arg2)) then + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + call icepack_warnings_add(subname//' flag_arg2 set but arg2 not passed') + endif + endif + if (flag_arg3) then + if (.not.present(arg3)) then + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + call icepack_warnings_add(subname//' flag_arg3 set but arg3 not passed') + endif + endif + if (icepack_warnings_aborted(subname)) return - .. code-block:: fortran + ... + call some_columnphysics_subroutine(arg1, arg2, arg3, ...) + ... + + end subroutine + + !------------ + + subroutine some_columnphysics_subroutine(arg1, arg2, arg3, ...) - subroutine icepack_example_interface(arg1, arg2, ...) real (kind=dbl_kind), intent(inout) :: arg1 real (kind=dbl_kind), optional, dimension(:), intent(inout) :: arg2 - ! - real (kind=dbl_kind), allocatable, dimension(:) :: l_arg2 - logical :: arg2_flag - - character(len=*), parameter :: subname = '(icepack_example_interface)' - - if (present(arg2)) then - arg2_flag = .true. - allocate(l_arg2(size(arg2))) - l_arg2 = arg2 - else - arg2_flag = .false. - allocate(l_arg2(1)) - l_arg2 = c0 + real (kind=dbl_kind), optional, intent(inout) :: arg3 + + if (flag_arg2) then + arg2(:) = ... endif - ... + if (flag_arg3) then + call someother_columnphysics_subroutine(arg3) + endif - call some_columnphysics_subroutine(arg1, l_arg2, arg2_flag, ...) + end subroutine - ... + !------------ - if (present(arg2)) then - arg2 = l_arg2 - endif - deallocate(l_arg2) + subroutine someother_columnphysics_subroutine(arg3) + + real (kind=dbl_kind), optional, intent(inout) :: arg3 + + arg3 = ... - return end subroutine + + Some notes + + * If optional arguments are passed but not needed, this is NOT an error. + + * If checking and implementation are done properly, optional arguments that are not needed will never be referenced anywhere in Icepack at that timestep + + * There is a unit test in CICE to verify robustness of this approach. + + * We recommend doing all checks for optional arguments for an interface before returning just for completeness (as shown above) + + * An argcheck parameter will control when to do the checks, 'none', 'first', or 'all' may be possible settings + + * Icepack is a simple serial code. Global flags and parameters should be set identically on all tasks/threads that call into Icepack. Icepack has no ability to reconcile or identify inconsistencies between different tasks/threads. + diff --git a/doc/source/user_guide/interfaces.include b/doc/source/user_guide/interfaces.include index bb1250da4..b9204a9bc 100644 --- a/doc/source/user_guide/interfaces.include +++ b/doc/source/user_guide/interfaces.include @@ -296,6 +296,9 @@ icepack_intfc.F90 use icepack_wavefracspec, only: icepack_init_wave use icepack_wavefracspec, only: icepack_step_wavefracture + use icepack_snow, only: icepack_init_snow + use icepack_snow, only: icepack_step_snow + use icepack_shortwave, only: icepack_prep_radiation use icepack_shortwave, only: icepack_step_radiation @@ -592,7 +595,9 @@ icepack_step_ridge !tr_pond_topo,& ! if .true., use explicit topography-based ponds !tr_aero ,& ! if .true., use aerosol tracers !tr_brine !,& ! if .true., brine height differs from ice thickness + #ifdef UNDEPRECATE_0LAYER !heat_capacity ! if true, ice has nonzero heat capacity + #endif logical (kind=log_kind), dimension(:), intent(inout) :: & first_ice ! true until ice forms @@ -736,7 +741,11 @@ icepack_init_parameters stefan_boltzmann_in, ice_ref_salinity_in, & Tffresh_in, Lsub_in, Lvap_in, Timelt_in, Tsmelt_in, & iceruf_in, Cf_in, Pstar_in, Cstar_in, kappav_in, & + #ifdef UNDEPRECATE_0LAYER kice_in, kseaice_in, ksno_in, & + #else + kice_in, ksno_in, & + #endif zref_in, hs_min_in, snowpatch_in, rhosi_in, sk_l_in, & saltmax_in, phi_init_in, min_salin_in, salt_loss_in, & min_bgc_in, dSin0_frazil_in, hi_ssl_in, hs_ssl_in, & @@ -758,13 +767,23 @@ icepack_init_parameters bgc_flux_type_in, z_tracers_in, scale_bgc_in, solve_zbgc_in, & modal_aero_in, skl_bgc_in, solve_zsal_in, grid_o_in, l_sk_in, & initbio_frac_in, grid_oS_in, l_skS_in, dEdd_algae_in, & + #ifdef UNDEPRECATE_0LAYER phi_snow_in, heat_capacity_in, T_max_in, fsal_in, & + #else + phi_snow_in, T_max_in, fsal_in, & + #endif fr_resp_in, algal_vel_in, R_dFe2dust_in, dustFe_sol_in, & op_dep_min_in, fr_graze_s_in, fr_graze_e_in, fr_mort2min_in, & fr_dFe_in, k_nitrif_in, t_iron_conv_in, max_loss_in, & max_dfe_doc1_in, fr_resp_s_in, conserv_check_in, & y_sk_DMS_in, t_sk_conv_in, t_sk_ox_in, frazil_scav_in, & - sw_redist_in, sw_frac_in, sw_dtemp_in) + sw_redist_in, sw_frac_in, sw_dtemp_in, snwgrain_in, & + snwredist_in, use_smliq_pnd_in, rsnw_fall_in, rsnw_tmax_in, & + rhosnew_in, rhosmin_in, rhosmax_in, windmin_in, drhosdwind_in, & + snwlvlfac_in, isnw_T_in, isnw_Tgrd_in, isnw_rhos_in, & + snowage_rhos_in, snowage_Tgrd_in, snowage_T_in, & + snowage_tau_in, snowage_kappa_in, snowage_drdt0_in, & + snw_aging_table_in) !----------------------------------------------------------------- ! parameter constants @@ -806,7 +825,9 @@ icepack_init_parameters Tsmelt_in, & ! melting temperature, snow top surface (C) ice_ref_salinity_in, & ! (ppt) kice_in, & ! thermal conductivity of fresh ice(W/m/deg) + #ifdef UNDEPRECATE_0LAYER kseaice_in, & ! thermal conductivity of sea ice (W/m/deg) + #endif ksno_in, & ! thermal conductivity of snow (W/m/deg) hs_min_in, & ! min snow thickness for computing zTsn (m) snowpatch_in, & ! parameter for fractional snow area (m) @@ -818,17 +839,23 @@ icepack_init_parameters integer (kind=int_kind), intent(in), optional :: & ktherm_in ! type of thermodynamics + #ifdef UNDEPRECATE_0LAYER ! 0 = 0-layer approximation + #else + ! -1 none + #endif ! 1 = Bitz and Lipscomb 1999 ! 2 = mushy layer theory - character (char_len), intent(in), optional :: & + character (len=*), intent(in), optional :: & conduct_in, & ! 'MU71' or 'bubbly' fbot_xfer_type_in ! transfer coefficient type for ice-ocean heat flux logical (kind=log_kind), intent(in), optional :: & + #ifdef UNDEPRECATE_0LAYER heat_capacity_in, &! if true, ice has nonzero heat capacity ! if false, use zero-layer thermodynamics + #endif calc_Tsfc_in , &! if true, calculate surface temperature ! if false, Tsfc is computed elsewhere and ! atmos-ice fluxes are provided to CICE @@ -847,7 +874,7 @@ icepack_init_parameters phi_c_slow_mode_in , & ! liquid fraction porosity cutoff for slow mode phi_i_mushy_in ! liquid fraction of congelation ice - character(len=char_len), intent(in), optional :: & + character(len=*), intent(in), optional :: & tfrz_option_in ! form of ocean freezing temperature ! 'minus1p8' = -1.8 C ! 'linear_salt' = -depressT * sss @@ -870,7 +897,7 @@ icepack_init_parameters awtvdf_in, & ! visible, diffuse awtidf_in ! near IR, diffuse - character (len=char_len), intent(in), optional :: & + character (len=*), intent(in), optional :: & shortwave_in, & ! shortwave method, 'ccsm3' or 'dEdd' albedo_type_in ! albedo parameterization, 'ccsm3' or 'constant' ! shortwave='dEdd' overrides this parameter @@ -943,13 +970,13 @@ icepack_init_parameters qqqocn_in, & ! for qsat over ocn TTTocn_in ! for qsat over ocn - character (len=char_len), intent(in), optional :: & - atmbndy_in ! atmo boundary method, 'similarity', 'constant' or 'mixed' + character (len=*), intent(in), optional :: & + atmbndy_in ! atmo boundary method, 'similarity', 'constant' or 'mixed' logical (kind=log_kind), intent(in), optional :: & - calc_strair_in, & ! if true, calculate wind stress components - formdrag_in, & ! if true, calculate form drag - highfreq_in ! if true, use high frequency coupling + calc_strair_in, & ! if true, calculate wind stress components + formdrag_in, & ! if true, calculate form drag + highfreq_in ! if true, use high frequency coupling integer (kind=int_kind), intent(in), optional :: & natmiter_in ! number of iterations for boundary layer calculations @@ -983,14 +1010,14 @@ icepack_init_parameters logical (kind=log_kind), intent(in), optional :: & wave_spec_in ! if true, use wave forcing - character (len=char_len), intent(in), optional :: & + character (len=*), intent(in), optional :: & wave_spec_type_in ! type of wave spectrum forcing !----------------------------------------------------------------------- ! Parameters for biogeochemistry !----------------------------------------------------------------------- - character(char_len), intent(in), optional :: & + character (len=*), intent(in), optional :: & bgc_flux_type_in ! type of ocean-ice piston velocity ! 'constant', 'Jin2006' @@ -1051,7 +1078,7 @@ icepack_init_parameters hs0_in ! snow depth for transition to bare sea ice (m) ! level-ice ponds - character (len=char_len), intent(in), optional :: & + character (len=*), intent(in), optional :: & frzpnd_in ! pond refreezing parameterization real (kind=dbl_kind), intent(in), optional :: & @@ -1065,6 +1092,43 @@ icepack_init_parameters real (kind=dbl_kind), intent(in), optional :: & hp1_in ! critical parameter for pond ice thickness + !----------------------------------------------------------------------- + ! Parameters for snow redistribution, metamorphosis + !----------------------------------------------------------------------- + + character (len=*), intent(in), optional :: & + snwredist_in, & ! type of snow redistribution + snw_aging_table_in ! snow aging lookup table + + logical (kind=log_kind), intent(in), optional :: & + use_smliq_pnd_in, &! use liquid in snow for ponds + snwgrain_in ! snow metamorphosis + + real (kind=dbl_kind), intent(in), optional :: & + rsnw_fall_in, & ! radius of new snow (10^-6 m) + rsnw_tmax_in, & ! maximum snow radius (10^-6 m) + rhosnew_in, & ! new snow density (kg/m^3) + rhosmin_in, & ! minimum snow density (kg/m^3) + rhosmax_in, & ! maximum snow density (kg/m^3) + windmin_in, & ! minimum wind speed to compact snow (m/s) + drhosdwind_in, & ! wind compaction factor (kg s/m^4) + snwlvlfac_in ! fractional increase in snow depth + + integer (kind=int_kind), intent(in), optional :: & + isnw_T_in, & ! maxiumum temperature index + isnw_Tgrd_in, & ! maxiumum temperature gradient index + isnw_rhos_in ! maxiumum snow density index + + real (kind=dbl_kind), dimension(:), intent(in), optional :: & + snowage_rhos_in, & ! snowage dimension data + snowage_Tgrd_in, & ! + snowage_T_in ! + + real (kind=dbl_kind), dimension(:,:,:), intent(in), optional :: & + snowage_tau_in, & ! (10^-6 m) + snowage_kappa_in, &! + snowage_drdt0_in ! (10^-6 m/hr) + .. _icepack_query_parameters: @@ -1089,7 +1153,11 @@ icepack_query_parameters stefan_boltzmann_out, ice_ref_salinity_out, & Tffresh_out, Lsub_out, Lvap_out, Timelt_out, Tsmelt_out, & iceruf_out, Cf_out, Pstar_out, Cstar_out, kappav_out, & + #ifdef UNDEPRECATE_0LAYER kice_out, kseaice_out, ksno_out, & + #else + kice_out, ksno_out, & + #endif zref_out, hs_min_out, snowpatch_out, rhosi_out, sk_l_out, & saltmax_out, phi_init_out, min_salin_out, salt_loss_out, & min_bgc_out, dSin0_frazil_out, hi_ssl_out, hs_ssl_out, & @@ -1111,13 +1179,23 @@ icepack_query_parameters bgc_flux_type_out, z_tracers_out, scale_bgc_out, solve_zbgc_out, & modal_aero_out, skl_bgc_out, solve_zsal_out, grid_o_out, l_sk_out, & initbio_frac_out, grid_oS_out, l_skS_out, & + #ifdef UNDEPRECATE_0LAYER phi_snow_out, heat_capacity_out, conserv_check_out, & + #else + phi_snow_out, conserv_check_out, & + #endif fr_resp_out, algal_vel_out, R_dFe2dust_out, dustFe_sol_out, & T_max_out, fsal_out, op_dep_min_out, fr_graze_s_out, fr_graze_e_out, & fr_mort2min_out, fr_resp_s_out, fr_dFe_out, & k_nitrif_out, t_iron_conv_out, max_loss_out, max_dfe_doc1_out, & y_sk_DMS_out, t_sk_conv_out, t_sk_ox_out, frazil_scav_out, & - sw_redist_out, sw_frac_out, sw_dtemp_out) + sw_redist_out, sw_frac_out, sw_dtemp_out, snwgrain_out, & + snwredist_out, use_smliq_pnd_out, rsnw_fall_out, rsnw_tmax_out, & + rhosnew_out, rhosmin_out, rhosmax_out, windmin_out, drhosdwind_out, & + snwlvlfac_out, isnw_T_out, isnw_Tgrd_out, isnw_rhos_out, & + snowage_rhos_out, snowage_Tgrd_out, snowage_T_out, & + snowage_tau_out, snowage_kappa_out, snowage_drdt0_out, & + snw_aging_table_out) !----------------------------------------------------------------- ! parameter constants @@ -1168,7 +1246,9 @@ icepack_query_parameters Tsmelt_out, & ! melting temperature, snow top surface (C) ice_ref_salinity_out, & ! (ppt) kice_out, & ! thermal conductivity of fresh ice(W/m/deg) + #ifdef UNDEPRECATE_0LAYER kseaice_out, & ! thermal conductivity of sea ice (W/m/deg) + #endif ksno_out, & ! thermal conductivity of snow (W/m/deg) hs_min_out, & ! min snow thickness for computing zTsn (m) snowpatch_out, & ! parameter for fractional snow area (m) @@ -1180,17 +1260,23 @@ icepack_query_parameters integer (kind=int_kind), intent(out), optional :: & ktherm_out ! type of thermodynamics + #ifdef UNDEPRECATE_0LAYER ! 0 = 0-layer approximation + #else + ! -1 none + #endif ! 1 = Bitz and Lipscomb 1999 ! 2 = mushy layer theory - character (char_len), intent(out), optional :: & + character (len=*), intent(out), optional :: & conduct_out, & ! 'MU71' or 'bubbly' fbot_xfer_type_out ! transfer coefficient type for ice-ocean heat flux logical (kind=log_kind), intent(out), optional :: & + #ifdef UNDEPRECATE_0LAYER heat_capacity_out,&! if true, ice has nonzero heat capacity ! if false, use zero-layer thermodynamics + #endif calc_Tsfc_out ,&! if true, calculate surface temperature ! if false, Tsfc is computed elsewhere and ! atmos-ice fluxes are provided to CICE @@ -1209,7 +1295,7 @@ icepack_query_parameters phi_c_slow_mode_out , & ! liquid fraction porosity cutoff for slow mode phi_i_mushy_out ! liquid fraction of congelation ice - character(len=char_len), intent(out), optional :: & + character(len=*), intent(out), optional :: & tfrz_option_out ! form of ocean freezing temperature ! 'minus1p8' = -1.8 C ! 'linear_salt' = -depressT * sss @@ -1232,7 +1318,7 @@ icepack_query_parameters awtvdf_out, & ! visible, diffuse awtidf_out ! near IR, diffuse - character (len=char_len), intent(out), optional :: & + character (len=*), intent(out), optional :: & shortwave_out, & ! shortwave method, 'ccsm3' or 'dEdd' albedo_type_out ! albedo parameterization, 'ccsm3' or 'constant' ! shortwave='dEdd' overrides this parameter @@ -1305,13 +1391,13 @@ icepack_query_parameters qqqocn_out, & ! for qsat over ocn TTTocn_out ! for qsat over ocn - character (len=char_len), intent(out), optional :: & - atmbndy_out ! atmo boundary method, 'similarity', 'constant' or 'mixed' + character (len=*), intent(out), optional :: & + atmbndy_out ! atmo boundary method, 'similarity', 'constant' or 'mixed' logical (kind=log_kind), intent(out), optional :: & - calc_strair_out, & ! if true, calculate wind stress components - formdrag_out, & ! if true, calculate form drag - highfreq_out ! if true, use high frequency coupling + calc_strair_out, & ! if true, calculate wind stress components + formdrag_out, & ! if true, calculate form drag + highfreq_out ! if true, use high frequency coupling integer (kind=int_kind), intent(out), optional :: & natmiter_out ! number of iterations for boundary layer calculations @@ -1345,15 +1431,15 @@ icepack_query_parameters logical (kind=log_kind), intent(out), optional :: & wave_spec_out ! if true, use wave forcing - character (len=char_len), intent(out), optional :: & + character (len=*), intent(out), optional :: & wave_spec_type_out ! type of wave spectrum forcing !----------------------------------------------------------------------- ! Parameters for biogeochemistry !----------------------------------------------------------------------- - character(char_len), intent(out), optional :: & - bgc_flux_type_out ! type of ocean-ice piston velocity + character (len=*), intent(out), optional :: & + bgc_flux_type_out ! type of ocean-ice piston velocity ! 'constant', 'Jin2006' logical (kind=log_kind), intent(out), optional :: & @@ -1413,7 +1499,7 @@ icepack_query_parameters hs0_out ! snow depth for transition to bare sea ice (m) ! level-ice ponds - character (len=char_len), intent(out), optional :: & + character (len=*), intent(out), optional :: & frzpnd_out ! pond refreezing parameterization real (kind=dbl_kind), intent(out), optional :: & @@ -1427,6 +1513,42 @@ icepack_query_parameters real (kind=dbl_kind), intent(out), optional :: & hp1_out ! critical parameter for pond ice thickness + !----------------------------------------------------------------------- + ! Parameters for snow redistribution, metamorphosis + !----------------------------------------------------------------------- + + character (len=*), intent(out), optional :: & + snwredist_out, & ! type of snow redistribution + snw_aging_table_out ! snow aging lookup table + + logical (kind=log_kind), intent(out), optional :: & + use_smliq_pnd_out, &! use liquid in snow for ponds + snwgrain_out ! snow metamorphosis + + real (kind=dbl_kind), intent(out), optional :: & + rsnw_fall_out, & ! radius of new snow (10^-6 m) + rsnw_tmax_out, & ! maximum snow radius (10^-6 m) + rhosnew_out, & ! new snow density (kg/m^3) + rhosmin_out, & ! minimum snow density (kg/m^3) + rhosmax_out, & ! maximum snow density (kg/m^3) + windmin_out, & ! minimum wind speed to compact snow (m/s) + drhosdwind_out, & ! wind compaction factor (kg s/m^4) + snwlvlfac_out ! fractional increase in snow depth + + integer (kind=int_kind), intent(out), optional :: & + isnw_T_out, & ! maxiumum temperature index + isnw_Tgrd_out, & ! maxiumum temperature gradient index + isnw_rhos_out ! maxiumum snow density index + + real (kind=dbl_kind), dimension(:), intent(out), optional :: & + snowage_rhos_out, & ! snowage dimension data + snowage_Tgrd_out, & ! + snowage_T_out ! + + real (kind=dbl_kind), dimension(:,:,:), intent(out), optional :: & + snowage_tau_out, & ! (10^-6 m) + snowage_kappa_out, &! + snowage_drdt0_out ! (10^-6 m/hr) .. _icepack_write_parameters: @@ -1580,7 +1702,8 @@ icepack_step_radiation albpndn, apeffn, & snowfracn, & dhsn, ffracn, & - l_print_point, & + rsnow, & + l_print_point, & initonly) integer (kind=int_kind), intent(in) :: & @@ -1683,11 +1806,93 @@ icepack_step_radiation dEdd_algae , & ! .true. use prognostic chla in dEdd modal_aero ! .true. use modal aerosol optical treatment + real (kind=dbl_kind), dimension(:,:), intent(inout), optional :: & + rsnow ! snow grain radius tracer (10^-6 m) + logical (kind=log_kind), optional :: & initonly ! flag to indicate init only, default is false +icepack_snow.F90 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _icepack_init_snow: + +icepack_init_snow +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. code-block:: fortran + + ! Updates snow tracers + ! + ! authors: Elizabeth C. Hunke, LANL + ! Nicole Jeffery, LANL + + subroutine icepack_init_snow + + + +.. _icepack_step_snow: + +icepack_step_snow +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. code-block:: fortran + + ! Updates snow tracers + ! + ! authors: Elizabeth C. Hunke, LANL + ! Nicole Jeffery, LANL + + subroutine icepack_step_snow(dt, nilyr, & + nslyr, ncat, & + wind, aice, & + aicen, vicen, & + vsnon, Tsfc, & + zqin1, zSin1, & + zqsn, & + alvl, vlvl, & + smice, smliq, & + rsnw, rhos_cmpn, & + fresh, fhocn, & + fsloss, fsnow) + + integer (kind=int_kind), intent(in) :: & + nslyr, & ! number of snow layers + nilyr, & ! number of ice layers + ncat ! number of thickness categories + + real (kind=dbl_kind), intent(in) :: & + dt , & ! time step + wind , & ! wind speed (m/s) + fsnow , & ! snowfall rate (kg m-2 s-1) + aice ! ice area fraction + + real (kind=dbl_kind), dimension(:), intent(in) :: & + aicen, & ! ice area fraction + vicen, & ! ice volume (m) + Tsfc , & ! surface temperature (C) + zqin1, & ! ice upper layer enthalpy + zSin1, & ! ice upper layer salinity + alvl, & ! level ice area tracer + vlvl ! level ice volume tracer + + real (kind=dbl_kind), intent(inout) :: & + fresh , & ! fresh water flux to ocean (kg/m^2/s) + fhocn , & ! net heat flux to ocean (W/m^2) + fsloss ! rate of snow loss to leads (kg/m^2/s) + + real (kind=dbl_kind), dimension(:), intent(inout) :: & + vsnon ! snow volume (m) + + real (kind=dbl_kind), dimension(:,:), intent(inout) :: & + zqsn , & ! snow enthalpy (J/m^3) + smice , & ! tracer for mass of ice in snow (kg/m^3) + smliq , & ! tracer for mass of liquid in snow (kg/m^3) + rsnw , & ! snow grain radius (10^-6 m) + rhos_cmpn ! effective snow density: compaction (kg/m^3) + + + icepack_therm_itd.F90 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2037,7 +2242,7 @@ icepack_step_therm1 frzmlt , rside , & fside , & fsnow , frain , & - fpond , & + fpond , fsloss , & fsurf , fsurfn , & fcondtop , fcondtopn , & fcondbot , fcondbotn , & @@ -2075,7 +2280,10 @@ icepack_step_therm1 melts , meltsn , & congel , congeln , & snoice , snoicen , & - dsnown , & + dsnow , dsnown , & + meltsliq , meltsliqn , & + rsnwn , & + smicen , smliqn , & lmask_n , lmask_s , & mlt_onset , frz_onset , & yday , prescribed_ice, & @@ -2174,17 +2382,26 @@ icepack_step_therm1 frz_onset ! day of year that freezing begins (congel or frazil) real (kind=dbl_kind), intent(inout), optional :: & - fswthru_vdr , & ! vis dir shortwave penetrating to ocean (W/m^2) - fswthru_vdf , & ! vis dif shortwave penetrating to ocean (W/m^2) - fswthru_idr , & ! nir dir shortwave penetrating to ocean (W/m^2) - fswthru_idf ! nir dif shortwave penetrating to ocean (W/m^2) + fswthru_vdr , & ! vis dir shortwave penetrating to ocean (W/m^2) + fswthru_vdf , & ! vis dif shortwave penetrating to ocean (W/m^2) + fswthru_idr , & ! nir dir shortwave penetrating to ocean (W/m^2) + fswthru_idf , & ! nir dif shortwave penetrating to ocean (W/m^2) + dsnow , & ! change in snow depth (m/step-->cm/day) + meltsliq , & ! mass of snow melt (kg/m^2) + fsloss ! rate of snow loss to leads (kg/m^2/s) real (kind=dbl_kind), dimension(:), optional, intent(inout) :: & Qa_iso , & ! isotope specific humidity (kg/kg) Qref_iso , & ! isotope 2m atm reference spec humidity (kg/kg) fiso_atm , & ! isotope deposition rate (kg/m^2 s) fiso_ocn , & ! isotope flux to ocean (kg/m^2/s) - fiso_evap ! isotope evaporation (kg/m^2/s) + fiso_evap , & ! isotope evaporation (kg/m^2/s) + meltsliqn ! mass of snow melt (kg/m^2) + + real (kind=dbl_kind), dimension(:,:), optional, intent(inout) :: & + rsnwn , & ! snow grain radius (10^-6 m) + smicen , & ! tracer for mass of ice in snow (kg/m^3) + smliqn ! tracer for mass of liquid in snow (kg/m^3) real (kind=dbl_kind), optional, intent(in) :: & HDO_ocn , & ! ocean concentration of HDO (kg/kg) @@ -2264,8 +2481,12 @@ icepack_init_tracer_flags ! set tracer active flags subroutine icepack_init_tracer_flags(& - tr_iage_in, tr_FY_in, tr_lvl_in, & + tr_iage_in, tr_FY_in, tr_lvl_in, tr_snow_in, & + #ifdef UNDEPRECATE_CESMPONDS + tr_pond_in, tr_pond_cesm_in, tr_pond_lvl_in, tr_pond_topo_in, & + #else tr_pond_in, tr_pond_lvl_in, tr_pond_topo_in, & + #endif tr_fsd_in, tr_aero_in, tr_iso_in, tr_brine_in, tr_zaero_in, & tr_bgc_Nit_in, tr_bgc_N_in, tr_bgc_DON_in, tr_bgc_C_in, tr_bgc_chl_in, & tr_bgc_Am_in, tr_bgc_Sil_in, tr_bgc_DMS_in, tr_bgc_Fe_in, tr_bgc_hum_in, & @@ -2276,8 +2497,12 @@ icepack_init_tracer_flags tr_FY_in , & ! if .true., use first-year area tracer tr_lvl_in , & ! if .true., use level ice tracer tr_pond_in , & ! if .true., use melt pond tracer + #ifdef UNDEPRECATE_CESMPONDS + tr_pond_cesm_in , & ! if .true., use cesm pond tracer + #endif tr_pond_lvl_in , & ! if .true., use level-ice pond tracer tr_pond_topo_in , & ! if .true., use explicit topography-based ponds + tr_snow_in , & ! if .true., use snow metamorphosis tracers tr_fsd_in , & ! if .true., use floe size distribution tracers tr_iso_in , & ! if .true., use isotope tracers tr_aero_in , & ! if .true., use aerosol tracers @@ -2306,8 +2531,12 @@ icepack_query_tracer_flags ! query tracer active flags subroutine icepack_query_tracer_flags(& - tr_iage_out, tr_FY_out, tr_lvl_out, & + tr_iage_out, tr_FY_out, tr_lvl_out, tr_snow_out, & + #ifdef UNDEPRECATE_CESMPONDS + tr_pond_out, tr_pond_cesm_out, tr_pond_lvl_out, tr_pond_topo_out, & + #else tr_pond_out, tr_pond_lvl_out, tr_pond_topo_out, & + #endif tr_fsd_out, tr_aero_out, tr_iso_out, tr_brine_out, tr_zaero_out, & tr_bgc_Nit_out, tr_bgc_N_out, tr_bgc_DON_out, tr_bgc_C_out, tr_bgc_chl_out, & tr_bgc_Am_out, tr_bgc_Sil_out, tr_bgc_DMS_out, tr_bgc_Fe_out, tr_bgc_hum_out, & @@ -2318,8 +2547,12 @@ icepack_query_tracer_flags tr_FY_out , & ! if .true., use first-year area tracer tr_lvl_out , & ! if .true., use level ice tracer tr_pond_out , & ! if .true., use melt pond tracer + #ifdef UNDEPRECATE_CESMPONDS + tr_pond_cesm_out , & ! if .true., use cesm pond tracer + #endif tr_pond_lvl_out , & ! if .true., use level-ice pond tracer tr_pond_topo_out , & ! if .true., use explicit topography-based ponds + tr_snow_out , & ! if .true., use snow metamorphosis tracers tr_fsd_out , & ! if .true., use floe size distribution tr_iso_out , & ! if .true., use isotope tracers tr_aero_out , & ! if .true., use aerosol tracers @@ -2365,6 +2598,7 @@ icepack_init_tracer_indices nt_Tsfc_in, nt_qice_in, nt_qsno_in, nt_sice_in, & nt_fbri_in, nt_iage_in, nt_FY_in, & nt_alvl_in, nt_vlvl_in, nt_apnd_in, nt_hpnd_in, nt_ipnd_in, & + nt_smice_in, nt_smliq_in, nt_rhos_in, nt_rsnw_in, & nt_fsd_in, nt_isosno_in, nt_isoice_in, & nt_aero_in, nt_zaero_in, nt_bgc_C_in, & nt_bgc_N_in, nt_bgc_chl_in, nt_bgc_DOC_in, nt_bgc_DON_in, & @@ -2385,12 +2619,16 @@ icepack_init_tracer_indices nt_sice_in, & ! volume-weighted ice bulk salinity (CICE grid layers) nt_fbri_in, & ! volume fraction of ice with dynamic salt (hinS/vicen*aicen) nt_iage_in, & ! volume-weighted ice age - nt_FY_in, & ! area-weighted first-year ice area + nt_FY_in, & ! area-weighted first-year ice area nt_alvl_in, & ! level ice area fraction nt_vlvl_in, & ! level ice volume fraction nt_apnd_in, & ! melt pond area fraction nt_hpnd_in, & ! melt pond depth nt_ipnd_in, & ! melt pond refrozen lid thickness + nt_smice_in,& ! mass of ice in snow + nt_smliq_in,& ! mass of liquid water in snow + nt_rhos_in, & ! snow density + nt_rsnw_in, & ! snow grain radius nt_fsd_in, & ! floe size distribution nt_isosno_in, & ! starting index for isotopes in snow nt_isoice_in, & ! starting index for isotopes in ice @@ -2464,6 +2702,7 @@ icepack_query_tracer_indices nt_Tsfc_out, nt_qice_out, nt_qsno_out, nt_sice_out, & nt_fbri_out, nt_iage_out, nt_FY_out, & nt_alvl_out, nt_vlvl_out, nt_apnd_out, nt_hpnd_out, nt_ipnd_out, & + nt_smice_out, nt_smliq_out, nt_rhos_out, nt_rsnw_out, & nt_fsd_out, nt_isosno_out, nt_isoice_out, & nt_aero_out, nt_zaero_out, nt_bgc_C_out, & nt_bgc_N_out, nt_bgc_chl_out, nt_bgc_DOC_out, nt_bgc_DON_out, & @@ -2490,6 +2729,10 @@ icepack_query_tracer_indices nt_apnd_out, & ! melt pond area fraction nt_hpnd_out, & ! melt pond depth nt_ipnd_out, & ! melt pond refrozen lid thickness + nt_smice_out,& ! mass of ice in snow + nt_smliq_out,& ! mass of liquid water in snow + nt_rhos_out, & ! snow density + nt_rsnw_out, & ! snow grain radius nt_fsd_out, & ! floe size distribution nt_isosno_out, & ! starting index for isotopes in snow nt_isoice_out, & ! starting index for isotopes in ice @@ -2675,10 +2918,10 @@ icepack_compute_tracers ! Given atrcrn = aicen*trcrn (or vicen*trcrn, vsnon*trcrn), compute trcrn. subroutine icepack_compute_tracers (ntrcr, trcr_depend, & - atrcrn, aicen, & - vicen, vsnon, & - trcr_base, n_trcr_strata, & - nt_strata, trcrn) + atrcrn, aicen, & + vicen, vsnon, & + trcr_base, n_trcr_strata, & + nt_strata, trcrn) integer (kind=int_kind), intent(in) :: & ntrcr ! number of tracers in use