From 0aa2305c35a8bd2d34a198f6341b4b312a4bade5 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Thu, 5 Oct 2023 17:42:44 -0700 Subject: [PATCH 01/30] Add new picard nonconvergence messages (#464) Co-authored-by: David Bailey Co-authored-by: Elizabeth Hunke --- columnphysics/icepack_therm_mushy.F90 | 219 ++++++++++++++++++++++---- 1 file changed, 188 insertions(+), 31 deletions(-) diff --git a/columnphysics/icepack_therm_mushy.F90 b/columnphysics/icepack_therm_mushy.F90 index 2ec95cde0..c5a79ffd8 100644 --- a/columnphysics/icepack_therm_mushy.F90 +++ b/columnphysics/icepack_therm_mushy.F90 @@ -1369,14 +1369,31 @@ subroutine picard_solver(nilyr, nslyr, & ! if not converged if (.not. lconverged) then - call picard_nonconvergence(nilyr, nslyr,& - Tsf0, Tsf, & - zTsn0, zTsn, & - zTin0, zTin, & - zSin0, zSin, & - zqsn0, zqsn, & - zqin0, zqin, & - phi) + call picard_nonconvergence(nilyr, nslyr, & + Tsf0, Tsf, & + zTsn0, zTsn, & + zTin0, zTin, & + zSin0, zSin, & + zqsn0, zqsn, & + zqin0, phi, & + dt, & + hilyr, hslyr, & + km, ks, & + Iswabs, Sswabs, & + Tbot, & + fswint, fswsfc, & + rhoa, flw, & + potT, Qa, & + shcoef, lhcoef, & + fcondtop, fcondbot, & + fadvheat, & + flwoutn, fsensn, & + flatn, fsurfn, & + qpond, qocn, & + Spond, sss, & + q, dSdt, & + w) + if (icepack_warnings_aborted(subname)) return call icepack_warnings_add(subname//" picard_solver: Picard solver non-convergence" ) call icepack_warnings_setabort(.true.,__FILE__,__LINE__) @@ -1388,13 +1405,30 @@ end subroutine picard_solver !======================================================================= - subroutine picard_nonconvergence(nilyr, nslyr,& - Tsf0, Tsf, & - zTsn0, zTsn, & - zTin0, zTin, & - zSin0, zSin, & - zqsn0, zqsn, & - zqin0, zqin, phi) + subroutine picard_nonconvergence(nilyr, nslyr, & + Tsf0, Tsf, & + zTsn0, zTsn, & + zTin0, zTin, & + zSin0, zSin, & + zqsn0, zqsn, & + zqin0, phi, & + dt, & + hilyr, hslyr, & + km, ks, & + Iswabs, Sswabs, & + Tbot, & + fswint, fswsfc, & + rhoa, flw, & + potT, Qa, & + shcoef, lhcoef, & + fcondtop, fcondbot, & + fadvheat, & + flwoutn, fsensn, & + flatn, fsurfn, & + qpond, qocn, & + Spond, sss, & + q, dSdt, & + w) integer (kind=int_kind), intent(in) :: & nilyr , & ! number of ice layers @@ -1414,34 +1448,157 @@ subroutine picard_nonconvergence(nilyr, nslyr,& zSin0 , & ! ice layer bulk salinity (ppt) zSin , & ! ice layer bulk salinity (ppt) zqin0 , & - zqin , & phi ! ice layer liquid fraction + real(kind=dbl_kind), intent(in) :: & + dt , & ! time step (s) + hilyr , & ! ice layer thickness (m) + hslyr , & ! snow layer thickness (m) + Tbot , & ! ice bottom surfce temperature (deg C) + fswint , & ! SW absorbed in ice interior below surface (W m-2) + fswsfc , & ! SW absorbed at ice/snow surface (W m-2) + rhoa , & ! air density (kg/m^3) + flw , & ! incoming longwave radiation (W/m^2) + potT , & ! air potential temperature (K) + Qa , & ! specific humidity (kg/kg) + shcoef , & ! transfer coefficient for sensible heat + lhcoef , & ! transfer coefficient for latent heat + qpond , & ! melt pond brine enthalpy (J m-3) + qocn , & ! ocean brine enthalpy (J m-3) + Spond , & ! melt pond salinity (ppt) + sss , & ! sea surface salinity (ppt) + w ! vertical flushing Darcy velocity (m/s) + + real(kind=dbl_kind), dimension(:), intent(in) :: & + km , & ! ice conductivity (W m-1 K-1) + Iswabs , & ! SW radiation absorbed in ice layers (W m-2) + dSdt ! gravity drainage desalination rate for slow mode (ppt s-1) + + real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: & + q ! upward interface vertical Darcy flow (m s-1) + + real(kind=dbl_kind), dimension(:), intent(in) :: & + ks , & ! snow conductivity (W m-1 K-1) + Sswabs ! SW radiation absorbed in snow layers (W m-2) + + real(kind=dbl_kind), intent(in) :: & + flwoutn , & ! upward LW at surface (W m-2) + fsensn , & ! surface downward sensible heat (W m-2) + flatn , & ! surface downward latent heat (W m-2) + fsurfn ! net flux to top surface, excluding fcondtop + + real(kind=dbl_kind), intent(in) :: & + fcondtop , & ! downward cond flux at top surface (W m-2) + fcondbot , & ! downward cond flux at bottom surface (W m-2) + fadvheat ! flow of heat to ocean due to advection (W m-2) + integer :: & k ! vertical layer index - character(len=*),parameter :: subname='(picard_nonconvergence)' + character(len=char_len_long) :: & + warning ! warning message - write(warnstr,*) subname, "-------------------------------------" - call icepack_warnings_add(warnstr) - - write(warnstr,*) subname, "picard convergence failed!" - call icepack_warnings_add(warnstr) - write(warnstr,*) subname, 0, Tsf0, Tsf - call icepack_warnings_add(warnstr) + character(len=*),parameter :: subname='(picard_nonconvergence)' + write(warning,*) "-------------------------------------" + call icepack_warnings_add(warning) + write(warning,*) + call icepack_warnings_add(warning) + + write(warning,*) trim(subname)//":picard convergence failed!" + call icepack_warnings_add(warning) + write(warning,*) "==========================" + call icepack_warnings_add(warning) + write(warning,*) + call icepack_warnings_add(warning) + + write(warning,*) "Surface: Tsf0, Tsf" + call icepack_warnings_add(warning) + write(warning,*) 0, Tsf0, Tsf + call icepack_warnings_add(warning) + write(warning,*) + call icepack_warnings_add(warning) + + write(warning,*) "Snow: zTsn0(k), zTsn(k), zqsn0(k), ks(k), Sswabs(k)" + call icepack_warnings_add(warning) do k = 1, nslyr - write(warnstr,*) subname, k, zTsn0(k), zTsn(k), zqsn(k), zqsn0(k) - call icepack_warnings_add(warnstr) + write(warning,*) k, zTsn0(k), zTsn(k), zqsn0(k), ks(k), Sswabs(k) + call icepack_warnings_add(warning) enddo ! k + write(warning,*) + call icepack_warnings_add(warning) + write(warning,*) "Ice: zTin0(k), zTin(k), zSin0(k), zSin(k), phi(k), zqin0(k), km(k), Iswabs(k), dSdt(k)" + call icepack_warnings_add(warning) do k = 1, nilyr - write(warnstr,*) subname, k, zTin0(k), zTin(k), zSin0(k), zSin(k), phi(k), zqin(k), zqin0(k) - call icepack_warnings_add(warnstr) + write(warning,*) k, zTin0(k), zTin(k), zSin0(k), zSin(k), phi(k), zqin0(k), km(k), Iswabs(k), dSdt(k) + call icepack_warnings_add(warning) enddo ! k - - write(warnstr,*) subname, "-------------------------------------" - call icepack_warnings_add(warnstr) + write(warning,*) + call icepack_warnings_add(warning) + + write(warning,*) "Ice boundary: q(k)" + call icepack_warnings_add(warning) + do k = 0, nilyr + write(warning,*) k, q(k) + call icepack_warnings_add(warning) + enddo ! k + write(warning,*) + call icepack_warnings_add(warning) + + write(warning,*) "dt: ", dt + call icepack_warnings_add(warning) + write(warning,*) "hilyr: ", hilyr + call icepack_warnings_add(warning) + write(warning,*) "hslyr: ", hslyr + call icepack_warnings_add(warning) + write(warning,*) "Tbot: ", Tbot + call icepack_warnings_add(warning) + write(warning,*) "fswint: ", fswint + call icepack_warnings_add(warning) + write(warning,*) "fswsfc: ", fswsfc + call icepack_warnings_add(warning) + write(warning,*) "rhoa: ", rhoa + call icepack_warnings_add(warning) + write(warning,*) "flw: ", flw + call icepack_warnings_add(warning) + write(warning,*) "potT: ", potT + call icepack_warnings_add(warning) + write(warning,*) "Qa: ", Qa + call icepack_warnings_add(warning) + write(warning,*) "shcoef: ", shcoef + call icepack_warnings_add(warning) + write(warning,*) "lhcoef: ", lhcoef + call icepack_warnings_add(warning) + write(warning,*) "qpond: ", qpond + call icepack_warnings_add(warning) + write(warning,*) "qocn: ", qocn + call icepack_warnings_add(warning) + write(warning,*) "Spond: ", Spond + call icepack_warnings_add(warning) + write(warning,*) "sss: ", sss + call icepack_warnings_add(warning) + write(warning,*) "w: ", w + call icepack_warnings_add(warning) + write(warning,*) "flwoutn: ", flwoutn + call icepack_warnings_add(warning) + write(warning,*) "fsensn: ", fsensn + call icepack_warnings_add(warning) + write(warning,*) "flatn: ", flatn + call icepack_warnings_add(warning) + write(warning,*) "fsurfn: ", fsurfn + call icepack_warnings_add(warning) + write(warning,*) "fcondtop: ", fcondtop + call icepack_warnings_add(warning) + write(warning,*) "fcondbot: ", fcondbot + call icepack_warnings_add(warning) + write(warning,*) "fadvheat: ", fadvheat + call icepack_warnings_add(warning) + write(warning,*) + call icepack_warnings_add(warning) + + write(warning,*) "-------------------------------------" + call icepack_warnings_add(warning) end subroutine picard_nonconvergence From 45da0b3b2d6818f8e038c0bea4c8ca06e44fe89b Mon Sep 17 00:00:00 2001 From: Philippe Blain Date: Wed, 11 Oct 2023 15:58:07 -0400 Subject: [PATCH 02/30] doc: mention code variables relating to 'calc_dragio' (#466) * Add .readthedocs.yaml Copy CICE's readthedocs configuration as of CICE-Consortium/CICE@06282a53 (Update version to 6.4.2 (#864), 2023-09-08). * doc: mention code variables relating to 'calc_dragio' At the end of the "Ocean" section, we mention that 'dragio' can be computed from 'iceruf_ocn' and 'thickness_ocn_layer1', but do not mention these code variables, nor the 'calc_dragio' setting used to activate that computation. Mention the code variables next to their mathematical symbol, for more clarity. --- doc/source/science_guide/sg_boundary_forcing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/science_guide/sg_boundary_forcing.rst b/doc/source/science_guide/sg_boundary_forcing.rst index c7715228d..ce4f10e07 100755 --- a/doc/source/science_guide/sg_boundary_forcing.rst +++ b/doc/source/science_guide/sg_boundary_forcing.rst @@ -318,7 +318,7 @@ the ocean. If the resulting sea surface temperature falls below the salinity-dependent freezing point, then new ice (frazil) forms. Otherwise, heat is made available for melting the ice. -The ice-ocean drag coefficient, :math:`c_w`, can optionally be computed from the thickness of the first ocean level, :math:`h_1`, and an under-ice roughness length, :math:`z_{io}`. +When the namelist option ``calc_dragio`` is set to true, the ice-ocean drag coefficient, :math:`c_w` (``dragio``), is computed from the thickness of the first ocean level, :math:`h_1` (``thickness_ocn_layer1``), and an under-ice roughness length, :math:`z_{io}` (``iceruf_ocn``). The computation follows :cite:`Roy15` : .. math:: From 182030d49ca12aa429fdca7bfda70ee67354ad75 Mon Sep 17 00:00:00 2001 From: Philippe Blain Date: Thu, 12 Oct 2023 13:21:47 -0400 Subject: [PATCH 03/30] icepack_parameters: don't recompute constants in icepack_query_parameters (#465) All parameters of icepack_parameters::icepack_query_parameters are intent(out), so it does not make sense to recompute constants at the end of that subroutine since no constants are changed. This superfluous call dates back to the introduction of icepack_query_parameters (then called icepack_query_constants) in 7646f2a (Migrate icepack_constants out of the columnphysics/constants directory..., 2017-10-04). Remove that call. --- columnphysics/icepack_parameters.F90 | 3 --- 1 file changed, 3 deletions(-) diff --git a/columnphysics/icepack_parameters.F90 b/columnphysics/icepack_parameters.F90 index 02deaae9a..f875409b5 100644 --- a/columnphysics/icepack_parameters.F90 +++ b/columnphysics/icepack_parameters.F90 @@ -1799,9 +1799,6 @@ subroutine icepack_query_parameters( & if (present(sw_frac_out) ) sw_frac_out = sw_frac if (present(sw_dtemp_out) ) sw_dtemp_out = sw_dtemp - call icepack_recompute_constants() - if (icepack_warnings_aborted(subname)) return - end subroutine icepack_query_parameters !======================================================================= From aea58f3ad07b6bc7b58b8dfd49dcc5fd22ce8c29 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Fri, 13 Oct 2023 13:07:16 -0700 Subject: [PATCH 04/30] Port to Perlmutter gnu, intel, cray. (#467) --- configuration/scripts/icepack.batch.csh | 17 +++++++ configuration/scripts/icepack.launch.csh | 7 +++ .../scripts/machines/Macros.perlmutter_cray | 38 ++++++++++++++ .../scripts/machines/Macros.perlmutter_gnu | 38 ++++++++++++++ .../scripts/machines/Macros.perlmutter_intel | 40 +++++++++++++++ .../scripts/machines/env.perlmutter_cray | 50 +++++++++++++++++++ .../scripts/machines/env.perlmutter_gnu | 50 +++++++++++++++++++ .../scripts/machines/env.perlmutter_intel | 50 +++++++++++++++++++ 8 files changed, 290 insertions(+) create mode 100644 configuration/scripts/machines/Macros.perlmutter_cray create mode 100644 configuration/scripts/machines/Macros.perlmutter_gnu create mode 100644 configuration/scripts/machines/Macros.perlmutter_intel create mode 100644 configuration/scripts/machines/env.perlmutter_cray create mode 100644 configuration/scripts/machines/env.perlmutter_gnu create mode 100644 configuration/scripts/machines/env.perlmutter_intel diff --git a/configuration/scripts/icepack.batch.csh b/configuration/scripts/icepack.batch.csh index a104b8ff3..2268d1267 100755 --- a/configuration/scripts/icepack.batch.csh +++ b/configuration/scripts/icepack.batch.csh @@ -127,6 +127,23 @@ cat >> ${jobfile} << EOFB ###SBATCH --mail-user username@domain.com EOFB +else if (${ICE_MACHINE} =~ perlmutter*) then +@ nthrds2 = ${nthrds} * 2 +cat >> ${jobfile} << EOFB +#SBATCH -J ${ICE_CASENAME} +#SBATCH -A ${acct} +#SBATCH --qos ${ICE_MACHINE_QUEUE} +#SBATCH --time ${ICE_RUNLENGTH} +#SBATCH --nodes ${nnodes} +#SBATCH --ntasks ${ncores} +#SBATCH --cpus-per-task ${nthrds2} +#SBATCH --constraint cpu +###SBATCH -e filename +###SBATCH -o filename +###SBATCH --mail-type FAIL +###SBATCH --mail-user username@domain.com +EOFB + else if (${ICE_MACHINE} =~ compy*) then cat >> ${jobfile} << EOFB #SBATCH -J ${ICE_CASENAME} diff --git a/configuration/scripts/icepack.launch.csh b/configuration/scripts/icepack.launch.csh index dc7ddd489..ad74e2709 100755 --- a/configuration/scripts/icepack.launch.csh +++ b/configuration/scripts/icepack.launch.csh @@ -14,6 +14,13 @@ cat >> ${jobfile} << EOFR aprun -n 1 -N 1 -d 1 ./icepack >&! \$ICE_RUNLOG_FILE EOFR +#========================================== + +elseif (${ICE_MACHINE} =~ perlmutter) then +cat >> ${jobfile} << EOFR +srun --cpu-bind=cores ./icepack >&! \$ICE_RUNLOG_FILE +EOFR + #========================================== else cat >> ${jobfile} << EOFR diff --git a/configuration/scripts/machines/Macros.perlmutter_cray b/configuration/scripts/machines/Macros.perlmutter_cray new file mode 100644 index 000000000..da073cac4 --- /dev/null +++ b/configuration/scripts/machines/Macros.perlmutter_cray @@ -0,0 +1,38 @@ +#============================================================================== +# Makefile macros for NERSC perlmutter, cray compiler +#============================================================================== + +CPP := ftn -e P +CPPDEFS := -DFORTRANUNDERSCORE -DNO_R16 ${ICE_CPPDEFS} +CFLAGS := -c -O2 + +FIXEDFLAGS := -132 +FREEFLAGS := +FFLAGS := -hbyteswapio +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -hfp0 -g -Rbcdps -Ktrap=fp +else + FFLAGS += -O2 -hfp0 # -eo +endif + +SCC := cc +SFC := ftn +CC := $(SCC) +FC := $(SFC) +LD := $(FC) + +NETCDF_PATH := $(NETCDF_DIR) + +INCLDIR := $(INCLDIR) + +LIB_NETCDF := $(NETCDF_PATH)/lib +SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -fopenmp + CFLAGS += -fopenmp + FFLAGS += -fopenmp +endif + diff --git a/configuration/scripts/machines/Macros.perlmutter_gnu b/configuration/scripts/machines/Macros.perlmutter_gnu new file mode 100644 index 000000000..d9eef27bb --- /dev/null +++ b/configuration/scripts/machines/Macros.perlmutter_gnu @@ -0,0 +1,38 @@ +#============================================================================== +# Makefile macros for NERSC perlmutter, gnu compiler +#============================================================================== + +CPP := ftn -E +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c + +FIXEDFLAGS := -ffixed-line-length-132 +FREEFLAGS := -ffree-form +FFLAGS := -fconvert=big-endian -fbacktrace -ffree-line-length-none -fallow-argument-mismatch +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -g -fcheck=bounds -finit-real=nan -fimplicit-none -ffpe-trap=invalid,zero,overflow --std f2008 +# FFLAGS += -O0 -g -fcheck=all -finit-real=snan -fimplicit-none -ffpe-trap=invalid,zero,overflow + CFLAGS += -O0 +endif + +SCC := gcc +SFC := gfortran +CC := $(SCC) +FC := $(SFC) +LD := $(FC) + +NETCDF_PATH := $(NETCDF_DIR) + +INCLDIR := $(INCLDIR) + +LIB_NETCDF := $(NETCDF_PATH)/lib +SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -fopenmp + CFLAGS += -fopenmp + FFLAGS += -fopenmp +endif + diff --git a/configuration/scripts/machines/Macros.perlmutter_intel b/configuration/scripts/machines/Macros.perlmutter_intel new file mode 100644 index 000000000..48a4782ea --- /dev/null +++ b/configuration/scripts/machines/Macros.perlmutter_intel @@ -0,0 +1,40 @@ +#============================================================================== +# Makefile macros for NERSC perlmutter, intel compiler +#============================================================================== + +CPP := fpp +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c -O2 -fp-model precise -march=core-avx2 + +FIXEDFLAGS := -fixed -132 +FREEFLAGS := -free +FFLAGS := -fp-model precise -convert big_endian -assume byterecl -ftz -traceback -march=core-avx2 +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created -link_mpi=dbg +# FFLAGS += -O0 -g -check all -fpe0 -ftrapuv -fp-model except -check noarg_temp_created -link_mpi=dbg -stand f08 +# FFLAGS += -O0 -g -check all -fpe0 -ftrapuv -fp-model except -check noarg_temp_created -init=snan,arrays -link_mpi=dbg +else + FFLAGS += -O2 +endif + +SCC := icx +SFC := ifort +CC := $(SCC) +FC := $(SFC) +LD := $(FC) + +NETCDF_PATH := $(NETCDF_DIR) + +INCLDIR := $(INCLDIR) + +LIB_NETCDF := $(NETCDF_PATH)/lib +SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -qopenmp + CFLAGS += -qopenmp + FFLAGS += -qopenmp +endif + diff --git a/configuration/scripts/machines/env.perlmutter_cray b/configuration/scripts/machines/env.perlmutter_cray new file mode 100644 index 000000000..6cafd0153 --- /dev/null +++ b/configuration/scripts/machines/env.perlmutter_cray @@ -0,0 +1,50 @@ +#!/bin/csh -f + +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source ${MODULESHOME}/init/csh + +#module unload PrgEnv-aocc +#module unload PrgEnv-cray +#module unload PrgEnv-gnu +#module unload PrgEnv-intel +#module unload PrgEnv-nvidia +#module unload cpe +#module load cpe/23.03 +#module unload gpu +module load cpu +module load PrgEnv-cray +module unload cce +module load cce/15.0.1 +module unload cray-netcdf +module unload cray-hdf5 +module load cray-hdf5/1.12.2.3 +module load cray-netcdf/4.9.0.3 +#module unload cray-pals +#module load cray-pals/1.2.2 + +endif + +limit coredumpsize unlimited +limit stacksize unlimited +setenv PALS_QUIET TRUE + +setenv ICE_MACHINE_MACHNAME perlmutter +setenv ICE_MACHINE_MACHINFO "HPE Cray EX AMD EPYC 7763 Milan, Slingshot-11 Interconnect" +setenv ICE_MACHINE_ENVNAME cray +setenv ICE_MACHINE_ENVINFO "Cray clang/Fortran 15.0.1, netcdf4.9.0.3" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR $SCRATCH/ICEPACK_RUNS +setenv ICE_MACHINE_INPUTDATA /global/cfs/cdirs/e3sm/tcraig/cice-consortium +setenv ICE_MACHINE_BASELINE $SCRATCH/ICEPACK_BASELINE +setenv ICE_MACHINE_SUBMIT "sbatch" +setenv ICE_MACHINE_ACCT P00000000 +setenv ICE_MACHINE_QUEUE "shared" +setenv ICE_MACHINE_TPNODE 128 +setenv ICE_MACHINE_BLDTHRDS 1 +setenv ICE_MACHINE_QSTAT "squeue --jobs= " diff --git a/configuration/scripts/machines/env.perlmutter_gnu b/configuration/scripts/machines/env.perlmutter_gnu new file mode 100644 index 000000000..417cdc897 --- /dev/null +++ b/configuration/scripts/machines/env.perlmutter_gnu @@ -0,0 +1,50 @@ +#!/bin/csh -f + +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source ${MODULESHOME}/init/csh + +#module unload PrgEnv-aocc +#module unload PrgEnv-cray +#module unload PrgEnv-gnu +#module unload PrgEnv-intel +#module unload PrgEnv-nvidia +#module unload cpe +#module load cpe/23.03 +#module unload gpu +module load cpu +module load PrgEnv-gnu +module unload gcc +module load gcc/11.2.0 +module unload cray-netcdf +module unload cray-hdf5 +module load cray-hdf5/1.12.2.3 +module load cray-netcdf/4.9.0.3 +#module unload cray-pals +#module load cray-pals/1.2.2 + +endif + +limit coredumpsize unlimited +limit stacksize unlimited +setenv PALS_QUIET TRUE + +setenv ICE_MACHINE_MACHNAME perlmutter +setenv ICE_MACHINE_MACHINFO "HPE Cray EX AMD EPYC 7763 Milan, Slingshot-11 Interconnect" +setenv ICE_MACHINE_ENVNAME gnu +setenv ICE_MACHINE_ENVINFO "gcc/gfortran 11.2.0 20210728, netcdf4.9.0.3" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR $SCRATCH/ICEPACK_RUNS +setenv ICE_MACHINE_INPUTDATA /global/cfs/cdirs/e3sm/tcraig/cice-consortium +setenv ICE_MACHINE_BASELINE $SCRATCH/ICEPACK_BASELINE +setenv ICE_MACHINE_SUBMIT "sbatch" +setenv ICE_MACHINE_ACCT P00000000 +setenv ICE_MACHINE_QUEUE "shared" +setenv ICE_MACHINE_TPNODE 128 +setenv ICE_MACHINE_BLDTHRDS 1 +setenv ICE_MACHINE_QSTAT "squeue --jobs= " diff --git a/configuration/scripts/machines/env.perlmutter_intel b/configuration/scripts/machines/env.perlmutter_intel new file mode 100644 index 000000000..85b6989af --- /dev/null +++ b/configuration/scripts/machines/env.perlmutter_intel @@ -0,0 +1,50 @@ +#!/bin/csh -f + +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source ${MODULESHOME}/init/csh + +#module unload PrgEnv-aocc +#module unload PrgEnv-cray +#module unload PrgEnv-gnu +#module unload PrgEnv-intel +#module unload PrgEnv-nvidia +#module unload cpe +#module load cpe/23.03 +#module unload gpu +module load cpu +module load PrgEnv-intel +module unload intel +module load intel/2023.1.0 +module unload cray-netcdf +module unload cray-hdf5 +module load cray-hdf5/1.12.2.3 +module load cray-netcdf/4.9.0.3 +#module unload cray-pals +#module load cray-pals/1.2.2 + +endif + +limit coredumpsize unlimited +limit stacksize unlimited +setenv PALS_QUIET TRUE + +setenv ICE_MACHINE_MACHNAME perlmutter +setenv ICE_MACHINE_MACHINFO "HPE Cray EX AMD EPYC 7763 Milan, Slingshot-11 Interconnect" +setenv ICE_MACHINE_ENVNAME intel +setenv ICE_MACHINE_ENVINFO "ifort 2021.9.0 20230302, netcdf4.9.0.3" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR $SCRATCH/ICEPACK_RUNS +setenv ICE_MACHINE_INPUTDATA /global/cfs/cdirs/e3sm/tcraig/cice-consortium +setenv ICE_MACHINE_BASELINE $SCRATCH/ICEPACK_BASELINE +setenv ICE_MACHINE_SUBMIT "sbatch" +setenv ICE_MACHINE_ACCT P00000000 +setenv ICE_MACHINE_QUEUE "shared" +setenv ICE_MACHINE_TPNODE 128 +setenv ICE_MACHINE_BLDTHRDS 1 +setenv ICE_MACHINE_QSTAT "squeue --jobs= " From f6989f1db6239ecaa2573eb5e50a7f06d127bb53 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Fri, 13 Oct 2023 14:22:37 -0700 Subject: [PATCH 05/30] Remove _old options for tfrz_option (#468) * Remove older "_old" tfrz_options, added for backwards compatibility Modify tfrz_option logic in icepack_sea_freezing_temperature to trap unsupported values * Update Icepack set_nml settings, remove _old from tfrz_option --- columnphysics/icepack_therm_shared.F90 | 13 +++++++++---- columnphysics/icepack_tracers.F90 | 13 ++----------- configuration/scripts/options/set_nml.alt03 | 2 +- configuration/scripts/options/set_nml.alt04 | 2 +- configuration/scripts/options/set_nml.bgcispol | 2 +- configuration/scripts/options/set_nml.bgcnice | 2 +- configuration/scripts/options/set_nml.bgcsklnice | 2 +- configuration/scripts/options/set_nml.fsd12 | 2 +- configuration/scripts/options/set_nml.leap | 2 +- configuration/scripts/options/set_nml.modal | 2 +- configuration/scripts/options/set_nml.thermo1 | 2 +- 11 files changed, 20 insertions(+), 24 deletions(-) diff --git a/columnphysics/icepack_therm_shared.F90 b/columnphysics/icepack_therm_shared.F90 index 32fa2ae96..eed1677a9 100644 --- a/columnphysics/icepack_therm_shared.F90 +++ b/columnphysics/icepack_therm_shared.F90 @@ -393,22 +393,27 @@ function icepack_sea_freezing_temperature(sss) result(Tf) character(len=*),parameter :: subname='(icepack_sea_freezing_temperature)' - if (trim(tfrz_option(1:5)) == 'mushy') then + if (trim(tfrz_option) == 'mushy') then Tf = icepack_liquidus_temperature(sss) ! deg C - elseif (trim(tfrz_option(1:11)) == 'linear_salt') then + elseif (trim(tfrz_option) == 'linear_salt') then Tf = -depressT * sss ! deg C - elseif (trim(tfrz_option(1:8)) == 'constant') then + elseif (trim(tfrz_option) == 'constant') then Tf = Tocnfrz - else + elseif (trim(tfrz_option) == 'minus1p8') then Tf = -1.8_dbl_kind + else + + call icepack_warnings_add(subname//' tfrz_option unsupported: '//trim(tfrz_option)) + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + endif end function icepack_sea_freezing_temperature diff --git a/columnphysics/icepack_tracers.F90 b/columnphysics/icepack_tracers.F90 index 3057ad57b..8414e0c98 100644 --- a/columnphysics/icepack_tracers.F90 +++ b/columnphysics/icepack_tracers.F90 @@ -7,7 +7,7 @@ module icepack_tracers use icepack_kinds - use icepack_parameters, only: c0, c1, puny, rhos, rsnw_fall, rhosnew, Tocnfrz, tfrz_option + use icepack_parameters, only: c0, c1, puny, rhos, rsnw_fall, rhosnew use icepack_parameters, only: snwredist, snwgrain use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted @@ -1265,16 +1265,7 @@ subroutine icepack_compute_tracers (ntrcr, trcr_depend, & else trcrn(it) = c0 if (it == nt_Tsfc) then -! tcraig, these old options should be deprecated -! exist for bit-for-bit backwards compatibility in testing - if (tfrz_option == "mushy_old" .or. & - tfrz_option == "linear_salt_old" .or. & - tfrz_option == "constant_old" .or. & - tfrz_option == "minus1p8_old") then - trcrn(it) = Tocnfrz ! surface temperature - else - trcrn(it) = Tf ! surface temperature - endif + trcrn(it) = Tf ! surface temperature endif endif diff --git a/configuration/scripts/options/set_nml.alt03 b/configuration/scripts/options/set_nml.alt03 index bd51c8561..3fa70399f 100644 --- a/configuration/scripts/options/set_nml.alt03 +++ b/configuration/scripts/options/set_nml.alt03 @@ -5,7 +5,7 @@ sw_redist = .true. sw_frac = 0.9d0 sw_dtemp = 0.02d0 - tfrz_option = 'linear_salt_old' + tfrz_option = 'linear_salt' conduct = 'bubbly' conserv_check = .true. restore_ocn = .true. diff --git a/configuration/scripts/options/set_nml.alt04 b/configuration/scripts/options/set_nml.alt04 index c416a2729..c468c4661 100644 --- a/configuration/scripts/options/set_nml.alt04 +++ b/configuration/scripts/options/set_nml.alt04 @@ -8,7 +8,7 @@ sw_redist = .true. sw_frac = 0.9d0 sw_dtemp = 0.02d0 - tfrz_option = 'linear_salt_old' + tfrz_option = 'linear_salt' conduct = 'bubbly' krdg_partic = 0 krdg_redist = 0 diff --git a/configuration/scripts/options/set_nml.bgcispol b/configuration/scripts/options/set_nml.bgcispol index 8c530fd2f..9f3eab1f6 100644 --- a/configuration/scripts/options/set_nml.bgcispol +++ b/configuration/scripts/options/set_nml.bgcispol @@ -24,4 +24,4 @@ tr_bgc_hum = .true. tr_bgc_DON = .true. tr_bgc_Fe = .false. - tfrz_option = 'mushy_old' + tfrz_option = 'mushy' diff --git a/configuration/scripts/options/set_nml.bgcnice b/configuration/scripts/options/set_nml.bgcnice index 5062b1699..286b76161 100644 --- a/configuration/scripts/options/set_nml.bgcnice +++ b/configuration/scripts/options/set_nml.bgcnice @@ -24,4 +24,4 @@ tr_bgc_hum = .true. tr_bgc_DON = .true. tr_bgc_Fe = .true. - tfrz_option = 'mushy_old' + tfrz_option = 'mushy' diff --git a/configuration/scripts/options/set_nml.bgcsklnice b/configuration/scripts/options/set_nml.bgcsklnice index ef3fb435f..12ac85505 100644 --- a/configuration/scripts/options/set_nml.bgcsklnice +++ b/configuration/scripts/options/set_nml.bgcsklnice @@ -22,4 +22,4 @@ year_init = 2015 tr_bgc_hum = .true. tr_bgc_DON = .true. tr_bgc_Fe = .true. - tfrz_option = 'mushy_old' + tfrz_option = 'mushy' diff --git a/configuration/scripts/options/set_nml.fsd12 b/configuration/scripts/options/set_nml.fsd12 index 1692e95b2..ac5a02bba 100644 --- a/configuration/scripts/options/set_nml.fsd12 +++ b/configuration/scripts/options/set_nml.fsd12 @@ -1,3 +1,3 @@ tr_fsd = .true. wave_spec_type = 'constant' -tfrz_option = 'mushy_old' +tfrz_option = 'mushy' diff --git a/configuration/scripts/options/set_nml.leap b/configuration/scripts/options/set_nml.leap index 4802b6eea..4c20718da 100644 --- a/configuration/scripts/options/set_nml.leap +++ b/configuration/scripts/options/set_nml.leap @@ -1,3 +1,3 @@ days_per_year = 365 use_leap_years = .true. -tfrz_option = 'mushy_old' +tfrz_option = 'mushy' diff --git a/configuration/scripts/options/set_nml.modal b/configuration/scripts/options/set_nml.modal index 22e670ca6..8e9db0eb4 100644 --- a/configuration/scripts/options/set_nml.modal +++ b/configuration/scripts/options/set_nml.modal @@ -5,5 +5,5 @@ tr_aero = .true. modal_aero = .true. rfracmin = 0.15 rfracmax = 1.0 -tfrz_option = 'mushy_old' +tfrz_option = 'mushy' diff --git a/configuration/scripts/options/set_nml.thermo1 b/configuration/scripts/options/set_nml.thermo1 index e1c3c2aac..4ed48a77a 100644 --- a/configuration/scripts/options/set_nml.thermo1 +++ b/configuration/scripts/options/set_nml.thermo1 @@ -6,5 +6,5 @@ sw_redist = .true. sw_frac = 0.9d0 sw_dtemp = 0.02d0 conduct = 'MU71' -tfrz_option = 'linear_salt_old' +tfrz_option = 'linear_salt' atm_data_type = 'clim' From 0c548120ce443824241051196f5ba508cb7ba7db Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Mon, 16 Oct 2023 14:40:05 -0700 Subject: [PATCH 06/30] Change CPP USE_SNICARNC to NO_SNICARNC (#469) --- columnphysics/icepack_shortwave_data.F90 | 7 ++++--- configuration/scripts/icepack.build | 4 ++-- doc/source/user_guide/ug_case_settings.rst | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/columnphysics/icepack_shortwave_data.F90 b/columnphysics/icepack_shortwave_data.F90 index d37df293d..50bdf5eaa 100644 --- a/columnphysics/icepack_shortwave_data.F90 +++ b/columnphysics/icepack_shortwave_data.F90 @@ -711,11 +711,12 @@ end subroutine icepack_shortwave_init_snicartest subroutine icepack_shortwave_init_snicar() -! USE_SNICARHC turns on big hardcoded tables but also increases compile time -#ifndef USE_SNICARHC +! NO_SNICARHC turns off hardcoded tables to reduce compile time +#ifdef NO_SNICARHC character(len=*),parameter :: subname='(icepack_shortwave_init_snicar)' + call icepack_warnings_add(subname//' ERROR: large shortwave snicar tables not compiled') + call icepack_warnings_add(subname//' ERROR: NO_SNICARHC CPP should be turned off') call icepack_warnings_setabort(.true.,__FILE__,__LINE__) - call icepack_warnings_add(subname//' ERROR: USE_SNICARHC CPP required') return #else integer (kind=int_kind) :: & diff --git a/configuration/scripts/icepack.build b/configuration/scripts/icepack.build index 2dd444fde..f897de471 100755 --- a/configuration/scripts/icepack.build +++ b/configuration/scripts/icepack.build @@ -68,8 +68,8 @@ setenv ICE_CPPDEFS "${ICE_CPPDEFS} -DNXGLOB=${ICE_NXGLOB} -DNICELYR=${NICELYR} - if (${ICE_IOTYPE} == 'netcdf') then setenv ICE_CPPDEFS "${ICE_CPPDEFS} -DUSE_NETCDF" endif -if (${ICE_SNICARHC} == 'true') then - setenv ICE_CPPDEFS "${ICE_CPPDEFS} -DUSE_SNICARHC" +if (${ICE_SNICARHC} == 'false') then + setenv ICE_CPPDEFS "${ICE_CPPDEFS} -DNO_SNICARHC" endif ### List of source code directories (in order of importance). diff --git a/doc/source/user_guide/ug_case_settings.rst b/doc/source/user_guide/ug_case_settings.rst index 754b51c2f..f3b80c455 100644 --- a/doc/source/user_guide/ug_case_settings.rst +++ b/doc/source/user_guide/ug_case_settings.rst @@ -31,8 +31,8 @@ can be found in :ref:`cicecpps`. The following CPPs are available. "**General Macros**", "" "NO_I8", "Converts ``integer*8`` to ``integer*4``." "NO_R16", "Converts ``real*16`` to ``real*8``." + "NO_SNICARHC", "Does not compile hardcoded (HC) 5 band snicar tables tables needed by ``shortwave=dEdd_snicar_ad``. May reduce compile time." "USE_NETCDF", "Turns on netcdf capabilities in Icepack. By default and generally, Icepack does not need netcdf." - "USE_SNICARHC", "Compiles hardcoded (HC) tables needed for ``dEdd_snicar_ad``, which can lengthen the compile time considerably." "","" "**Application Macros**", "" "CESMCOUPLED", "Turns on code changes for the CESM coupled application " From 863b19c618c24f879043058231f1c9d3977c5d1d Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Wed, 18 Oct 2023 10:47:28 -0700 Subject: [PATCH 07/30] Update Derecho inputdata path, point to campaign (#471) --- configuration/scripts/machines/env.derecho_cray | 2 +- configuration/scripts/machines/env.derecho_gnu | 2 +- configuration/scripts/machines/env.derecho_intel | 2 +- configuration/scripts/machines/env.derecho_intelclassic | 2 +- configuration/scripts/machines/env.derecho_inteloneapi | 2 +- configuration/scripts/machines/env.derecho_nvhpc | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/configuration/scripts/machines/env.derecho_cray b/configuration/scripts/machines/env.derecho_cray index 1fc814594..9faf34aa2 100644 --- a/configuration/scripts/machines/env.derecho_cray +++ b/configuration/scripts/machines/env.derecho_cray @@ -41,7 +41,7 @@ setenv ICE_MACHINE_ENVNAME cray setenv ICE_MACHINE_ENVINFO "cce 15.0.1, netcdf4.9.2" setenv ICE_MACHINE_MAKE gmake setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS -setenv ICE_MACHINE_INPUTDATA /glade/p/cesm/pcwg_dev +setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "qsub" setenv ICE_MACHINE_ACCT P00000000 diff --git a/configuration/scripts/machines/env.derecho_gnu b/configuration/scripts/machines/env.derecho_gnu index 3c45d71bf..606dbbebc 100644 --- a/configuration/scripts/machines/env.derecho_gnu +++ b/configuration/scripts/machines/env.derecho_gnu @@ -41,7 +41,7 @@ setenv ICE_MACHINE_ENVNAME gnu setenv ICE_MACHINE_ENVINFO "gcc 12.2.0 20220819, netcdf4.9.2" setenv ICE_MACHINE_MAKE gmake setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS -setenv ICE_MACHINE_INPUTDATA /glade/p/cesm/pcwg_dev +setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "qsub" setenv ICE_MACHINE_ACCT P00000000 diff --git a/configuration/scripts/machines/env.derecho_intel b/configuration/scripts/machines/env.derecho_intel index 6067556e8..fdf64e157 100644 --- a/configuration/scripts/machines/env.derecho_intel +++ b/configuration/scripts/machines/env.derecho_intel @@ -41,7 +41,7 @@ setenv ICE_MACHINE_ENVNAME intel setenv ICE_MACHINE_ENVINFO "ifort 2021.8.0 20221119, netcdf4.9.2" setenv ICE_MACHINE_MAKE gmake setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS -setenv ICE_MACHINE_INPUTDATA /glade/p/cesm/pcwg_dev +setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "qsub" setenv ICE_MACHINE_ACCT P00000000 diff --git a/configuration/scripts/machines/env.derecho_intelclassic b/configuration/scripts/machines/env.derecho_intelclassic index 7bd8e5dff..a2d583733 100644 --- a/configuration/scripts/machines/env.derecho_intelclassic +++ b/configuration/scripts/machines/env.derecho_intelclassic @@ -41,7 +41,7 @@ setenv ICE_MACHINE_ENVNAME intelclassic setenv ICE_MACHINE_ENVINFO "icc/ifort 2021.8.0 20221119, netcdf4.9.2" setenv ICE_MACHINE_MAKE gmake setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS -setenv ICE_MACHINE_INPUTDATA /glade/p/cesm/pcwg_dev +setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "qsub" setenv ICE_MACHINE_ACCT P00000000 diff --git a/configuration/scripts/machines/env.derecho_inteloneapi b/configuration/scripts/machines/env.derecho_inteloneapi index 09cdf7291..358bd9834 100644 --- a/configuration/scripts/machines/env.derecho_inteloneapi +++ b/configuration/scripts/machines/env.derecho_inteloneapi @@ -41,7 +41,7 @@ setenv ICE_MACHINE_ENVNAME inteloneapi setenv ICE_MACHINE_ENVINFO "ifx 2023.0.0 20221201, netcdf4.9.2" setenv ICE_MACHINE_MAKE gmake setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS -setenv ICE_MACHINE_INPUTDATA /glade/p/cesm/pcwg_dev +setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "qsub" setenv ICE_MACHINE_ACCT P00000000 diff --git a/configuration/scripts/machines/env.derecho_nvhpc b/configuration/scripts/machines/env.derecho_nvhpc index 32f4d1aca..4723c0da4 100644 --- a/configuration/scripts/machines/env.derecho_nvhpc +++ b/configuration/scripts/machines/env.derecho_nvhpc @@ -41,7 +41,7 @@ setenv ICE_MACHINE_ENVNAME nvhpc setenv ICE_MACHINE_ENVINFO "nvc 23.5-0, netcdf4.9.2" setenv ICE_MACHINE_MAKE gmake setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS -setenv ICE_MACHINE_INPUTDATA /glade/p/cesm/pcwg_dev +setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "qsub" setenv ICE_MACHINE_ACCT P00000000 From 7a0d4e9f16eb6505a11372ced01dbd217f00d505 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Wed, 18 Oct 2023 12:33:49 -0700 Subject: [PATCH 08/30] Clarify documentation associated with namelist inputs (#470) * Clarify documentation associated with namelist inputs Alphabetize cpl_frazil namelist documentation * Update documentation --- doc/source/icepack_index.rst | 8 +++++--- doc/source/user_guide/ug_case_settings.rst | 14 +++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/doc/source/icepack_index.rst b/doc/source/icepack_index.rst index fed6ceb18..bd5e89214 100755 --- a/doc/source/icepack_index.rst +++ b/doc/source/icepack_index.rst @@ -5,13 +5,15 @@ Index of primary variables and parameters ========================================== -This index defines many of the symbols used frequently in the ice model +This index defines many (but not all) of the symbols used frequently in the ice model code. Values appearing in this list are fixed or recommended; most namelist parameters are indicated ( :math:`\bullet`) with their default -values. For other namelist options, see Section :ref:`tabnamelist`. All -quantities in the code are expressed in MKS units (temperatures may take +values. All quantities in the code are expressed in MKS units (temperatures may take either Celsius or Kelvin units). Deprecated parameters are listed at the end. +Namelist variables are partly included here, but they are fully documented in +section :ref:`tabnamelist`. + .. csv-table:: *Alphabetical Index of Icepack Variables and Parameters* :header: " ", " ", " " :widths: 15, 30, 15, 1 diff --git a/doc/source/user_guide/ug_case_settings.rst b/doc/source/user_guide/ug_case_settings.rst index f3b80c455..0b7e4fa31 100644 --- a/doc/source/user_guide/ug_case_settings.rst +++ b/doc/source/user_guide/ug_case_settings.rst @@ -2,8 +2,8 @@ .. _case_settings: -Case Settings -===================== +Case Settings, Model Namelist, and CPPs +==================================================== There are two important files that define the case, **icepack.settings** and **icepack_in**. **icepack.settings** is a list of env variables that define many @@ -115,8 +115,8 @@ can be modified as needed. .. _tabnamelist: -Table of Namelist Inputs --------------------------- +Tables of Namelist Options +---------------------------- The Icepack driver reads a namelist input file, **icepack_in**, consisting of several namelist groups. The tables below summarize the different groups and the variables in each group. The variables are organized alphabetically @@ -344,6 +344,9 @@ forcing_nml "``calc_strair``", "``.false.``", "read wind stress and speed from files", "``.true.``" "", "``.true.``", "calculate wind stress and speed", "" "``calc_Tsfc``", "logical", "calculate surface temperature", "``.true.``" + "``cpl_frazil``", "``external``", "frazil water/salt fluxes are handled outside of Icepack", "``fresh_ice_correction``" + "", "``fresh_ice_correction``", "correct fresh-ice frazil water/salt fluxes for mushy physics", "" + "", "``internal``", "send full frazil water/salt fluxes for mushy physics", "" "``data_dir``", "string", "path to forcing data directory", "' '" "``default_season``", "``summer``", "forcing initial summer values", "``winter``" "", "``winter``", "forcing initial winter values", "" @@ -378,9 +381,6 @@ forcing_nml "", "``minus1p8``", "constant ocean freezing temperature (:math:`-1.8^{\circ} C`)", "" "", "``mushy``", "matches mushy-layer thermo (ktherm=2)", "" "``trestore``", "integer", "sst restoring time scale (days)", "90" - "``cpl_frazil``", "``external``", "frazil water/salt fluxes are handled outside of Icepack", "``fresh_ice_correction``" - "", "``fresh_ice_correction``", "correct fresh-ice frazil water/salt fluxes for mushy physics", "" - "", "``internal``", "send full frazil water/salt fluxes for mushy physics", "" "``update_ocn_f``", "``.false.``", "do not include frazil water/salt fluxes in ocn fluxes", "``.false.``" "", "``true``", "include frazil water/salt fluxes in ocn fluxes", "" "``ustar_min``", "real", "minimum value of ocean friction velocity in m/s", "0.005" From 6ad0f44d7d1da19403ddc9131d3d813cccb2ec0f Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Fri, 27 Oct 2023 14:43:20 -0700 Subject: [PATCH 09/30] Update 5-band dEdd to support test data (#472) * Update 5-band dEdd to support test data Add an interpolation method in icepack_shortwave.F90 for rsnw Refactor portions of icepack_shortwave to improve robustness Add snicar and snicartest test cases * Update the 5-band snicar shortwave rsnw_snicar_tab interpolation This changes answers but QC tests pass. The new implementation checks whether the rsnw_snicar_tab is an array of integer values with deltas of value 1 (and sets the rsnw_snicar_chk variable). If so, it uses a shortcut to find the rsnw_snicar_tab bounds for interpolation, otherwise it calls the shortwave_search routine. In testing, the shortcut did not change performance much, but that could change in the future. * Clean up debug output * Refactor the logic to control rsnw table interpolation in the shortwave. Set a character string, rsnw_datatype, at initialization. --- columnphysics/icepack_shortwave.F90 | 189 ++++++++++++++---- columnphysics/icepack_shortwave_data.F90 | 17 +- configuration/scripts/options/set_env.snicar | 2 - .../scripts/options/set_env.snicartest | 2 - configuration/scripts/tests/base_suite.ts | 4 + configuration/scripts/tests/snicar_suite.ts | 7 - 6 files changed, 162 insertions(+), 59 deletions(-) delete mode 100644 configuration/scripts/options/set_env.snicartest delete mode 100644 configuration/scripts/tests/snicar_suite.ts diff --git a/columnphysics/icepack_shortwave.F90 b/columnphysics/icepack_shortwave.F90 index f6c1a7223..dfa2d6422 100644 --- a/columnphysics/icepack_shortwave.F90 +++ b/columnphysics/icepack_shortwave.F90 @@ -62,7 +62,7 @@ module icepack_shortwave use icepack_tracers, only: tr_zaero, nlt_chl_sw, nlt_zaero_sw use icepack_tracers, only: n_algae, n_aero, n_zaero use icepack_tracers, only: nmodal1, nmodal2, max_aero - use icepack_shortwave_data, only: nspint_3bd, nspint_5bd + use icepack_shortwave_data, only: nspint_3bd, nspint_5bd, rsnw_datatype use icepack_zbgc_shared,only: R_chl2N, F_abs_chl use icepack_zbgc_shared,only: remap_zbgc use icepack_orbital, only: compute_coszen @@ -101,9 +101,8 @@ module icepack_shortwave gaer_5bd, kaer_5bd, waer_5bd use icepack_shortwave_data, only: & nmbrad_snicar , & ! number of snow grain radii in SNICAR SSP tables - rsnw_snicar_min, & ! minimum snow radius - integer value used for indexing - rsnw_snicar_max ! maximum snow radius - integer value used for indexing - use icepack_shortwave_data, only: & + rsnw_snicar_min, & ! minimum snow radius + rsnw_snicar_max, & ! maximum snow radius ssp_snwextdr, ssp_snwalbdr, ssp_sasymmdr, & ssp_snwextdf, ssp_snwalbdf, ssp_sasymmdf, & rsnw_snicar_tab @@ -2135,7 +2134,7 @@ subroutine compute_dEdd_3bd( & ! Cheng: note that aerosol IOPs are related to snow grain radius. ! CICE adjusted snow grain radius rsnw to frsnw in the original 3-band ! scheme, while for SNICAR the snow grain radius is used directly. - ksnow = k - min(k-1,0) + ksnow = max(k,1) tmp_gs = frsnw(ksnow) ! grain size index @@ -2268,7 +2267,7 @@ subroutine compute_dEdd_3bd( & do k = 0, nslyr ! use top rsnw, rhosnw for snow ssl and rest of top layer - ksnow = k - min(k-1,0) + ksnow = max(k,1) ! find snow iops using input snow density and snow grain radius: if (frsnw(ksnow) < rsnw_tab(1)) then Qs = Qs_tab(ns,1) @@ -2279,20 +2278,16 @@ subroutine compute_dEdd_3bd( & ws = ws_tab(ns,nmbrad_snw) gs = gs_tab(ns,nmbrad_snw) else - ! linear interpolation in rsnw - do nr = 2, nmbrad_snw - if (rsnw_tab(nr-1) <= frsnw(ksnow) .and. & - frsnw(ksnow) < rsnw_tab(nr)) then - delr = (frsnw(ksnow) - rsnw_tab(nr-1)) / & - (rsnw_tab(nr) - rsnw_tab(nr-1)) - Qs = Qs_tab(ns,nr-1)*(c1-delr) + & - Qs_tab(ns,nr )* delr - ws = ws_tab(ns,nr-1)*(c1-delr) + & - ws_tab(ns,nr )* delr - gs = gs_tab(ns,nr-1)*(c1-delr) + & - gs_tab(ns,nr )* delr - endif - enddo ! nr + call shortwave_search(frsnw(ksnow),rsnw_tab,nr) + if (icepack_warnings_aborted(subname)) return + delr = (frsnw(ksnow) - rsnw_tab(nr-1)) / & + (rsnw_tab(nr) - rsnw_tab(nr-1)) + Qs = Qs_tab(ns,nr-1)*(c1-delr) + & + Qs_tab(ns,nr )* delr + ws = ws_tab(ns,nr-1)*(c1-delr) + & + ws_tab(ns,nr )* delr + gs = gs_tab(ns,nr-1)*(c1-delr) + & + gs_tab(ns,nr )* delr endif ks = Qs*((rhosnw(ksnow)/rhoi)*3._dbl_kind / & (4._dbl_kind*frsnw(ksnow)*1.0e-6_dbl_kind)) @@ -4677,7 +4672,7 @@ subroutine compute_dEdd_5bd( & ! CICE adjusted snow grain radius rsnw to frsnw, while for ! SNICAR there is no need, the tmp_gs is therefore calculated ! differently from code in subroutine compute_dEdd - ksnow = k - min(k-1,0) + ksnow = max(k,1) tmp_gs = rsnw(ksnow) ! use rsnw not frsnw ! grain size index @@ -4806,7 +4801,7 @@ subroutine compute_dEdd_5bd( & if (nsky == 1) then ! direct incident do k = 0, nslyr ! use top rsnw, rhosnw for snow ssl and rest of top layer - ksnow = k - min(k-1,0) + ksnow = max(k,1) if (rsnw(ksnow) <= rsnw_snicar_min) then ks = ext_cff_mss_ice_drc(ns,1) ws = ss_alb_ice_drc (ns,1) @@ -4815,16 +4810,18 @@ subroutine compute_dEdd_5bd( & ks = ext_cff_mss_ice_drc(ns,nmbrad_snicar) ws = ss_alb_ice_drc (ns,nmbrad_snicar) gs = asm_prm_ice_drc (ns,nmbrad_snicar) - elseif (ceiling(rsnw(ksnow)) - rsnw(ksnow) < 1.0e-3_dbl_kind) then - ! radius = 30 --> nr = 1 in SNICAR table ! NOTE - nr = ceiling(rsnw(ksnow)) - 30 + 1 ! hardwired min radius = 30 - ks = ext_cff_mss_ice_drc(ns,nr) - ws = ss_alb_ice_drc (ns,nr) - gs = asm_prm_ice_drc (ns,nr) - else ! linear interpolation in rsnw - nr = ceiling(rsnw(ksnow)) - 30 + 1 ! hardwired min radius = 30 - delr = (rsnw(ksnow) - floor(rsnw(ksnow))) & ! hardwired delta radius = 1 in table - / (ceiling(rsnw(ksnow)) - floor(rsnw(ksnow))) ! denom always = 1 + else + ! linear interpolation + if (trim(rsnw_datatype) == 'sorted_idelta1') then + ! NOTE: Assumes delta rsnw_snicar_tab is 1 and rsnw_snicar_tab are integers + ! This is just for performance, could call shortwave_search + nr = ceiling(rsnw(ksnow)) - nint(rsnw_snicar_min) + 1 + else + call shortwave_search(rsnw(ksnow),rsnw_snicar_tab,nr) + if (icepack_warnings_aborted(subname)) return + endif + delr = (rsnw(ksnow) - rsnw_snicar_tab(nr-1)) & + / (rsnw_snicar_tab(nr) - rsnw_snicar_tab(nr-1)) ks = ext_cff_mss_ice_drc(ns,nr-1)*(c1-delr) & + ext_cff_mss_ice_drc(ns,nr )* delr ws = ss_alb_ice_drc (ns,nr-1)*(c1-delr) & @@ -4839,7 +4836,7 @@ subroutine compute_dEdd_5bd( & elseif (nsky == 2) then ! diffuse incident do k = 0, nslyr ! use top rsnw, rhosnw for snow ssl and rest of top layer - ksnow = k - min(k-1,0) + ksnow = max(k,1) if (rsnw(ksnow) < rsnw_snicar_min) then ks = ext_cff_mss_ice_dfs(ns,1) ws = ss_alb_ice_dfs (ns,1) @@ -4848,16 +4845,18 @@ subroutine compute_dEdd_5bd( & ks = ext_cff_mss_ice_dfs(ns,nmbrad_snicar) ws = ss_alb_ice_dfs (ns,nmbrad_snicar) gs = asm_prm_ice_dfs (ns,nmbrad_snicar) - elseif (ceiling(rsnw(ksnow)) - rsnw(ksnow) < 1.0e-3_dbl_kind) then - ! radius = 30 --> nr = 1 in SNICAR table ! NOTE - nr = ceiling(rsnw(ksnow)) - 30 + 1 ! hardwired min radius = 30 - ks = ext_cff_mss_ice_dfs(ns,nr) - ws = ss_alb_ice_dfs (ns,nr) - gs = asm_prm_ice_dfs (ns,nr) - else ! linear interpolation in rsnw - nr = ceiling(rsnw(ksnow)) - 30 + 1 ! hardwired min radius = 30 - delr = (rsnw(ksnow) - floor(rsnw(ksnow))) & ! hardwired delta radius = 1 in table - / (ceiling(rsnw(ksnow)) - floor(rsnw(ksnow))) + else + ! linear interpolation + if (trim(rsnw_datatype) == 'sorted_idelta1') then + ! NOTE: delta rsnw_snicar_tab is 1 and rsnw_snicar_tab are integers + ! This is just for performance, could call shortwave_search + nr = ceiling(rsnw(ksnow)) - nint(rsnw_snicar_min) + 1 + else + call shortwave_search(rsnw(ksnow),rsnw_snicar_tab,nr) + if (icepack_warnings_aborted(subname)) return + endif + delr = (rsnw(ksnow) - rsnw_snicar_tab(nr-1)) & + / (rsnw_snicar_tab(nr) - rsnw_snicar_tab(nr-1)) ks = ext_cff_mss_ice_dfs(ns,nr-1)*(c1-delr) & + ext_cff_mss_ice_dfs(ns,nr )* delr ws = ss_alb_ice_dfs (ns,nr-1)*(c1-delr) & @@ -5400,6 +5399,110 @@ subroutine compute_dEdd_5bd( & end subroutine compute_dEdd_5bd +!======================================================================= +! This subroutine searches array for val and returns nr such that +! array(nr-1) < val <= array(nr) +! If nr cannot be found, an error is thrown +! This does NOT check that array is sorted because it would be too expensive, +! but it must be sorted to work properly. + + subroutine shortwave_search(val,array,nr) + + real (kind=dbl_kind), intent(in) :: & + val ! search value + + real (kind=dbl_kind), dimension (:), intent(in) :: & + array ! sorted array + + integer (kind=int_kind), intent(out) :: & + nr ! index in array >= val + + ! local variables + + integer (kind=int_kind) :: & + nrcnt, & ! counter + nrp, & ! prior nr + nrl, nru, & ! lower and upper search indices + nrsize ! size of array + + logical (kind=log_kind) :: & + found ! search flag + + character (len=512) :: & + tmpstr ! temporary string + + character(len=*),parameter :: subname='(shortwave_search)' + + + if (rsnw_datatype(1:6) /= 'sorted') then + call icepack_warnings_add(subname//' rsnw_datatype not valid: '//trim(rsnw_datatype)) + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + endif + + nrsize = size(array) + +!debug write(tmpstr,*) "val = ",val +! call icepack_warnings_add(subname//trim(tmpstr)) +! write(tmpstr,*) "nrsize = ",nrsize +! call icepack_warnings_add(subname//trim(tmpstr)) +! write(tmpstr,*) "array1 = ",array(1) +! call icepack_warnings_add(subname//trim(tmpstr)) +! write(tmpstr,*) "arrayn = ",array(nrsize) +! call icepack_warnings_add(subname//trim(tmpstr)) + + if (nrsize > 10) then + ! binary search + nrl = 1 + nru = nrsize + nr = (nrl + nru) / 2 + found = .false. + nrcnt = 0 + do while (.not.found .and. nrcnt < nrsize) + nrcnt = nrcnt + 1 + nrp = nr + if (val > array(nr)) then + if (val < array(nr+1)) then + found = .true. + nr = nr + 1 + else + nrl = nr + 1 + nr = (nrl + nru) / 2 + endif + else + if (val > array(nr-1)) then + found = .true. + else + nru = nr - 1 + nr = (nrl + nru) / 2 + endif + endif +!debug write(tmpstr,*) "iter = ",nrcnt,nrp,nr +! call icepack_warnings_add(subname//trim(tmpstr)) +! call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + enddo + if (.not. found) then + call icepack_warnings_add(subname//' ERROR: binary search failed') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + return + endif + else + ! linear search + nr = -1 + do nrcnt = 2,nrsize + if (val > array(nrcnt-1) .and. val < array(nrcnt)) then + nr = nrcnt + exit + endif + enddo + if (nr < 1) then + call icepack_warnings_add(subname//' ERROR: linear search failed') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + return + endif + endif + + end subroutine shortwave_search + !======================================================================= end module icepack_shortwave diff --git a/columnphysics/icepack_shortwave_data.F90 b/columnphysics/icepack_shortwave_data.F90 index 50bdf5eaa..b9ebe614d 100644 --- a/columnphysics/icepack_shortwave_data.F90 +++ b/columnphysics/icepack_shortwave_data.F90 @@ -15,6 +15,9 @@ module icepack_shortwave_data nspint_3bd = 3, & ! number of solar spectral bands nspint_5bd = 5 ! number of solar spectral bands (snicar snow) + character (len=char_len), public :: & + rsnw_datatype = 'unknown' + ! dEdd 3-band data real (kind=dbl_kind), dimension (nspint_3bd), public :: & ! inherent optical properties (iop) @@ -63,7 +66,9 @@ module icepack_shortwave_data ! dEdd 5-band data SSP SNICAR integer (kind=int_kind), public :: & - nmbrad_snicar , & ! number of snow grain radii in SNICAR SSP tables + nmbrad_snicar ! number of snow grain radii in SNICAR SSP tables + + real (kind=dbl_kind), public :: & rsnw_snicar_min, & ! minimum snow radius - integer value used for indexing rsnw_snicar_max ! maximum snow radius - integer value used for indexing @@ -107,6 +112,7 @@ subroutine icepack_shortwave_init_dEdd3band allocate(gs_tab (nspint_3bd,nmbrad_snw)) ! snow grain radii (micro-meters) for table + rsnw_datatype = 'sorted' rsnw_tab = (/ & ! snow grain radius for each table entry (micro-meters) 5._dbl_kind, 7._dbl_kind, 10._dbl_kind, 15._dbl_kind, & 20._dbl_kind, 30._dbl_kind, 40._dbl_kind, 50._dbl_kind, & @@ -646,6 +652,7 @@ subroutine icepack_shortwave_init_snicartest() 6._dbl_kind, 37._dbl_kind, 221._dbl_kind, 600._dbl_kind, 1340._dbl_kind/) rsnw_snicar_min = rsnw_snicar_tab(1) ! minimum snow radius - integer value used for indexing rsnw_snicar_max = rsnw_snicar_tab(nmbrad_snicar) ! maximum snow radius - integer value used for indexing + rsnw_datatype = 'sorted' allocate(ssp_snwextdr(nspint_5bd,nmbrad_snicar)) ! extinction coefficient, direct allocate(ssp_snwextdf(nspint_5bd,nmbrad_snicar)) ! extinction coefficient, diffuse @@ -9586,11 +9593,11 @@ subroutine icepack_shortwave_init_snicar() ! Copy to local variables -!echmod - this might not be needed - rsnw_snicar_min = 30 ! minimum snow grain radius - rsnw_snicar_max = 1500 ! maximum snow grain radius + rsnw_snicar_min = 30._dbl_kind ! minimum snow grain radius + rsnw_snicar_max = 1500._dbl_kind ! maximum snow grain radius + rsnw_datatype = 'sorted_idelta1' ! sorted "integers" with constant delta 1 allocate(rsnw_snicar_tab(nmbrad_snicar)) - rsnw_snicar_tab(1) = real(rsnw_snicar_min,dbl_kind) + rsnw_snicar_tab(1) = rsnw_snicar_min do n = 1, nmbrad_snicar-1 rsnw_snicar_tab(n+1) = rsnw_snicar_tab(n) + 1.0_dbl_kind enddo diff --git a/configuration/scripts/options/set_env.snicar b/configuration/scripts/options/set_env.snicar index 13cd94861..91c70cb4b 100644 --- a/configuration/scripts/options/set_env.snicar +++ b/configuration/scripts/options/set_env.snicar @@ -1,3 +1 @@ -setenv ICE_IOTYPE netcdf -setenv ICE_NXGLOB 1 setenv ICE_SNICARHC true diff --git a/configuration/scripts/options/set_env.snicartest b/configuration/scripts/options/set_env.snicartest deleted file mode 100644 index 7ac74351d..000000000 --- a/configuration/scripts/options/set_env.snicartest +++ /dev/null @@ -1,2 +0,0 @@ -setenv ICE_IOTYPE netcdf -setenv ICE_NXGLOB 1 diff --git a/configuration/scripts/tests/base_suite.ts b/configuration/scripts/tests/base_suite.ts index ce98270fd..43e405dab 100644 --- a/configuration/scripts/tests/base_suite.ts +++ b/configuration/scripts/tests/base_suite.ts @@ -21,6 +21,8 @@ smoke col 1x1 debug,run1year,calcdragio smoke col 1x1 debug,run1year,modal smoke col 1x1 debug,run1year,fluxopenw smoke col 1x1 debug,run1year,dyn,fluxopenw +smoke col 1x1 debug,run1year,debug,snicartest +smoke col 1x1 debug,run1year,debug,snicar restart col 1x1 debug restart col 1x1 diag1 restart col 1x1 pondlvl @@ -39,4 +41,6 @@ restart col 1x1 fsd12,short restart col 1x1 snwitdrdg,snwgrain restart col 1x1 modal restart col 1x1 fluxopenw +restart col 1x1 snicartest +restart col 1x1 snicar diff --git a/configuration/scripts/tests/snicar_suite.ts b/configuration/scripts/tests/snicar_suite.ts deleted file mode 100644 index 2eb4c9b32..000000000 --- a/configuration/scripts/tests/snicar_suite.ts +++ /dev/null @@ -1,7 +0,0 @@ -# Test Grid PEs Sets BFB-compare -smoke col 1x1 diag1,run1year -smoke col 1x1 debug,run1year -smoke col 1x1 diag1,run1year,snicartest -smoke col 1x1 debug,run1year,snicartest -smoke col 1x1 diag1,run1year,snicar -smoke col 1x1 debug,run1year,snicar From 71093e6e5b608067cb124d769cb4180c3f6f9820 Mon Sep 17 00:00:00 2001 From: Elizabeth Hunke Date: Fri, 27 Oct 2023 15:43:47 -0600 Subject: [PATCH 10/30] adjust denominator for flux limiting by -puny (fbot+fside<0) (#474) --- columnphysics/icepack_therm_vertical.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/columnphysics/icepack_therm_vertical.F90 b/columnphysics/icepack_therm_vertical.F90 index 2d0c20cea..bca098ea6 100644 --- a/columnphysics/icepack_therm_vertical.F90 +++ b/columnphysics/icepack_therm_vertical.F90 @@ -638,7 +638,7 @@ subroutine frzmlt_bottom_lateral (dt, ncat, & ! FYI: fside is not yet correct for fsd, may need to adjust fbot further !----------------------------------------------------------------- - xtmp = frzmlt/(fbot + fside + puny) + xtmp = frzmlt/(fbot + fside - puny) xtmp = min(xtmp, c1) fbot = fbot * xtmp rside = rside * xtmp From 84ff38867dcf27eccaaf83a827195c45c84d73fe Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Fri, 27 Oct 2023 14:44:00 -0700 Subject: [PATCH 11/30] Update version, interface documentation, trailing blanks (#473) --- columnphysics/icepack_itd.F90 | 14 +++++++------- columnphysics/icepack_mechred.F90 | 2 +- columnphysics/icepack_shortwave.F90 | 2 +- columnphysics/icepack_therm_itd.F90 | 14 +++++++------- columnphysics/icepack_therm_vertical.F90 | 2 +- columnphysics/version.txt | 2 +- configuration/driver/icedrv_forcing.F90 | 4 ++-- configuration/driver/icedrv_init_column.F90 | 2 +- doc/source/conf.py | 4 ++-- doc/source/user_guide/interfaces.include | 7 +++++-- 10 files changed, 28 insertions(+), 25 deletions(-) diff --git a/columnphysics/icepack_itd.F90 b/columnphysics/icepack_itd.F90 index b86d1cf78..0da1f1590 100644 --- a/columnphysics/icepack_itd.F90 +++ b/columnphysics/icepack_itd.F90 @@ -135,7 +135,7 @@ subroutine rebin (ntrcr, trcr_depend, & real (kind=dbl_kind), dimension(0:ncat), intent(in) :: & hin_max ! category limits (m) - + real (kind=dbl_kind), intent(in) :: & Tf ! freezing temperature @@ -785,11 +785,11 @@ subroutine cleanup_itd (dt, ntrcr, & ntrcr , & ! number of tracers in use nbtrcr, & ! number of bio tracers in use n_aero ! number of aerosol tracers - - real (kind=dbl_kind), intent(in) :: & - dt ! time step - - real (kind=dbl_kind), intent(in) :: & + + real (kind=dbl_kind), intent(in) :: & + dt ! time step + + real (kind=dbl_kind), intent(in) :: & Tf ! Freezing temperature real (kind=dbl_kind), dimension(0:ncat), intent(in) :: & @@ -1923,7 +1923,7 @@ subroutine icepack_aggregate (ncat, & atrcr, aice, & vice , vsno, & trcr_base, n_trcr_strata, & - nt_strata, trcr, Tf) + nt_strata, trcr, Tf) if (icepack_warnings_aborted(subname)) return deallocate (atrcr) diff --git a/columnphysics/icepack_mechred.F90 b/columnphysics/icepack_mechred.F90 index 818faa01d..b32a2c199 100644 --- a/columnphysics/icepack_mechred.F90 +++ b/columnphysics/icepack_mechred.F90 @@ -401,7 +401,7 @@ subroutine ridge_ice (dt, ndtd, & msnow_mlt, esnow_mlt, & maero, miso, & mpond, Tf, & - aredistn, vredistn) + aredistn, vredistn) if (icepack_warnings_aborted(subname)) return !----------------------------------------------------------------- diff --git a/columnphysics/icepack_shortwave.F90 b/columnphysics/icepack_shortwave.F90 index dfa2d6422..30be6869f 100644 --- a/columnphysics/icepack_shortwave.F90 +++ b/columnphysics/icepack_shortwave.F90 @@ -4508,7 +4508,7 @@ subroutine compute_dEdd_5bd( & ! copy/point to table data for local names asm_prm_ice_drc => ssp_sasymmdr asm_prm_ice_dfs => ssp_sasymmdf - ss_alb_ice_drc => ssp_snwalbdr + ss_alb_ice_drc => ssp_snwalbdr ss_alb_ice_dfs => ssp_snwalbdf ext_cff_mss_ice_drc => ssp_snwextdr ext_cff_mss_ice_dfs => ssp_snwextdf diff --git a/columnphysics/icepack_therm_itd.F90 b/columnphysics/icepack_therm_itd.F90 index b6048dbce..b53051494 100644 --- a/columnphysics/icepack_therm_itd.F90 +++ b/columnphysics/icepack_therm_itd.F90 @@ -92,10 +92,10 @@ subroutine linear_itd (ncat, hin_max, & ntrcr, trcr_depend, & trcr_base, n_trcr_strata,& nt_strata, & - aicen_init, vicen_init, & - aicen, trcrn, & - vicen, vsnon, & - aice, aice0, & + aicen_init, vicen_init, & + aicen, trcrn, & + vicen, vsnon, & + aice, aice0, & fpond, Tf ) integer (kind=int_kind), intent(in) :: & @@ -1627,8 +1627,8 @@ subroutine add_new_ice (ncat, nilyr, & vi0tmp = fnew*dt / (rhoi*Lfresh) ! ocn/cpl assumes frazil volume is pure, fresh ice dfresh = -rhoi*(vi0new - vi0tmp)/dt frazil_diag = frazil - vi0tmp -! else -! do nothing - other correction options could be implemented in the future +! else +! do nothing - other correction options could be implemented in the future endif if (saltflux_option == 'prognostic') then @@ -1637,7 +1637,7 @@ subroutine add_new_ice (ncat, nilyr, & dfsalt = ice_ref_salinity*p001*dfresh endif fresh = fresh + dfresh - fsalt = fsalt + dfsalt + fsalt = fsalt + dfsalt endif !----------------------------------------------------------------- diff --git a/columnphysics/icepack_therm_vertical.F90 b/columnphysics/icepack_therm_vertical.F90 index bca098ea6..81e357b4e 100644 --- a/columnphysics/icepack_therm_vertical.F90 +++ b/columnphysics/icepack_therm_vertical.F90 @@ -2495,7 +2495,7 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & fsnow = fsnow*(c1-worka) endif ! snwredist -!echmod - remove all of this code - non-BFB because of values carried in tracer arrays when the snow physics options are not active +!echmod - remove all of this code - non-BFB because of values carried in tracer arrays when the snow physics options are not active !----------------------------------------------------------------- ! solid and liquid components of snow mass !----------------------------------------------------------------- diff --git a/columnphysics/version.txt b/columnphysics/version.txt index 739229a40..760fc61f7 100644 --- a/columnphysics/version.txt +++ b/columnphysics/version.txt @@ -1 +1 @@ -ICEPACK 1.3.4 +ICEPACK 1.4.0 diff --git a/configuration/driver/icedrv_forcing.F90 b/configuration/driver/icedrv_forcing.F90 index f7cfb01ff..b3f360f7a 100644 --- a/configuration/driver/icedrv_forcing.F90 +++ b/configuration/driver/icedrv_forcing.F90 @@ -97,7 +97,7 @@ module icedrv_forcing oceanmixed_ice , & ! if true, use internal ocean mixed layer restore_ocn ! restore sst if true - real (kind=dbl_kind), public :: & + real (kind=dbl_kind), public :: & trest, & ! restoring time scale (sec) trestore ! restoring time scale (days) @@ -1077,7 +1077,7 @@ end subroutine ocn_ISPOL subroutine finish_ocn_forcing(sst_temp) ! Compute ocean freezing temperature Tf based on tfrz_option -! 'minus1p8' Tf = -1.8 C +! 'minus1p8' Tf = -1.8 C ! 'constant' Tf = Tocnfrz ! 'linear_salt' Tf = -depressT * sss ! 'mushy' Tf conforms with mushy layer thermo (ktherm=2) diff --git a/configuration/driver/icedrv_init_column.F90 b/configuration/driver/icedrv_init_column.F90 index 15a795bcc..9a22a5ff3 100644 --- a/configuration/driver/icedrv_init_column.F90 +++ b/configuration/driver/icedrv_init_column.F90 @@ -1066,7 +1066,7 @@ subroutine init_zbgc if (modal_aero .AND. (.NOT. tr_zaero) .AND. (.NOT. tr_aero)) then modal_aero = .false. endif - + if (modal_aero .AND. trim(shortwave(1:4)) /= 'dEdd') then write(nu_diag,*) 'WARNING: modal_aero = T but shortwave /= dEdd' write(nu_diag,*) 'WARNING: setting modal_aero = F' diff --git a/doc/source/conf.py b/doc/source/conf.py index 6a6aa7cc0..48648d1a5 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.4' +version = u'1.4.0' # The full version, including alpha/beta/rc tags. -version = u'1.3.4' +version = u'1.4.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/user_guide/interfaces.include b/doc/source/user_guide/interfaces.include index e4bbb7d37..44aebada4 100644 --- a/doc/source/user_guide/interfaces.include +++ b/doc/source/user_guide/interfaces.include @@ -844,7 +844,7 @@ icepack_init_parameters rhos_in, rhoi_in, rhow_in, cp_air_in, emissivity_in, & cp_ice_in, cp_ocn_in, hfrazilmin_in, floediam_in, & depressT_in, dragio_in, thickness_ocn_layer1_in, iceruf_ocn_in, & - albocn_in, gravit_in, viscosity_dyn_in, & + albocn_in, gravit_in, viscosity_dyn_in, tscale_pnd_drain_in, & Tocnfrz_in, rhofresh_in, zvir_in, vonkar_in, cp_wv_in, & stefan_boltzmann_in, ice_ref_salinity_in, & Tffresh_in, Lsub_in, Lvap_in, Timelt_in, Tsmelt_in, & @@ -927,6 +927,7 @@ icepack_init_parameters cp_ocn_in, & ! specific heat of ocn (J/kg/K) depressT_in, & ! Tf:brine salinity ratio (C/ppt) viscosity_dyn_in, & ! dynamic viscosity of brine (kg/m/s) + tscale_pnd_drain_in,&! mushy macroscopic drainage timescale (days) Tocnfrz_in, & ! freezing temp of seawater (C) Tffresh_in, & ! freezing temp of fresh ice (K) Lsub_in, & ! latent heat, sublimation freshwater (J/kg) @@ -1258,7 +1259,8 @@ icepack_query_parameters p333_out, p666_out, spval_const_out, pih_out, piq_out, pi2_out, & rhos_out, rhoi_out, rhow_out, cp_air_out, emissivity_out, & cp_ice_out, cp_ocn_out, hfrazilmin_out, floediam_out, & - depressT_out, dragio_out, thickness_ocn_layer1_out, iceruf_ocn_out, albocn_out, gravit_out, viscosity_dyn_out, & + depressT_out, dragio_out, thickness_ocn_layer1_out, iceruf_ocn_out, & + albocn_out, gravit_out, viscosity_dyn_out, tscale_pnd_drain_out, & Tocnfrz_out, rhofresh_out, zvir_out, vonkar_out, cp_wv_out, & stefan_boltzmann_out, ice_ref_salinity_out, & Tffresh_out, Lsub_out, Lvap_out, Timelt_out, Tsmelt_out, & @@ -1349,6 +1351,7 @@ icepack_query_parameters cp_ocn_out, & ! specific heat of ocn (J/kg/K) depressT_out, & ! Tf:brine salinity ratio (C/ppt) viscosity_dyn_out, & ! dynamic viscosity of brine (kg/m/s) + tscale_pnd_drain_out, & ! mushy macroscopic drainage timescale (days) Tocnfrz_out, & ! freezing temp of seawater (C) Tffresh_out, & ! freezing temp of fresh ice (K) Lsub_out, & ! latent heat, sublimation freshwater (J/kg) From d1a42fb142033ca8c82a3f440ed38c63d992a314 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Fri, 27 Oct 2023 22:18:08 -0700 Subject: [PATCH 12/30] Fix icepack.launch.csh (#475) --- configuration/scripts/icepack.launch.csh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration/scripts/icepack.launch.csh b/configuration/scripts/icepack.launch.csh index ad74e2709..5218f0c9c 100755 --- a/configuration/scripts/icepack.launch.csh +++ b/configuration/scripts/icepack.launch.csh @@ -16,7 +16,7 @@ EOFR #========================================== -elseif (${ICE_MACHINE} =~ perlmutter) then +else if (${ICE_MACHINE} =~ perlmutter) then cat >> ${jobfile} << EOFR srun --cpu-bind=cores ./icepack >&! \$ICE_RUNLOG_FILE EOFR From b129416d7157a33a80b8ebfe40ce8d36773227cc Mon Sep 17 00:00:00 2001 From: Elizabeth Hunke Date: Tue, 14 Nov 2023 16:32:57 -0700 Subject: [PATCH 13/30] correct ks units, clean up comments, bug fix for BL99 enthalpy calculation (#476) * correct ks units, clean up comments, big fix for BL99 enthalpy calculation * make it pretty --- columnphysics/icepack_mechred.F90 | 1 - columnphysics/icepack_shortwave.F90 | 2 +- columnphysics/icepack_shortwave_data.F90 | 8 ------ columnphysics/icepack_therm_itd.F90 | 1 - columnphysics/icepack_therm_vertical.F90 | 35 ++++++------------------ configuration/driver/icedrv_step.F90 | 1 - 6 files changed, 9 insertions(+), 39 deletions(-) diff --git a/columnphysics/icepack_mechred.F90 b/columnphysics/icepack_mechred.F90 index b32a2c199..d897dba49 100644 --- a/columnphysics/icepack_mechred.F90 +++ b/columnphysics/icepack_mechred.F90 @@ -68,7 +68,6 @@ module icepack_mechred Gstar = p15 , & ! max value of G(h) that participates ! (krdg_partic = 0) astar = p05 , & ! e-folding scale for G(h) participation -!echmod astar = p1 , & ! e-folding scale for G(h) participation ! (krdg_partic = 1) maxraft= c1 , & ! max value of hrmin - hi = max thickness ! of ice that rafts (m) diff --git a/columnphysics/icepack_shortwave.F90 b/columnphysics/icepack_shortwave.F90 index 30be6869f..236e25f8a 100644 --- a/columnphysics/icepack_shortwave.F90 +++ b/columnphysics/icepack_shortwave.F90 @@ -1844,7 +1844,7 @@ subroutine compute_dEdd_3bd( & delr , & ! snow grain radius interpolation parameter ! inherent optical properties (iop) for snow Qs , & ! Snow extinction efficiency - ks , & ! Snow mass extinction coefficient (m^2/kg) ! echmod - CHECK units and usage + ks , & ! Snow mass extinction coefficient (1/m) ws , & ! Snow single scattering albedo gs ! Snow asymmetry parameter diff --git a/columnphysics/icepack_shortwave_data.F90 b/columnphysics/icepack_shortwave_data.F90 index b9ebe614d..fb41c415c 100644 --- a/columnphysics/icepack_shortwave_data.F90 +++ b/columnphysics/icepack_shortwave_data.F90 @@ -448,14 +448,6 @@ subroutine icepack_shortwave_init_dEdd5band character (len=*),parameter :: subname='(icepack_shortwave_init_dEdd5band)' - ! 5-bands ice surface scattering layer (ssl) iops to match SNICAR calculations - ! note by Cheng Dang: - ! for now these data are not needed since the sea ice layer IOPs can be directly - ! assigned based on the 3 bands data after adjustment based on tuning parameter R_ice - ! In the future, when 5-band sea ice IOPs are available, these data shall be updated - ! and the sea ice layer IOPs shall be calculated based on updated 5band iops* -!echmod - the comment above says these are not needed but they are nevertheless used below - ! ! The 5band data given in this section are based on CICE and SNICAR band choice: ! SNICAR band 1 = CICE band 1 ! SNICAR band 2 + SNICAR band 3 = CICE band 2 diff --git a/columnphysics/icepack_therm_itd.F90 b/columnphysics/icepack_therm_itd.F90 index b53051494..0606747a7 100644 --- a/columnphysics/icepack_therm_itd.F90 +++ b/columnphysics/icepack_therm_itd.F90 @@ -2293,7 +2293,6 @@ subroutine icepack_step_therm2 (dt, ncat, nltrcr, & ! thickness, and the other half decreases the area). !----------------------------------------------------------------- -!echmod: test this if (ncat==1) & call reduce_area (hin_max (0), & aicen (1), vicen (1), & diff --git a/columnphysics/icepack_therm_vertical.F90 b/columnphysics/icepack_therm_vertical.F90 index 81e357b4e..7cd9f2533 100644 --- a/columnphysics/icepack_therm_vertical.F90 +++ b/columnphysics/icepack_therm_vertical.F90 @@ -962,21 +962,18 @@ subroutine init_vertical_profile(nilyr, nslyr, & !----------------------------------------------------------------- if (ktherm /= 2) then - if (zTin(k) > c0) then - zTin(k) = c0 - zqin(k) = -rhoi*Lfresh + zTin(k) = c0 + zqin(k) = -rhoi*Lfresh endif - endif -! echmod: is this necessary? -! if (ktherm == 1) then -! if (zTin(k)>= -zSin(k)*depressT) then -! zTin(k) = -zSin(k)*depressT - puny -! zqin(k) = -rhoi*cp_ocn*zSin(k)*depressT -! endif -! endif + if (ktherm == 1) then + if (zTin(k)>= -zSin(k)*depressT) then + zTin(k) = -zSin(k)*depressT - puny + zqin(k) = -zSin(k)*depressT*rhoi*cp_ocn + endif + endif !----------------------------------------------------------------- ! initial energy per unit area of ice/snow, relative to 0 C @@ -2495,22 +2492,6 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & fsnow = fsnow*(c1-worka) endif ! snwredist -!echmod - remove all of this code - non-BFB because of values carried in tracer arrays when the snow physics options are not active - !----------------------------------------------------------------- - ! solid and liquid components of snow mass - !----------------------------------------------------------------- -! massicen(:,:) = c0 -! massliqn(:,:) = c0 -! if (snwgrain) then -! rnslyr = c1 / real(nslyr, dbl_kind) -! do n = 1, ncat -! do k = 1, nslyr -! massicen(k,n) = smicen(k,n) * vsnon(n) * rnslyr ! kg/m^2 -! massliqn(k,n) = smliqn(k,n) * vsnon(n) * rnslyr -! enddo -! enddo -! endif - !----------------------------------------------------------------- ! Update the neutral drag coefficients to account for form drag ! Oceanic and atmospheric drag coefficients diff --git a/configuration/driver/icedrv_step.F90 b/configuration/driver/icedrv_step.F90 index dc86ac398..0f25b5656 100644 --- a/configuration/driver/icedrv_step.F90 +++ b/configuration/driver/icedrv_step.F90 @@ -237,7 +237,6 @@ subroutine step_therm1 (dt) enddo ! i do i = 1, nx -!echmod do i = 3,3 if (tr_aero) then ! trcrn(nt_aero) has units kg/m^3 do n = 1, ncat From f6ff8f7c4d4cb6feabe3651b13204cf43fc948e3 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Fri, 17 Nov 2023 09:22:49 -0800 Subject: [PATCH 14/30] Update logical for optional argument wlat, caught with debug by gnu compiler (#477) --- columnphysics/icepack_therm_itd.F90 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/columnphysics/icepack_therm_itd.F90 b/columnphysics/icepack_therm_itd.F90 index 0606747a7..047b921bf 100644 --- a/columnphysics/icepack_therm_itd.F90 +++ b/columnphysics/icepack_therm_itd.F90 @@ -964,6 +964,7 @@ subroutine lateral_melt (dt, ncat, & bin1_arealoss, tmp ! logical (kind=log_kind) :: & + fsd_wlat, & ! .true. if wlat present and wlat > puny flag ! .true. if there could be lateral melting real (kind=dbl_kind), dimension (ncat) :: & @@ -1024,7 +1025,14 @@ subroutine lateral_melt (dt, ncat, & f_flx = c0 end if - if (tr_fsd .and. wlat > puny) then + ! fsd_wlat == if (tr_fsd .and. wlat > puny) + ! need fsd_wlat because wlat is optional + fsd_wlat = .false. + if (tr_fsd .and. present(wlat)) then + if (wlat > puny) fsd_wlat = .true. + endif + + if (fsd_wlat) then flag = .true. ! for FSD rside and fside not yet computed correctly, redo here From 3ffde678ce81de782eccc557de249323534de100 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Thu, 29 Feb 2024 20:33:22 -0800 Subject: [PATCH 15/30] Update pull request template, Update conda_macos debug flag (#484) Update pull request template to ask for additional information about the PR. This information can and will be used during the squash merge process to produce more useful commit logs. Update Macros.conda_macos to remove ffpe-trap=invalid from debug flags. This flag causes nf90_create to fail with the latest version of the conda environment. This happens when debug flags are on and a test with netcdf is turned on. I believe this is a compiler error. --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- configuration/scripts/machines/Macros.conda_macos | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 4ab4ecadf..8b0fa3a24 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -26,4 +26,4 @@ please refer to: Date: Fri, 1 Mar 2024 10:14:48 -0700 Subject: [PATCH 16/30] Add gnuplot to the conda environment (#483) * Add gnuplot to the conda environment This fix allows the timeseries.csh script to be used for Icepack standalone runs. --- configuration/scripts/machines/environment.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configuration/scripts/machines/environment.yml b/configuration/scripts/machines/environment.yml index dfbcaf85e..d2adbf009 100644 --- a/configuration/scripts/machines/environment.yml +++ b/configuration/scripts/machines/environment.yml @@ -8,6 +8,8 @@ dependencies: - netcdf-fortran - netcdf4 - make +# Plotting dependencies + - gnuplot # Python dependencies for building the HTML documentation - sphinx - sphinxcontrib-bibtex From 74cc6f42607f3c286132edbf60b687ab3ec00fab Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Fri, 26 Apr 2024 15:41:58 -0700 Subject: [PATCH 17/30] Add Tutorial to User Guide as Appendix (#485) * add tutorial documentation * add tutorial * add tutorial * add tutorial * add tutorial * add tutorial * Minor clarifications and grammatical updates. --------- Co-authored-by: Elizabeth Hunke --- doc/source/appendices/icepack_index.rst | 1 + doc/source/appendices/index.rst | 11 ++ doc/source/appendices/tutorial.rst | 221 ++++++++++++++++++++++++ doc/source/index.rst | 2 +- 4 files changed, 234 insertions(+), 1 deletion(-) create mode 120000 doc/source/appendices/icepack_index.rst create mode 100755 doc/source/appendices/index.rst create mode 100644 doc/source/appendices/tutorial.rst diff --git a/doc/source/appendices/icepack_index.rst b/doc/source/appendices/icepack_index.rst new file mode 120000 index 000000000..de23229be --- /dev/null +++ b/doc/source/appendices/icepack_index.rst @@ -0,0 +1 @@ +../icepack_index.rst \ No newline at end of file diff --git a/doc/source/appendices/index.rst b/doc/source/appendices/index.rst new file mode 100755 index 000000000..ffd6e293c --- /dev/null +++ b/doc/source/appendices/index.rst @@ -0,0 +1,11 @@ +.. _appendices: + +Appendices +----------------------- + +.. toctree:: + :maxdepth: 3 + + icepack_index.rst + tutorial.rst + diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst new file mode 100644 index 000000000..fbd0aa567 --- /dev/null +++ b/doc/source/appendices/tutorial.rst @@ -0,0 +1,221 @@ +:tocdepth: 3 + +.. _tutorial: + +Icepack Tutorial +================= + + + +Learning Goals +---------------- + +In this activity you will clone the Icepack model code from the Consortium GitHub repository to run standalone Icepack simulations. You will also make namelist changes and code modifications for experiments and make some basic plots. If you run into issues, contact dbailey@ucar.edu. + +Notes: + +* Command line text is shown in highlighted boxes. +* When there is the syntax, you need to fill in your personal information (e.g. a URL or username) for that command but without the angle brackets. Your GitHub and local computer usernames may not be the same, so check which you need to use. +* There is a lot of documentation. + + * Icepack User Guide, https://cice-consortium-icepack.readthedocs.io/en/latest/index.html + * CICE-Consortium GitHub Usage Guide, https://github.com/CICE-Consortium/About-Us/wiki/Git-Workflow-Guide + * CICE and Icepack Resources, https://github.com/CICE-Consortium/About-Us/wiki/Resource-Index + + +Github One-time Configuration +---------------------------------- + +You need to have your own GitHub account before you can start the following activities, and you should have already forked the Icepack repository. +For information about how to set up a GitHub account for the Icepack repository, see the Consortium documentation here, https://github.com/CICE-Consortium/About-Us/wiki/Git-Workflow-Guide. The Consortium recommends that you keep your fork’s main branch in sync with the Consortium version and that you always work on branches. This is all documented in the Git-Workflow-Guide linked above. + +Note: + +* The workflow guide is oriented toward setting up CICE rather than Icepack, but the same workflow applies to Icepack standalone. Icepack can be set up and run as an independent model following the same workflow. + + +Clone Icepack +------------------- + +Clone your Icepack repository fork (use the URL from your fork) to a local sandbox:: + + mkdir ~/icepack-dirs + cd ~/icepack-dirs + git clone https://github.com//Icepack + +If you have completed this correctly there should be an “Icepack” directory in the icepack-dirs directory. This is the “sandbox” we will be working in locally on your machine. + +Move to the Icepack directory and check which branch you are using. This should be main:: + + cd Icepack + git status + +Take a minute to orient yourself to the big picture structure of the directories and files in Icepack. The documentation has information about the Icepack :ref:`dirstructure`. + +Make sure your main is up to date and create a branch. You can also update your fork directly in github by clicking the Sync fork button. If your code is already up to date, you can skip this step:: + + git remote --v (Check the origin and NO upstream) + git remote add upstream https://github.com/CICE-Consortium/Icepack + git remote --v (Check upstream has been added) + git pull upstream main + git push origin main + git branch + git checkout + + +Conda and Laptop One-time Configuration +------------------------------------------ + +To build and run Icepack on your laptop, you need to install software via conda. Instructions on how to do that can be found in the Icepack user guide, :ref:`laptops`. If you have a Windows machine, we recommend using the Ubuntu Linux application, https://ubuntu.com/desktop/wsl. Make sure to follow the instructions for installing miniconda. If your laptop has a conda environment already installed, you will still need to activate the icepack environment, and you may need to do so using the recommended miniconda distribution. Return here after completing section :ref:`laptops` in the documentation. After installing miniconda, the main steps are:: + + cd ~/icepack-dirs/Icepack + conda env create -f configuration/scripts/machines/environment.yml + conda activate icepack + +Before you can run Icepack, you have to set up a directory structure and download the input and forcing datasets:: + + mkdir -p ~/icepack-dirs/runs ~/icepack-dirs/input ~/icepack-dirs/baseline + cd ~/icepack-dirs/input + curl -O https://zenodo.org/records/3728287/files/Icepack_data-20200326.tar.gz + tar -xzf Icepack_data-20200326.tar.gz + +You can also run Icepack on an external machine that is supported by the Consortium or to which you have ported the code. In this case, you do not need to port to your laptop. + + +Set Up an Icepack Simulation +----------------------------- + +Use the online Icepack documentation and in particular the :ref:`quickstart` and :ref:`running_icepack` sections as guidance and for details on the command line settings:: + + cd ~/icepack-dirs + mkdir cases + cd ~/Icepack + ./icepack.setup --case ~/icepack-dirs/cases/icepack_test0 --mach --env + +Notes: + +* If you are doing this in the conda environment, the machine is “conda”. +* Similarly, the variable is set to the compiler on your machine. For the conda environment, this is “macos” or “linux”. + +The setup script creates a case consistent with the machine and other defined settings under ~/icepack-dirs/cases/ with the name you selected (icepack_test0). The case directory will contain build and run scripts, a namelist file, and other necessary files. Once the case is set up any of these files can be manually edited to refine the desired configuration. + +Move to the new case directory and examine the settings:: + + cd ~/icepack-dirs/cases/icepack_test0 + +Open the **icepack.settings** file and look at it briefly. Note the ICE_CASEDIR (it should match this directory) and the ICE_RUNDIR (where the model will be run and output created). Now look at the default namelist settings in **icepack_in**. + +Build the code:: + + ./icepack.build + +The build script basically runs gmake under the covers, but there are a number of other tasks that are handled by the script to make the build more robust. If the build is successful you will see the message “COMPILE SUCCESSFUL” at the bottom of the screen. You can also check the README.case file to check the status. + +Submit the job. The submit script just submits the run scripts. Look at both **icepack.run** and **icepack.submit** files to see more details. The out-of-the-box run has default settings for the physics and other options. You can have a look at **icepack_in** and **icepack.settings** to review those settings. Then:: + + ./icepack.submit + +If the run is successful, you will see the message “ICEPACK COMPLETED SUCCESSFULLY” in the icepack run log file. Note that this job runs quickly - you are running a column model with four grid cells! + +Look at the output! Go to the ICE_RUNDIR where output was created. A successful model integration will create ice_diag.* files and a file in the “restart” directory called “iced.2016-01-01-00000”. The Icepack documentation has more information about :ref:`history`. + +Follow the documentation to create some plots of the output using the tools provided with Icepack (:ref:`testplotting`). The conda icepack environment must be activated, if it isn’t already:: + + cd ~/icepack-dirs/Icepack/configuration/scripts/tests/ + conda activate icepack + ./timeseries.csh ~/icepack-dirs/runs/icepack_test0/ice_diag.full_ITD + +Note that you can run the plotting script on any of the four ice_diag.* files. The .png files are created in the ICE_RUNDIR directory. Open the files:: + + cd ~/icepack-dirs/runs/icepack_test0/ + open .png + +Or use your file browser to navigate to the directory and double click on the images. + +Questions to think about while looking at the output. + +* What time period does an out-of-the-box run cover? +* What are the differences between the full_ITD plots and the icefree plots (or any other combination of the ice_diag.* output files)? Which fields are the same? Which are different? Why would this be? +* What happens to ice area and ice thickness around October 1, 2015? Why do you see this signal? +* How does your output compare to the sample output provided for this release? (hint: see the wiki!) + +Take a step back and think about all the directories and files you have created. The Icepack “sandbox” was cloned from GitHub and has the actual Icepack code. + +* There is a particular case directory for building and launching the code, and some output (e.g. job log) are copied. +* There is a particular run directory for each case. This is where the model is run and big files are found. + + +Set Up a Longer Run +--------------------- + +Once you have had success with the previous step, you can run another, longer experiment to practice some basic changes for Icepack. Go back to your Icepack directory:: + + cd ~/icepack-dirs/Icepack/ + +You need to set up a new out-of-the-box case (icepack_test1):: + + ./icepack.setup --case ~/icepack-dirs/cases/icepack_test1 --mach --env + +Go into the cases/icepack_test1 directory, and build the case. +Change the following namelist settings in **icepack_in**, + + npt = 8760 + +How long is this setting the model to run? Change this to run for 10 years (hint: The timestep is one hour, and there are 24 steps per day, and 365 days per year). + +Details about namelist options are in the documentation (:ref:`case_settings`). + +Submit the job. Check the output and think about the following: + +* Over what dates did the model run this time? +* What date would the model restart from? + + +Modify a physics option +--------------------------- + +Set up another case:: + + ./icepack.setup --case ~/icepack-dirs/cases/icepack_test2 --mach --env + +Build the code. + +Change the thermodynamics option from ktherm = 2 to ktherm = 1 in **icepack_in**, and set sw_redist = .true. The intent here is to change the namelist option for the current experiment in the case directory. Think about what would happen if you changed **icepack_in** in the source code before creating the case instead (hint: this experiment should work the same, but what about future experiments?). + +Submit the job. Have a look at the output. + +* What is different compared to your first run? +* What happens if sw_redist = .false. with ktherm = 1? Why? + + +Change a Parameter in the Fortran Code +----------------------------------------- + +Set up another case:: + + ./icepack.setup --case ~/icepack-dirs/cases/icepack_test3 --mach --env + +Change to the source code directory:: + + cd columnphysics + +Edit icepack_mechred.F90 to change the line + + fsnowrdg = p5 , & ! snow fraction that survives in ridging + +to + + fsnowrdg = c1 , & ! snow fraction that survives in ridging + +Build the code and submit the job. + +* What is different about this run? +* What do you think the fsnowrdg parameter is doing here? + +Revert your code changes:: + + cd ~/Icepack + git status + git checkout columnphysics/icepack_mechred.F90 + git status + diff --git a/doc/source/index.rst b/doc/source/index.rst index ee714eb79..5788fbe18 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -16,7 +16,7 @@ Icepack Documentation user_guide/index_standalone.rst user_guide/index_withmodels.rst developer_guide/index.rst - icepack_index.rst + appendices/index.rst zreferences.rst * :ref:`search` From 2fd2140154379aedab8bf56b90bc4f6e2a38226f Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Tue, 14 May 2024 08:40:15 -0700 Subject: [PATCH 18/30] Update version to Icepack 1.4.1 (#486) Update Copyright to 2024 in code and LICENSE file --- LICENSE.pdf | Bin 55036 -> 55309 bytes columnphysics/icepack_intfc.F90 | 4 ++-- columnphysics/version.txt | 2 +- doc/source/conf.py | 6 +++--- doc/source/intro/copyright.rst | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/LICENSE.pdf b/LICENSE.pdf index 80ae31d5183808e151adbeca14f21d7b66e4761a..18e26a09961123cc71743b11a8c7c894bf3eaf13 100644 GIT binary patch delta 40337 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 delta 39985 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 PVXzn$3ky_35$pc}gCu9b diff --git a/columnphysics/icepack_intfc.F90 b/columnphysics/icepack_intfc.F90 index 0d8be0b31..2f8b648b3 100644 --- a/columnphysics/icepack_intfc.F90 +++ b/columnphysics/icepack_intfc.F90 @@ -1,8 +1,8 @@ !======================================================================= -! Copyright (c) 2023, Triad National Security, LLC +! Copyright (c) 2024, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2023. Triad National Security, LLC. This software was +! Copyright 2024. Triad National Security, LLC. This software was ! produced under U.S. Government contract DE-AC52-06NA25396 for Los ! Alamos National Laboratory (LANL), which is operated by Triad ! National Security, LLC for the U.S. Department of Energy. The U.S. diff --git a/columnphysics/version.txt b/columnphysics/version.txt index 760fc61f7..7efd5d798 100644 --- a/columnphysics/version.txt +++ b/columnphysics/version.txt @@ -1 +1 @@ -ICEPACK 1.4.0 +ICEPACK 1.4.1 diff --git a/doc/source/conf.py b/doc/source/conf.py index 48648d1a5..e9d2e3ef7 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -54,7 +54,7 @@ # General information about the project. project = u'Icepack' -copyright = u'2023, Triad National Security, LLC (code) and National Center for Atmospheric Research (documentation)' +copyright = u'2024, Triad National Security, LLC (code) and National Center for Atmospheric Research (documentation)' author = u'CICE-Consortium' # The version info for the project you're documenting, acts as replacement for @@ -62,9 +62,9 @@ # built documents. # # The short X.Y version. -version = u'1.4.0' +version = u'1.4.1' # The full version, including alpha/beta/rc tags. -version = u'1.4.0' +version = u'1.4.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/intro/copyright.rst b/doc/source/intro/copyright.rst index e477d9d57..8ddeef022 100755 --- a/doc/source/intro/copyright.rst +++ b/doc/source/intro/copyright.rst @@ -5,7 +5,7 @@ Copyright ============================= -© Copyright 2023, Triad National Security LLC. All rights reserved. +© Copyright 2024, Triad National Security LLC. All rights reserved. This software was produced under U.S. Government contract 89233218CNA000001 for Los Alamos National Laboratory (LANL), which is operated by Triad National Security, LLC for the U.S. Department From ae69b806990ef2412e2f714c5b4ba4c096b163b6 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Tue, 14 May 2024 11:15:56 -0700 Subject: [PATCH 19/30] Update one more copyright date (#487) --- configuration/driver/icedrv_MAIN.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configuration/driver/icedrv_MAIN.F90 b/configuration/driver/icedrv_MAIN.F90 index 5c84695f2..8d76f63ca 100644 --- a/configuration/driver/icedrv_MAIN.F90 +++ b/configuration/driver/icedrv_MAIN.F90 @@ -1,8 +1,8 @@ !======================================================================= -! Copyright (c) 2023, Triad National Security, LLC +! Copyright (c) 2024, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2023. Triad National Security, LLC. This software was +! Copyright 2024. Triad National Security, LLC. This software was ! produced under U.S. Government contract DE-AC52-06NA25396 for Los ! Alamos National Laboratory (LANL), which is operated by Triad ! National Security, LLC for the U.S. Department of Energy. The U.S. From 083d6e3cf42198bc7b4ffd1f02063c4c5b35b639 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Tue, 28 May 2024 09:21:19 -0700 Subject: [PATCH 20/30] Update gnuplot, improve titles and fonts (#490) Add run_testoutput script to generate release plots for Icepack --- configuration/scripts/tests/run_testoutput.csh | 14 ++++++++++++++ configuration/scripts/tests/timeseries.csh | 13 +++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 configuration/scripts/tests/run_testoutput.csh diff --git a/configuration/scripts/tests/run_testoutput.csh b/configuration/scripts/tests/run_testoutput.csh new file mode 100644 index 000000000..cbb2a91ec --- /dev/null +++ b/configuration/scripts/tests/run_testoutput.csh @@ -0,0 +1,14 @@ +#/bin/csh -f + +./icepack.setup -m conda -e macos --case basecase -s diag1,run1year +cd basecase +./icepack.build +./icepack.submit +cd logs +foreach file (ice*[0-9]) + cp ${file} ${file}.txt +end +conda activate icepack +../../configuration/scripts/tests/timeseries.csh ice_diag.full_ITD.*[0-9] + +echo "run_testoutput DONE" diff --git a/configuration/scripts/tests/timeseries.csh b/configuration/scripts/tests/timeseries.csh index 75faa81a6..459c905b8 100755 --- a/configuration/scripts/tests/timeseries.csh +++ b/configuration/scripts/tests/timeseries.csh @@ -71,9 +71,10 @@ foreach field ($fieldlist:q) endif set output = `echo $fieldname | sed 's/ /_/g'` - set casename = `echo $basename | rev | cut -d / -f 1-2 | rev | sed 's/\//, /'` - set fname_base = "${casename}_${output}" + set logfileonly = `echo $basename | rev | cut -d / -f 1 | rev` + set title = "${logfileonly}" set output_fname = "${basename}_${output}.png" + rm ${output_fname} echo "Plotting data for '$fieldname' and saving to $output_fname" @@ -85,7 +86,7 @@ set style data points set datafile separator "," # Term type and background color, canvas size -set terminal png size 1920,960 +set terminal png size 1920,960 font "default,20" # x-axis set xdata time @@ -95,9 +96,9 @@ set format x "%Y/%m/%d" # Axis tick marks set xtics rotate -set title "$fname_base" -set ylabel "$field" -set xlabel "Simulation Day" +set title "$title" noenhanced font "default,30" +set ylabel "$field" font "default,30" +set xlabel "Simulation Day" font "default,30" # Set y-axis limits $yrange From 1a820b45cc37d71fa62e508e5bb1470b4203ce91 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Mon, 29 Jul 2024 12:31:24 -0700 Subject: [PATCH 21/30] Update documentation for adding a tracer and the tutorial (#493) Documentation is being update based on the Consortium workshop in 2024. The "adding a tracer" section has been updated as has the tutorial section related to adding a fluff tracer. An example set of code diffs for the tutorial is also includes as reference. --- doc/source/appendices/fluff.diff | 975 ++++++++++++++++++ doc/source/appendices/tutorial.rst | 244 ++--- .../developer_guide/dg_adding_tracers.rst | 147 ++- 3 files changed, 1177 insertions(+), 189 deletions(-) create mode 100644 doc/source/appendices/fluff.diff diff --git a/doc/source/appendices/fluff.diff b/doc/source/appendices/fluff.diff new file mode 100644 index 000000000..03f745b74 --- /dev/null +++ b/doc/source/appendices/fluff.diff @@ -0,0 +1,975 @@ +diff --git a/columnphysics/icepack_fluff.F90 b/columnphysics/icepack_fluff.F90 +new file mode 100644 +index 0000000..f938ea8 +--- /dev/null ++++ b/columnphysics/icepack_fluff.F90 +@@ -0,0 +1,52 @@ ++!======================================================================= ++ ++ module icepack_fluff ++ ++ use icepack_kinds ++ use icepack_parameters, only: puny ++ use icepack_warnings, only: warnstr, icepack_warnings_add ++ use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted ++ ++ implicit none ++ ++ private ++ public :: update_fluff ++ ++!======================================================================= ++ ++ contains ++ ++!======================================================================= ++ ++! Increase ice fluffball tracer ++ ++ subroutine update_fluff (dt, rfluff, fatm, focn, aicen) ++ ++ real (kind=dbl_kind), intent(in) :: & ++ dt ! time step (s) ++ ++ real (kind=dbl_kind), intent(in) :: & ++ aicen, & ! ice area (m2) ++ fatm, & ! atm forcing (kg/m2/s) ++ focn ! ocn forcing (kg/m2/s) ++ ++ real (kind=dbl_kind), intent(inout) :: & ++ rfluff ! fluff tracer (kg) ++ ++ character(len=*),parameter :: subname='(update_fluff)' ++ ++ if (aicen > puny) then ++ rfluff = rfluff + fatm*aicen*dt ! atm forcing ++ rfluff = rfluff + focn*aicen*dt ! ocn forcing ++ endif ++! rfluff = rfluff + dt/86400._dbl_kind ! by timestep ++! other physics ... ++! rfluff = ... ++ ++ end subroutine update_fluff ++ ++!======================================================================= ++ ++ end module icepack_fluff ++ ++!======================================================================= +diff --git a/columnphysics/icepack_therm_vertical.F90 b/columnphysics/icepack_therm_vertical.F90 +index 7cd9f25..e231e8f 100644 +--- a/columnphysics/icepack_therm_vertical.F90 ++++ b/columnphysics/icepack_therm_vertical.F90 +@@ -31,7 +31,7 @@ module icepack_therm_vertical + use icepack_parameters, only: icepack_chkoptargflag + + use icepack_tracers, only: tr_iage, tr_FY, tr_aero, tr_pond, tr_fsd, tr_iso +- use icepack_tracers, only: tr_pond_lvl, tr_pond_topo ++ use icepack_tracers, only: tr_pond_lvl, tr_pond_topo, tr_fluff + use icepack_tracers, only: n_aero, n_iso + + use icepack_therm_shared, only: ferrmax, l_brine +@@ -51,6 +51,7 @@ module icepack_therm_vertical + use icepack_isotope, only: update_isotope + use icepack_atmo, only: neutral_drag_coeffs, icepack_atm_boundary + use icepack_age, only: increment_age ++ use icepack_fluff, only: update_fluff + use icepack_firstyear, only: update_FYarea + use icepack_flux, only: set_sfcflux, merge_fluxes + use icepack_meltpond_lvl, only: compute_ponds_lvl +@@ -2081,7 +2082,7 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + zqin , zSin , & + alvl , vlvl , & + apnd , hpnd , & +- ipnd , & ++ ipnd , fluff , & + iage , FY , & + aerosno , aeroice , & + isosno , isoice , & +@@ -2142,6 +2143,7 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + faero_atm , faero_ocn , & + fiso_atm , fiso_ocn , & + fiso_evap , & ++ ffluff_atm , ffluff_ocn , & + HDO_ocn , H2_16O_ocn , & + H2_18O_ocn , & + dhsn , ffracn , & +@@ -2266,6 +2268,7 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + meltsliq ! mass of snow melt (kg/m^2) + + real (kind=dbl_kind), dimension(:), intent(inout), optional :: & ++ fluff , & ! fluffballs + Qa_iso , & ! isotope specific humidity (kg/kg) + Qref_iso , & ! isotope 2m atm ref spec humidity (kg/kg) + fiso_atm , & ! isotope deposition rate (kg/m^2 s) +@@ -2281,6 +2284,8 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + smliqn ! tracer for mass of liq in snow (kg/m^3) + + real (kind=dbl_kind), intent(in), optional :: & ++ ffluff_atm , & ! fluff atm forcing (kg/m^2 s) ++ ffluff_ocn , & ! fluff ocn forcing (kg/m^2/s) + HDO_ocn , & ! ocean concentration of HDO (kg/kg) + H2_16O_ocn , & ! ocean concentration of H2_16O (kg/kg) + H2_18O_ocn , & ! ocean concentration of H2_18O (kg/kg) +@@ -2451,6 +2456,14 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + return + endif + endif ++ if (tr_fluff) then ++ if (.not.(present(fluff) .and. present(ffluff_atm) .and. & ++ present(ffluff_ocn))) then ++ call icepack_warnings_add(subname//' error in fluff arguments, tr_fluff=T') ++ call icepack_warnings_setabort(.true.,__FILE__,__LINE__) ++ return ++ endif ++ endif + endif + + !----------------------------------------------------------------- +@@ -2615,6 +2628,17 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + yday, FY(n)) + if (icepack_warnings_aborted(subname)) return + ++ !----------------------------------------------------------------- ++ ! Update ice fluffballs ++ !----------------------------------------------------------------- ++ ++ if (tr_fluff) call update_fluff (dt = dt, & ++ rfluff = fluff(n), & ++ fatm = ffluff_atm, & ++ focn = ffluff_ocn, & ++ aicen = aicen(n)) ++ if (icepack_warnings_aborted(subname)) return ++ + !----------------------------------------------------------------- + ! Vertical thermodynamics: Heat conduction, growth and melting. + !----------------------------------------------------------------- +diff --git a/columnphysics/icepack_tracers.F90 b/columnphysics/icepack_tracers.F90 +index 8414e0c..84e4981 100644 +--- a/columnphysics/icepack_tracers.F90 ++++ b/columnphysics/icepack_tracers.F90 +@@ -58,6 +58,7 @@ module icepack_tracers + nblyr = 0, & ! number of bio/brine layers per category + nfsd = 0, & ! number of fsd layers + n_iso = 0, & ! number of isotopes in use ++ n_fluff = 0, & ! number of fluffballs in use + n_aero = 0, & ! number of aerosols in use + n_zaero = 0, & ! number of z aerosols in use + n_algae = 0, & ! number of algae in use +@@ -87,6 +88,7 @@ module icepack_tracers + nt_rsnw = 0, & ! snow grain radius + nt_isosno = 0, & ! starting index for isotopes in snow + nt_isoice = 0, & ! starting index for isotopes in ice ++ nt_fluff = 0, & ! starting index for fluffballs + nt_aero = 0, & ! starting index for aerosols in ice + nt_bgc_Nit = 0, & ! nutrients + nt_bgc_Am = 0, & ! +@@ -110,6 +112,7 @@ module icepack_tracers + tr_iso = .false., & ! if .true., use isotope tracers + tr_aero = .false., & ! if .true., use aerosol tracers + tr_brine = .false., & ! if .true., brine height differs from ice thickness ++ tr_fluff = .false., & ! if .true., use fluffballs + tr_fsd = .false. ! if .true., use floe size distribution + + !----------------------------------------------------------------- +@@ -207,7 +210,7 @@ module icepack_tracers + + subroutine icepack_init_tracer_flags(& + tr_iage_in, tr_FY_in, tr_lvl_in, tr_snow_in, & +- tr_pond_in, tr_pond_lvl_in, tr_pond_topo_in, & ++ tr_pond_in, tr_pond_lvl_in, tr_pond_topo_in, tr_fluff_in, & + 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, & +@@ -223,6 +226,7 @@ subroutine icepack_init_tracer_flags(& + tr_snow_in , & ! if .true., use snow redistribution or metamorphosis tracers + tr_fsd_in , & ! if .true., use floe size distribution tracers + tr_iso_in , & ! if .true., use isotope tracers ++ tr_fluff_in , & ! if .true., use fluffball tracers + tr_aero_in , & ! if .true., use aerosol tracers + tr_brine_in , & ! if .true., brine height differs from ice thickness + tr_zaero_in , & ! if .true., black carbon is tracers (n_zaero) +@@ -251,6 +255,7 @@ subroutine icepack_init_tracer_flags(& + if (present(tr_snow_in) ) tr_snow = tr_snow_in + if (present(tr_fsd_in) ) tr_fsd = tr_fsd_in + if (present(tr_iso_in) ) tr_iso = tr_iso_in ++ if (present(tr_fluff_in) ) tr_fluff = tr_fluff_in + if (present(tr_aero_in) ) tr_aero = tr_aero_in + if (present(tr_brine_in) ) tr_brine = tr_brine_in + if (present(tr_zaero_in) ) tr_zaero = tr_zaero_in +@@ -274,7 +279,7 @@ end subroutine icepack_init_tracer_flags + + subroutine icepack_query_tracer_flags(& + tr_iage_out, tr_FY_out, tr_lvl_out, tr_snow_out, & +- tr_pond_out, tr_pond_lvl_out, tr_pond_topo_out, & ++ tr_pond_out, tr_pond_lvl_out, tr_pond_topo_out, tr_fluff_out, & + 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, & +@@ -290,6 +295,7 @@ subroutine icepack_query_tracer_flags(& + tr_snow_out , & ! if .true., use snow redistribution or metamorphosis tracers + tr_fsd_out , & ! if .true., use floe size distribution + tr_iso_out , & ! if .true., use isotope tracers ++ tr_fluff_out , & ! if .true., use fluffball tracers + tr_aero_out , & ! if .true., use aerosol tracers + tr_brine_out , & ! if .true., brine height differs from ice thickness + tr_zaero_out , & ! if .true., black carbon is tracers (n_zaero) +@@ -318,6 +324,7 @@ subroutine icepack_query_tracer_flags(& + if (present(tr_snow_out) ) tr_snow_out = tr_snow + if (present(tr_fsd_out) ) tr_fsd_out = tr_fsd + if (present(tr_iso_out) ) tr_iso_out = tr_iso ++ if (present(tr_fluff_out) ) tr_fluff_out = tr_fluff + if (present(tr_aero_out) ) tr_aero_out = tr_aero + if (present(tr_brine_out) ) tr_brine_out = tr_brine + if (present(tr_zaero_out) ) tr_zaero_out = tr_zaero +@@ -357,6 +364,7 @@ subroutine icepack_write_tracer_flags(iounit) + write(iounit,*) " tr_snow = ",tr_snow + write(iounit,*) " tr_fsd = ",tr_fsd + write(iounit,*) " tr_iso = ",tr_iso ++ write(iounit,*) " tr_fluff = ",tr_fluff + write(iounit,*) " tr_aero = ",tr_aero + write(iounit,*) " tr_brine = ",tr_brine + write(iounit,*) " tr_zaero = ",tr_zaero +@@ -383,7 +391,7 @@ subroutine icepack_init_tracer_indices(& + 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_fsd_in, nt_isosno_in, nt_isoice_in, nt_fluff_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, & + nt_bgc_DIC_in, nt_bgc_Fed_in, nt_bgc_Fep_in, nt_bgc_Nit_in, nt_bgc_Am_in, & +@@ -416,6 +424,7 @@ subroutine icepack_init_tracer_indices(& + nt_fsd_in, & ! floe size distribution + nt_isosno_in, & ! starting index for isotopes in snow + nt_isoice_in, & ! starting index for isotopes in ice ++ nt_fluff_in, & ! starting index for fluffballs + nt_aero_in, & ! starting index for aerosols in ice + nt_bgc_Nit_in, & ! nutrients + nt_bgc_Am_in, & ! +@@ -497,6 +506,7 @@ subroutine icepack_init_tracer_indices(& + if (present(nt_rsnw_in) ) nt_rsnw = nt_rsnw_in + if (present(nt_isosno_in) ) nt_isosno = nt_isosno_in + if (present(nt_isoice_in) ) nt_isoice = nt_isoice_in ++ if (present(nt_fluff_in) ) nt_fluff = nt_fluff_in + if (present(nt_aero_in) ) nt_aero = nt_aero_in + if (present(nt_bgc_Nit_in) ) nt_bgc_Nit = nt_bgc_Nit_in + if (present(nt_bgc_Am_in) ) nt_bgc_Am = nt_bgc_Am_in +@@ -745,7 +755,7 @@ subroutine icepack_query_tracer_indices(& + 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_fsd_out, nt_isosno_out, nt_isoice_out, nt_fluff_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, & + nt_bgc_DIC_out, nt_bgc_Fed_out, nt_bgc_Fep_out, nt_bgc_Nit_out, nt_bgc_Am_out, & +@@ -778,6 +788,7 @@ subroutine icepack_query_tracer_indices(& + nt_fsd_out, & ! floe size distribution + nt_isosno_out, & ! starting index for isotopes in snow + nt_isoice_out, & ! starting index for isotopes in ice ++ nt_fluff_out, & ! starting index for fluffballs + nt_aero_out, & ! starting index for aerosols in ice + nt_bgc_Nit_out, & ! nutrients + nt_bgc_Am_out, & ! +@@ -857,6 +868,7 @@ subroutine icepack_query_tracer_indices(& + if (present(nt_rsnw_out) ) nt_rsnw_out = nt_rsnw + if (present(nt_isosno_out) ) nt_isosno_out = nt_isosno + if (present(nt_isoice_out) ) nt_isoice_out = nt_isoice ++ if (present(nt_fluff_out) ) nt_fluff_out = nt_fluff + if (present(nt_aero_out) ) nt_aero_out = nt_aero + if (present(nt_bgc_Nit_out) ) nt_bgc_Nit_out = nt_bgc_Nit + if (present(nt_bgc_Am_out) ) nt_bgc_Am_out = nt_bgc_Am +@@ -936,6 +948,7 @@ subroutine icepack_write_tracer_indices(iounit) + write(iounit,*) " nt_rsnw = ",nt_rsnw + write(iounit,*) " nt_isosno = ",nt_isosno + write(iounit,*) " nt_isoice = ",nt_isoice ++ write(iounit,*) " nt_fluff = ",nt_fluff + write(iounit,*) " nt_aero = ",nt_aero + write(iounit,*) " nt_bgc_Nit = ",nt_bgc_Nit + write(iounit,*) " nt_bgc_Am = ",nt_bgc_Am +@@ -1014,7 +1027,7 @@ end subroutine icepack_write_tracer_indices + + subroutine icepack_init_tracer_sizes(& + ncat_in, nilyr_in, nslyr_in, nblyr_in, nfsd_in , & +- n_algae_in, n_DOC_in, n_aero_in, n_iso_in, & ++ n_algae_in, n_DOC_in, n_aero_in, n_iso_in, n_fluff_in, & + n_DON_in, n_DIC_in, n_fed_in, n_fep_in, n_zaero_in, & + ntrcr_in, ntrcr_o_in, nbtrcr_in, nbtrcr_sw_in) + +@@ -1032,6 +1045,7 @@ subroutine icepack_init_tracer_sizes(& + n_fep_in , & ! + n_zaero_in, & ! + n_iso_in , & ! ++ n_fluff_in, & ! + n_aero_in , & ! + ntrcr_in , & ! number of tracers in use + ntrcr_o_in, & ! number of non-bio tracers in use +@@ -1056,6 +1070,7 @@ subroutine icepack_init_tracer_sizes(& + if (present(n_fep_in) ) n_fep = n_fep_in + if (present(n_zaero_in) ) n_zaero = n_zaero_in + if (present(n_iso_in) ) n_iso = n_iso_in ++ if (present(n_fluff_in) ) n_fluff = n_fluff_in + if (present(n_aero_in) ) n_aero = n_aero_in + + if (present(ntrcr_in) ) ntrcr = ntrcr_in +@@ -1074,7 +1089,7 @@ subroutine icepack_query_tracer_sizes(& + max_don_out , max_fe_out , nmodal1_out , & + nmodal2_out , max_aero_out , max_nbtrcr_out , & + ncat_out, nilyr_out, nslyr_out, nblyr_out, nfsd_out, & +- n_algae_out, n_DOC_out, n_aero_out, n_iso_out, & ++ n_algae_out, n_DOC_out, n_aero_out, n_iso_out, n_fluff_out, & + n_DON_out, n_DIC_out, n_fed_out, n_fep_out, n_zaero_out, & + ntrcr_out, ntrcr_o_out, nbtrcr_out, nbtrcr_sw_out) + +@@ -1103,6 +1118,7 @@ subroutine icepack_query_tracer_sizes(& + n_fep_out , & ! + n_zaero_out, & ! + n_iso_out , & ! ++ n_fluff_out, & ! + n_aero_out , & ! + ntrcr_out , & ! number of tracers in use + ntrcr_o_out, & ! number of non-bio tracers in use +@@ -1138,6 +1154,7 @@ subroutine icepack_query_tracer_sizes(& + if (present(n_zaero_out) ) n_zaero_out = n_zaero + if (present(n_aero_out) ) n_aero_out = n_aero + if (present(n_iso_out) ) n_iso_out = n_iso ++ if (present(n_fluff_out) ) n_fluff_out = n_fluff + + if (present(ntrcr_out) ) ntrcr_out = ntrcr + if (present(ntrcr_o_out) ) ntrcr_o_out = ntrcr_o +@@ -1186,6 +1203,7 @@ subroutine icepack_write_tracer_sizes(iounit) + write(iounit,*) " n_zaero = ",n_zaero + write(iounit,*) " n_aero = ",n_aero + write(iounit,*) " n_iso = ",n_iso ++ write(iounit,*) " n_fluff = ",n_fluff + write(iounit,*) " ntrcr = ",ntrcr + write(iounit,*) " ntrcr_o = ",ntrcr_o + write(iounit,*) " nbtrcr = ",nbtrcr +diff --git a/configuration/driver/icedrv_InitMod.F90 b/configuration/driver/icedrv_InitMod.F90 +index 107ffdc..8a34f61 100644 +--- a/configuration/driver/icedrv_InitMod.F90 ++++ b/configuration/driver/icedrv_InitMod.F90 +@@ -44,7 +44,8 @@ subroutine icedrv_initialize + use icedrv_flux, only: init_coupler_flux, init_history_therm, & + init_flux_atm_ocn + use icedrv_forcing, only: init_forcing, get_forcing, get_wave_spec +- use icedrv_forcing_bgc, only: get_forcing_bgc, faero_default, fiso_default, init_forcing_bgc ++ use icedrv_forcing_bgc, only: get_forcing_bgc, faero_default, fiso_default, & ++ init_forcing_bgc, ffluff_default + use icedrv_restart_shared, only: restart + use icedrv_init, only: input_data, init_state, init_grid2, init_fsd + use icedrv_init_column, only: init_thermo_vertical, init_shortwave, init_zbgc +@@ -56,6 +57,7 @@ subroutine icedrv_initialize + tr_snow, & ! from icepack + tr_aero, & ! from icepack + tr_iso, & ! from icepack ++ tr_fluff, & ! from icepack + tr_zaero, & ! from icepack + tr_fsd, wave_spec + +@@ -135,7 +137,7 @@ subroutine icedrv_initialize + call icepack_query_parameters(wave_spec_out=wave_spec) + call icepack_query_tracer_flags(tr_snow_out=tr_snow) + call icepack_query_tracer_flags(tr_aero_out=tr_aero) +- call icepack_query_tracer_flags(tr_iso_out=tr_iso) ++ call icepack_query_tracer_flags(tr_iso_out=tr_iso, tr_fluff_out=tr_fluff) + call icepack_query_tracer_flags(tr_zaero_out=tr_zaero) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & +@@ -155,6 +157,7 @@ subroutine icedrv_initialize + endif + + if (tr_iso) call fiso_default ! default values ++ if (tr_fluff) call ffluff_default ! fluffball forcing + ! aerosols + ! if (tr_aero) call faero_data ! data file + ! if (tr_zaero) call fzaero_data ! data file (gx1) +diff --git a/configuration/driver/icedrv_RunMod.F90 b/configuration/driver/icedrv_RunMod.F90 +index e20ebf8..81fd86a 100644 +--- a/configuration/driver/icedrv_RunMod.F90 ++++ b/configuration/driver/icedrv_RunMod.F90 +@@ -33,12 +33,13 @@ subroutine icedrv_run + + use icedrv_calendar, only: istep, istep1, time, dt, stop_now, calendar + use icedrv_forcing, only: get_forcing, get_wave_spec +- use icedrv_forcing_bgc, only: faero_default, fiso_default, get_forcing_bgc ++ use icedrv_forcing_bgc, only: faero_default, fiso_default, get_forcing_bgc, & ++ ffluff_default + use icedrv_flux, only: init_flux_atm_ocn + use icedrv_history, only: history_format, history_close + + logical (kind=log_kind) :: skl_bgc, z_tracers, tr_aero, tr_zaero, & +- wave_spec, tr_fsd, tr_iso ++ wave_spec, tr_fsd, tr_iso, tr_fluff + + character(len=*), parameter :: subname='(icedrv_run)' + +@@ -47,7 +48,8 @@ subroutine icedrv_run + !-------------------------------------------------------------------- + + call icepack_query_tracer_flags(tr_aero_out=tr_aero, tr_zaero_out=tr_zaero, & +- tr_fsd_out=tr_fsd, tr_iso_out=tr_iso) ++ tr_fsd_out=tr_fsd, tr_iso_out=tr_iso, & ++ tr_fluff_out=tr_fluff) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & + file=__FILE__,line= __LINE__) +@@ -78,6 +80,7 @@ subroutine icedrv_run + + ! biogeochemistry forcing + if (tr_iso) call fiso_default ! default values ++ if (tr_fluff) call ffluff_default ! fluffball forcing + if (tr_aero .or. tr_zaero) call faero_default ! default values + if (skl_bgc .or. z_tracers) call get_forcing_bgc ! biogeochemistry + +diff --git a/configuration/driver/icedrv_diagnostics.F90 b/configuration/driver/icedrv_diagnostics.F90 +index eaa44d5..cd59cde 100644 +--- a/configuration/driver/icedrv_diagnostics.F90 ++++ b/configuration/driver/icedrv_diagnostics.F90 +@@ -87,7 +87,8 @@ subroutine runtime_diags (dt) + pTair, pfsnow, pfrain, & + paice, hiavg, hsavg, hbravg, psalt, pTsfc, & + pevap, pfhocn, fsdavg, & +- rsnwavg, rhosavg, smicetot, smliqtot, smtot ++ rsnwavg, rhosavg, smicetot, smliqtot, smtot, & ++ fluffavg + + real (kind=dbl_kind), dimension (nx) :: & + work1, work2, work3 +@@ -95,9 +96,9 @@ subroutine runtime_diags (dt) + real (kind=dbl_kind) :: & + Tffresh, rhos, rhow, rhoi + +- logical (kind=log_kind) :: tr_brine, tr_fsd, tr_iso, tr_snow ++ logical (kind=log_kind) :: tr_brine, tr_fsd, tr_iso, tr_snow, tr_fluff + integer (kind=int_kind) :: nt_fbri, nt_Tsfc, nt_fsd, nt_isosno, nt_isoice +- integer (kind=int_kind) :: nt_rsnw, nt_rhos, nt_smice, nt_smliq ++ integer (kind=int_kind) :: nt_rsnw, nt_rhos, nt_smice, nt_smliq, nt_fluff + + character(len=*), parameter :: subname='(runtime_diags)' + +@@ -107,11 +108,11 @@ subroutine runtime_diags (dt) + + call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc, & + snwredist_out=snwredist, snwgrain_out=snwgrain) +- call icepack_query_tracer_flags(tr_brine_out=tr_brine, & ++ call icepack_query_tracer_flags(tr_brine_out=tr_brine, tr_fluff_out=tr_fluff, & + tr_fsd_out=tr_fsd,tr_iso_out=tr_iso,tr_snow_out=tr_snow) + call icepack_query_tracer_indices(nt_fbri_out=nt_fbri, nt_Tsfc_out=nt_Tsfc,& + nt_fsd_out=nt_fsd, nt_isosno_out=nt_isosno, nt_isoice_out=nt_isoice, & +- nt_rsnw_out=nt_rsnw, nt_rhos_out=nt_rhos, & ++ nt_rsnw_out=nt_rsnw, nt_rhos_out=nt_rhos, nt_fluff_out=nt_fluff, & + nt_smice_out=nt_smice, nt_smliq_out=nt_smliq) + call icepack_query_parameters(Tffresh_out=Tffresh, rhos_out=rhos, & + rhow_out=rhow, rhoi_out=rhoi) +@@ -138,6 +139,7 @@ subroutine runtime_diags (dt) + hbravg = c0 ! avg brine thickness + rsnwavg = c0 ! avg snow grain radius + rhosavg = c0 ! avg snow density ++ fluffavg = c0 ! fluffball avg + smicetot = c0 ! total mass of ice in snow (kg/m2) + smliqtot = c0 ! total mass of liquid in snow (kg/m2) + smtot = c0 ! total mass of snow volume (kg/m2) +@@ -172,6 +174,11 @@ subroutine runtime_diags (dt) + smicetot = smicetot / real(nslyr,kind=dbl_kind) ! mass of ice in snow + smliqtot = smliqtot / real(nslyr,kind=dbl_kind) ! mass of liquid in snow + end if ++ if (tr_fluff) then ! fluffballs ++ do nc = 1, ncat ++ fluffavg = fluffavg + trcrn(n,nt_fluff,nc)*aicen(n,nc)/paice ! fluffballs ++ end do ++ end if + + endif + if (vice(n) /= c0) psalt = work2(n)/vice(n) +@@ -252,6 +259,10 @@ subroutine runtime_diags (dt) + endif + endif + ++ if (tr_fluff) then ++ write(nu_diag_out+n-1,900) 'fluffballs (kg) = ',fluffavg ++ endif ++ + write(nu_diag_out+n-1,*) '----------ocn----------' + write(nu_diag_out+n-1,900) 'sst (C) = ',sst(n) ! sea surface temperature + write(nu_diag_out+n-1,900) 'sss (ppt) = ',sss(n) ! sea surface salinity +@@ -267,6 +278,7 @@ subroutine runtime_diags (dt) + write(nu_diag_out+n-1,901) 'isotopic conc chg = ',pdiso(n,k),k + enddo + endif ++ + end do + 899 format (43x,a24) + 900 format (a25,2x,f24.17) +diff --git a/configuration/driver/icedrv_domain_size.F90 b/configuration/driver/icedrv_domain_size.F90 +index 75bb4d2..57b9c08 100644 +--- a/configuration/driver/icedrv_domain_size.F90 ++++ b/configuration/driver/icedrv_domain_size.F90 +@@ -28,6 +28,7 @@ module icedrv_domain_size + n_don = TRDON , & ! number of DON pools in use + n_fed = TRFED , & ! number of Fe pools in use dissolved Fe + n_fep = TRFEP , & ! number of Fe pools in use particulate Fe ++ n_fluff = NFLUFF , & ! number of fluffballs + nfreq = 25 , & ! number of wave frequencies ! HARDWIRED FOR NOW + nblyr = NBGCLYR , & ! number of bio/brine layers per category + ! maximum number of biology tracers + aerosols +@@ -43,6 +44,7 @@ module icedrv_domain_size + + nslyr & ! snow enthalpy + !!!!! optional tracers: + + nfsd & ! number of floe size categories ++ + n_fluff & ! number of fluffball tracers + + TRAGE & ! age + + TRFY & ! first-year area + + TRLVL*2 & ! level/deformed ice +diff --git a/configuration/driver/icedrv_flux.F90 b/configuration/driver/icedrv_flux.F90 +index 39c0908..8e32ec0 100644 +--- a/configuration/driver/icedrv_flux.F90 ++++ b/configuration/driver/icedrv_flux.F90 +@@ -299,6 +299,10 @@ module icedrv_flux + fiso_atm , & ! isotope deposition rate (kg/m^2 s) + fiso_evap ! isotope evaporation rate (kg/m^2 s) + ++ real (kind=dbl_kind), dimension(nx), public :: & ! coupling variable for tr_fluff ++ ffluff_atm, & ! fluffball source from atm (kg/m^2 s) ++ ffluff_ocn ! fluffball source from ocn (kg/m^2 s) ++ + real (kind=dbl_kind), & + dimension (nx,icepack_max_nbtrcr), public :: & + flux_bio_atm ! all bio fluxes to ice from atmosphere +@@ -476,6 +480,8 @@ subroutine init_coupler_flux + + fiso_atm (:,:) = c0 ! isotope deposition rate (kg/m2/s) + fiso_evap (:,:) = c0 ! isotope evaporation rate (kg/m2/s) ++ ffluff_atm (:) = c0 ! fluffball forcing from atm (kg/m2/s) ++ ffluff_ocn (:) = c0 ! fluffball forcing from ocean (kg/m2/s) + faero_atm (:,:) = c0 ! aerosol deposition rate (kg/m2/s) + flux_bio_atm (:,:) = c0 ! zaero and bio deposition rate (kg/m2/s) + +diff --git a/configuration/driver/icedrv_forcing_bgc.F90 b/configuration/driver/icedrv_forcing_bgc.F90 +index f471022..70eacbe 100644 +--- a/configuration/driver/icedrv_forcing_bgc.F90 ++++ b/configuration/driver/icedrv_forcing_bgc.F90 +@@ -10,7 +10,7 @@ module icedrv_forcing_bgc + use icedrv_kinds + use icedrv_domain_size, only: nx + use icedrv_calendar, only: secday +- use icedrv_constants, only: nu_forcing, nu_diag ++ use icedrv_constants, only: nu_forcing, nu_diag, c0 + use icepack_intfc, only: icepack_max_algae, icepack_max_doc + use icepack_intfc, only: icepack_max_dic + use icepack_intfc, only: icepack_query_tracer_flags +@@ -19,7 +19,8 @@ module icedrv_forcing_bgc + + implicit none + private +- public :: get_forcing_bgc, faero_default, fiso_default, init_forcing_bgc ++ public :: get_forcing_bgc, faero_default, fiso_default, init_forcing_bgc, & ++ ffluff_default + + real (kind=dbl_kind), dimension(365) :: & ! hardwired for now + sil_data, nit_data +@@ -182,6 +183,21 @@ subroutine fiso_default + + end subroutine fiso_default + ++!======================================================================= ++ ++! constant values for atmospheric and ocean fluffballs ++ ++ subroutine ffluff_default ++ ++ use icedrv_flux, only: ffluff_atm, ffluff_ocn ++ character(len=*), parameter :: subname='(ffluff_default)' ++ ++! ffluff_atm(:) = c0 ! kg/m^2 s ++ ffluff_atm(:) = 1.e-8_dbl_kind ! kg/m^2 s ++ ffluff_ocn(:) = c0 ! kg/m^2 s ++ ++ end subroutine ffluff_default ++ + !======================================================================= + + end module icedrv_forcing_bgc +diff --git a/configuration/driver/icedrv_init.F90 b/configuration/driver/icedrv_init.F90 +index c1e738c..ed69c07 100644 +--- a/configuration/driver/icedrv_init.F90 ++++ b/configuration/driver/icedrv_init.F90 +@@ -58,7 +58,7 @@ subroutine input_data + + use icedrv_diagnostics, only: diag_file, nx_names + use icedrv_domain_size, only: nilyr, nslyr, nblyr, max_ntrcr, ncat +- use icedrv_domain_size, only: n_iso, n_aero, nfsd ++ use icedrv_domain_size, only: n_iso, n_aero, nfsd, n_fluff + use icedrv_calendar, only: year_init, istep0 + use icedrv_calendar, only: dumpfreq, diagfreq, dump_last + use icedrv_calendar, only: npt, dt, ndtd, days_per_year, use_leap_years +@@ -116,12 +116,12 @@ subroutine input_data + + integer (kind=int_kind) :: ntrcr + logical (kind=log_kind) :: tr_iage, tr_FY, tr_lvl, tr_pond, tr_snow +- logical (kind=log_kind) :: tr_iso, tr_aero, tr_fsd ++ logical (kind=log_kind) :: tr_iso, tr_aero, tr_fsd, tr_fluff + logical (kind=log_kind) :: tr_pond_lvl, tr_pond_topo, wave_spec + integer (kind=int_kind) :: nt_Tsfc, nt_sice, nt_qice, nt_qsno, nt_iage, nt_FY + integer (kind=int_kind) :: nt_alvl, nt_vlvl, nt_apnd, nt_hpnd, nt_ipnd, & + nt_smice, nt_smliq, nt_rhos, nt_rsnw, & +- nt_aero, nt_fsd, nt_isosno, nt_isoice ++ nt_aero, nt_fsd, nt_isosno, nt_isoice, nt_fluff + + real (kind=real_kind) :: rplvl, rptopo + real (kind=dbl_kind) :: Cf, puny +@@ -194,6 +194,7 @@ subroutine input_data + tr_snow, & + tr_aero, & + tr_fsd, & ++ tr_fluff, & + tr_iso + + !----------------------------------------------------------------- +@@ -300,6 +301,7 @@ subroutine input_data + tr_aero = .false. ! aerosols + tr_fsd = .false. ! floe size distribution + tr_iso = .false. ! isotopes ++ tr_fluff = .false. ! fluffballs + + !----------------------------------------------------------------- + ! read from input file +@@ -549,6 +551,13 @@ subroutine input_data + call icedrv_system_abort(file=__FILE__,line=__LINE__) + endif + ++ if (tr_fluff .and. n_fluff==0) then ++ write (nu_diag,*) 'WARNING: fluffballs activated but' ++ write (nu_diag,*) 'WARNING: not allocated in tracer array.' ++ write (nu_diag,*) 'WARNING: Activate in compilation script.' ++ call icedrv_system_abort(file=__FILE__,line=__LINE__) ++ endif ++ + if (tr_aero .and. n_aero==0) then + write (nu_diag,*) 'WARNING: aerosols activated but' + write (nu_diag,*) 'WARNING: not allocated in tracer array.' +@@ -892,6 +901,12 @@ subroutine input_data + ntrcr = ntrcr + n_iso ! n_iso species in ice + end if + ++ nt_fluff = max_ntrcr ++ if (tr_fluff) then ! fluffballs ++ nt_fluff = ntrcr + 1 ++ ntrcr = ntrcr + n_fluff ++ end if ++ + nt_aero = max_ntrcr - 4*n_aero + if (tr_aero) then + nt_aero = ntrcr + 1 +@@ -918,6 +933,7 @@ subroutine input_data + write(nu_diag,1020) 'nblyr = ', nblyr + write(nu_diag,1020) 'nfsd = ', nfsd + write(nu_diag,1020) 'n_iso = ', n_iso ++ write(nu_diag,1020) 'n_fluff = ', n_fluff + write(nu_diag,1020) 'n_aero = ', n_aero + write(nu_diag,*)' ' + write(nu_diag,1020) 'nx = ', nx +@@ -991,10 +1007,10 @@ subroutine input_data + windmin_in=windmin, drhosdwind_in=drhosdwind, snwlvlfac_in=snwlvlfac) + call icepack_init_tracer_sizes(ntrcr_in=ntrcr, & + ncat_in=ncat, nilyr_in=nilyr, nslyr_in=nslyr, nblyr_in=nblyr, & +- nfsd_in=nfsd, n_iso_in=n_iso, n_aero_in=n_aero) ++ nfsd_in=nfsd, n_iso_in=n_iso, n_aero_in=n_aero, n_fluff_in=n_fluff) + call icepack_init_tracer_flags(tr_iage_in=tr_iage, & + tr_FY_in=tr_FY, tr_lvl_in=tr_lvl, tr_aero_in=tr_aero, & +- tr_iso_in=tr_iso, tr_snow_in=tr_snow, & ++ tr_iso_in=tr_iso, tr_snow_in=tr_snow, tr_fluff_in=tr_fluff, & + tr_pond_in=tr_pond, & + tr_pond_lvl_in=tr_pond_lvl, & + tr_pond_topo_in=tr_pond_topo, tr_fsd_in=tr_fsd) +@@ -1005,7 +1021,7 @@ subroutine input_data + nt_apnd_in=nt_apnd, nt_hpnd_in=nt_hpnd, nt_ipnd_in=nt_ipnd, & + nt_smice_in=nt_smice, nt_smliq_in=nt_smliq, & + nt_rhos_in=nt_rhos, nt_rsnw_in=nt_rsnw, & +- nt_aero_in=nt_aero, nt_fsd_in=nt_fsd, & ++ nt_aero_in=nt_aero, nt_fsd_in=nt_fsd, nt_fluff_in=nt_fluff, & + nt_isosno_in=nt_isosno, nt_isoice_in=nt_isoice) + + call icepack_warnings_flush(nu_diag) +@@ -1073,7 +1089,7 @@ subroutine init_state + + use icepack_intfc, only: icepack_aggregate + use icedrv_domain_size, only: ncat, nilyr, nslyr, nblyr, max_ntrcr +- use icedrv_domain_size, only: n_iso, n_aero, nfsd ++ use icedrv_domain_size, only: n_iso, n_aero, nfsd, n_fluff + use icedrv_flux, only: sst, Tf, Tair, salinz, Tmltz + use icedrv_state, only: trcr_depend, aicen, trcrn, vicen, vsnon + use icedrv_state, only: aice0, aice, vice, vsno, trcr, aice_init +@@ -1086,10 +1102,10 @@ subroutine init_state + + integer (kind=int_kind) :: ntrcr + logical (kind=log_kind) :: tr_iage, tr_FY, tr_lvl, tr_aero, tr_fsd, tr_iso +- logical (kind=log_kind) :: tr_pond_lvl, tr_pond_topo, tr_snow ++ logical (kind=log_kind) :: tr_pond_lvl, tr_pond_topo, tr_snow, tr_fluff + integer (kind=int_kind) :: nt_Tsfc, nt_sice, nt_qice, nt_qsno, nt_iage, nt_fy + integer (kind=int_kind) :: nt_alvl, nt_vlvl, nt_apnd, nt_hpnd, nt_ipnd, & +- nt_smice, nt_smliq, nt_rhos, nt_rsnw, & ++ nt_smice, nt_smliq, nt_rhos, nt_rsnw, nt_fluff, & + nt_aero, nt_fsd, nt_isosno, nt_isoice + + character(len=*), parameter :: subname='(init_state)' +@@ -1102,7 +1118,7 @@ subroutine init_state + call icepack_query_tracer_flags(tr_iage_out=tr_iage, & + tr_FY_out=tr_FY, tr_lvl_out=tr_lvl, tr_aero_out=tr_aero, & + tr_iso_out=tr_iso, tr_snow_out=tr_snow, & +- tr_pond_lvl_out=tr_pond_lvl, & ++ tr_pond_lvl_out=tr_pond_lvl, tr_fluff_out=tr_fluff, & + tr_pond_topo_out=tr_pond_topo, tr_fsd_out=tr_fsd) + call icepack_query_tracer_indices(nt_Tsfc_out=nt_Tsfc, & + nt_sice_out=nt_sice, nt_qice_out=nt_qice, & +@@ -1111,7 +1127,7 @@ subroutine init_state + nt_apnd_out=nt_apnd, nt_hpnd_out=nt_hpnd, & + nt_ipnd_out=nt_ipnd, & + nt_smice_out=nt_smice, nt_smliq_out=nt_smliq, & +- nt_rhos_out=nt_rhos, nt_rsnw_out=nt_rsnw, & ++ nt_rhos_out=nt_rhos, nt_rsnw_out=nt_rsnw, nt_fluff_out=nt_fluff, & + nt_isosno_out=nt_isosno, nt_isoice_out=nt_isoice, & + nt_aero_out=nt_aero, nt_fsd_out=nt_fsd) + call icepack_warnings_flush(nu_diag) +@@ -1178,6 +1194,12 @@ subroutine init_state + trcr_depend(nt_isoice) = 1 ! ice + enddo + endif ++ if (tr_fluff) then ! isotopes ++ do it = 1, n_fluff ++! trcr_depend(nt_fluff + it -1) = 0 ! area ++ trcr_depend(nt_fluff + it -1) = 1 ! ice volume ++ enddo ++ endif + if (tr_aero) then ! volume-weighted aerosols + do it = 1, n_aero + trcr_depend(nt_aero+(it-1)*4 ) = 2 ! snow +diff --git a/configuration/driver/icedrv_restart.F90 b/configuration/driver/icedrv_restart.F90 +index 762d1b3..5a687e8 100644 +--- a/configuration/driver/icedrv_restart.F90 ++++ b/configuration/driver/icedrv_restart.F90 +@@ -29,6 +29,7 @@ module icedrv_restart + write_restart_snow, read_restart_snow, & + write_restart_fsd, read_restart_fsd, & + write_restart_iso, read_restart_iso, & ++ write_restart_fluff, read_restart_fluff, & + write_restart_aero, read_restart_aero + + character (len=3), private :: nchar ! +@@ -89,7 +90,7 @@ subroutine dumpfile + + logical (kind=log_kind) :: & + tr_iage, tr_FY, tr_lvl, tr_iso, tr_aero, tr_brine, & +- tr_pond_topo, tr_pond_lvl, tr_snow, tr_fsd ++ tr_pond_topo, tr_pond_lvl, tr_snow, tr_fsd, tr_fluff + ! skl_bgc, z_tracers + + integer (kind=int_kind) :: dims(2) +@@ -115,7 +116,7 @@ subroutine dumpfile + + call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & + tr_lvl_out=tr_lvl, tr_aero_out=tr_aero, tr_iso_out=tr_iso, & +- tr_brine_out=tr_brine, & ++ tr_brine_out=tr_brine, tr_fluff_out=tr_fluff, & + tr_pond_topo_out=tr_pond_topo, & + tr_pond_lvl_out=tr_pond_lvl,tr_snow_out=tr_snow,tr_fsd_out=tr_fsd) + ! call icepack_query_parameters(skl_bgc_out=skl_bgc, z_tracers_out=z_tracers) +@@ -224,6 +225,7 @@ subroutine dumpfile + if (tr_aero) call write_restart_aero(dims) ! ice aerosols + if (tr_brine) call write_restart_hbrine(dims) ! brine height + if (tr_fsd) call write_restart_fsd(dims) ! floe size distribution ++ if (tr_fluff) call write_restart_fluff(dims) ! fluffballs + ! called in icedrv_RunMod.F90 to prevent circular dependencies + ! if (skl_bgc .or. z_tracers) & + ! call write_restart_bgc ! biogeochemistry +@@ -275,7 +277,7 @@ subroutine restartfile (ice_ic) + + logical (kind=log_kind) :: & + tr_iage, tr_FY, tr_lvl, tr_iso, tr_aero, tr_brine, & +- tr_pond_topo, tr_pond_lvl, tr_snow, tr_fsd ++ tr_pond_topo, tr_pond_lvl, tr_snow, tr_fsd, tr_fluff + + character(len=char_len_long) :: filename + character(len=*), parameter :: subname='(restartfile)' +@@ -290,7 +292,7 @@ subroutine restartfile (ice_ic) + + call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & + tr_lvl_out=tr_lvl, tr_aero_out=tr_aero, tr_iso_out=tr_iso, & +- tr_brine_out=tr_brine, & ++ tr_brine_out=tr_brine, tr_fluff_out=tr_fluff, & + tr_pond_topo_out=tr_pond_topo, & + tr_pond_lvl_out=tr_pond_lvl,tr_snow_out=tr_snow,tr_fsd_out=tr_fsd) + call icepack_warnings_flush(nu_diag) +@@ -399,6 +401,7 @@ subroutine restartfile (ice_ic) + if (tr_aero) call read_restart_aero() ! ice aerosols + if (tr_brine) call read_restart_hbrine ! brine height + if (tr_fsd) call read_restart_fsd() ! floe size distribution ++ if (tr_fluff) call read_restart_fluff() ! fluffballs + + !----------------------------------------------------------------- + ! Ensure ice is binned in correct categories +@@ -768,6 +771,52 @@ end subroutine read_restart_age + + !======================================================================= + ++! Dumps all values needed for restarting ++ ++ subroutine write_restart_fluff(dims) ++ ++ use icedrv_state, only: trcrn ++ use icedrv_domain_size, only: ncat ++ ++ integer (kind=int_kind), intent(in), optional :: & ++ dims(:) ! netcdf dimension IDs ++ ++ integer (kind=int_kind) :: nt_fluff ++ character(len=*), parameter :: subname='(write_restart_fluff)' ++ ++ call icepack_query_tracer_indices(nt_fluff_out=nt_fluff) ++ call icepack_warnings_flush(nu_diag) ++ if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & ++ file=__FILE__,line= __LINE__) ++ ++ call write_restart_field(nu_dump,trcrn(:,nt_fluff,:),ncat,'fluff',dims) ++ ++ end subroutine write_restart_fluff ++ ++!======================================================================= ++ ++! Reads all values needed for an ice fluff restart ++ ++ subroutine read_restart_fluff() ++ ++ use icedrv_state, only: trcrn ++ use icedrv_domain_size, only: ncat ++ integer (kind=int_kind) :: nt_fluff ++ character(len=*), parameter :: subname='(read_restart_fluff)' ++ ++ write(nu_diag,*) 'min/max fluff (s)' ++ ++ call icepack_query_tracer_indices(nt_fluff_out=nt_fluff) ++ call icepack_warnings_flush(nu_diag) ++ if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & ++ file=__FILE__,line= __LINE__) ++ ++ call read_restart_field(nu_restart,trcrn(:,nt_fluff,:),ncat,'fluff') ++ ++ end subroutine read_restart_fluff ++ ++!======================================================================= ++ + ! Dumps all values needed for restarting + ! author Elizabeth C. Hunke, LANL + +diff --git a/configuration/driver/icedrv_step.F90 b/configuration/driver/icedrv_step.F90 +index 0f25b56..1dc844d 100644 +--- a/configuration/driver/icedrv_step.F90 ++++ b/configuration/driver/icedrv_step.F90 +@@ -127,7 +127,7 @@ subroutine step_therm1 (dt) + use icedrv_flux, only: fswthru, fswthru_vdr, fswthru_vdf, fswthru_idr, fswthru_idf + use icedrv_flux, only: flatn_f, fsensn_f, fsurfn_f, fcondtopn_f + use icedrv_flux, only: dsnow, dsnown, faero_atm, faero_ocn +- use icedrv_flux, only: fiso_atm, fiso_ocn, fiso_evap ++ use icedrv_flux, only: fiso_atm, fiso_ocn, fiso_evap, ffluff_atm, ffluff_ocn + use icedrv_flux, only: HDO_ocn, H2_16O_ocn, H2_18O_ocn + use icedrv_init, only: lmask_n, lmask_s + use icedrv_state, only: aice, aicen, aice_init, aicen_init, vicen_init +@@ -151,7 +151,7 @@ subroutine step_therm1 (dt) + + integer (kind=int_kind) :: & + ntrcr, nt_apnd, nt_hpnd, nt_ipnd, nt_alvl, nt_vlvl, nt_Tsfc, & +- nt_iage, nt_FY, nt_qice, nt_sice, nt_qsno, & ++ nt_iage, nt_FY, nt_qice, nt_sice, nt_qsno, nt_fluff, & + nt_aero, nt_isosno, nt_isoice, nt_rsnw, nt_smice, nt_smliq + + logical (kind=log_kind) :: & +@@ -198,7 +198,7 @@ subroutine step_therm1 (dt) + call icepack_query_tracer_indices( & + nt_apnd_out=nt_apnd, nt_hpnd_out=nt_hpnd, nt_ipnd_out=nt_ipnd, & + nt_alvl_out=nt_alvl, nt_vlvl_out=nt_vlvl, nt_Tsfc_out=nt_Tsfc, & +- nt_iage_out=nt_iage, nt_FY_out=nt_FY, & ++ nt_iage_out=nt_iage, nt_FY_out=nt_FY, nt_fluff_out=nt_fluff, & + nt_qice_out=nt_qice, nt_sice_out=nt_sice, & + nt_aero_out=nt_aero, nt_qsno_out=nt_qsno, & + nt_rsnw_out=nt_rsnw, nt_smice_out=nt_smice, nt_smliq_out=nt_smliq, & +@@ -289,6 +289,7 @@ subroutine step_therm1 (dt) + hpnd = trcrn(i,nt_hpnd,:), & + ipnd = trcrn(i,nt_ipnd,:), & + iage = trcrn(i,nt_iage,:), & ++ fluff= trcrn(i,nt_fluff,:), & + FY = trcrn(i,nt_FY,:), & + rsnwn = rsnwn (:,:), & + smicen = smicen(:,:), & +@@ -356,6 +357,8 @@ subroutine step_therm1 (dt) + faero_ocn = faero_ocn(i,1:n_aero), & + fiso_atm = fiso_atm (i,:), & + fiso_ocn = fiso_ocn (i,:), & ++ ffluff_atm = ffluff_atm (i), & ++ ffluff_ocn = ffluff_ocn (i), & + fiso_evap = fiso_evap (i,:), & + HDO_ocn = HDO_ocn (i), & + H2_16O_ocn = H2_16O_ocn (i), & +diff --git a/configuration/scripts/icepack.build b/configuration/scripts/icepack.build +index f897de4..10e9d23 100755 +--- a/configuration/scripts/icepack.build ++++ b/configuration/scripts/icepack.build +@@ -63,7 +63,7 @@ endif + if !(-d ${ICE_OBJDIR}) mkdir -p ${ICE_OBJDIR} + cd ${ICE_OBJDIR} + +-setenv ICE_CPPDEFS "${ICE_CPPDEFS} -DNXGLOB=${ICE_NXGLOB} -DNICELYR=${NICELYR} -DNSNWLYR=${NSNWLYR} -DNICECAT=${NICECAT} -DNFSDCAT=${NFSDCAT} -DTRAGE=${TRAGE} -DTRFY=${TRFY} -DTRLVL=${TRLVL} -DTRPND=${TRPND} -DTRSNOW=${TRSNOW} -DTRBRI=${TRBRI} -DNTRISO=${NTRISO} -DNTRAERO=${NTRAERO} -DNBGCLYR=${NBGCLYR} -DTRALG=${TRALG} -DTRBGCZ=${TRBGCZ} -DTRDOC=${TRDOC} -DTRDOC=${TRDOC} -DTRDIC=${TRDIC} -DTRDON=${TRDON} -DTRFED=${TRFED} -DTRFEP=${TRFEP} -DTRZAERO=${TRZAERO} -DTRBGCS=${TRBGCS} " ++setenv ICE_CPPDEFS "${ICE_CPPDEFS} -DNXGLOB=${ICE_NXGLOB} -DNICELYR=${NICELYR} -DNSNWLYR=${NSNWLYR} -DNICECAT=${NICECAT} -DNFSDCAT=${NFSDCAT} -DTRAGE=${TRAGE} -DTRFY=${TRFY} -DTRLVL=${TRLVL} -DTRPND=${TRPND} -DTRSNOW=${TRSNOW} -DTRBRI=${TRBRI} -DNTRISO=${NTRISO} -DNTRAERO=${NTRAERO} -DNBGCLYR=${NBGCLYR} -DTRALG=${TRALG} -DTRBGCZ=${TRBGCZ} -DTRDOC=${TRDOC} -DTRDOC=${TRDOC} -DTRDIC=${TRDIC} -DTRDON=${TRDON} -DTRFED=${TRFED} -DTRFEP=${TRFEP} -DTRZAERO=${TRZAERO} -DTRBGCS=${TRBGCS} -DNFLUFF=${NFLUFF}" + + if (${ICE_IOTYPE} == 'netcdf') then + setenv ICE_CPPDEFS "${ICE_CPPDEFS} -DUSE_NETCDF" +diff --git a/configuration/scripts/icepack.settings b/configuration/scripts/icepack.settings +index 5c536f8..e5ec95f 100755 +--- a/configuration/scripts/icepack.settings ++++ b/configuration/scripts/icepack.settings +@@ -74,6 +74,7 @@ setenv TRFEP 0 # number of particulate iron tracers + # (up to max_fe = 2) + setenv TRFED 0 # number of dissolved iron tracers + # (up to max_fe = 2) ++setenv NFLUFF 0 # number of fluffball tracers + + ### Specialty code + setenv ICE_SNICARHC false # include hardcoded (HC) snicar tables +diff --git a/configuration/scripts/icepack_in b/configuration/scripts/icepack_in +index bbf7a59..88f76b0 100644 +--- a/configuration/scripts/icepack_in ++++ b/configuration/scripts/icepack_in +@@ -33,6 +33,7 @@ + tr_aero = .false. + tr_fsd = .false. + tr_iso = .false. ++ tr_fluff = .false. + / + + &thermo_nml +diff --git a/configuration/scripts/options/set_env.fluff b/configuration/scripts/options/set_env.fluff +new file mode 100644 +index 0000000..49ac114 +--- /dev/null ++++ b/configuration/scripts/options/set_env.fluff +@@ -0,0 +1 @@ ++setenv NFLUFF 1 # number of fluff tracers +diff --git a/configuration/scripts/options/set_nml.fluff b/configuration/scripts/options/set_nml.fluff +new file mode 100644 +index 0000000..cb0a4ea +--- /dev/null ++++ b/configuration/scripts/options/set_nml.fluff +@@ -0,0 +1 @@ ++tr_fluff = .true. +diff --git a/configuration/scripts/tests/timeseries.csh b/configuration/scripts/tests/timeseries.csh +index 459c905..7b2d5fe 100755 +--- a/configuration/scripts/tests/timeseries.csh ++++ b/configuration/scripts/tests/timeseries.csh +@@ -29,6 +29,7 @@ set fieldlist=("area fraction " \ + "new ice (m)" \ + "congelation (m)" \ + # "snow-ice (m)" \ ++ "fluffballs (kg)" \ + "intnl enrgy chng(W/m^2)") + + # Get the filename for the latest log diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index fbd0aa567..a938eba53 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -10,7 +10,7 @@ Icepack Tutorial Learning Goals ---------------- -In this activity you will clone the Icepack model code from the Consortium GitHub repository to run standalone Icepack simulations. You will also make namelist changes and code modifications for experiments and make some basic plots. If you run into issues, contact dbailey@ucar.edu. +In this activity you will clone the Icepack model code from the Consortium GitHub repository, create a branch, add a new tracer to Icepack, and run standalone Icepack simulations. You will also make namelist changes and code modifications for experiments and make some basic plots. Notes: @@ -23,199 +23,133 @@ Notes: * CICE and Icepack Resources, https://github.com/CICE-Consortium/About-Us/wiki/Resource-Index -Github One-time Configuration ----------------------------------- +Create An Icepack Branch, Port, and Run Initial Case +------------------------------------------------------ -You need to have your own GitHub account before you can start the following activities, and you should have already forked the Icepack repository. -For information about how to set up a GitHub account for the Icepack repository, see the Consortium documentation here, https://github.com/CICE-Consortium/About-Us/wiki/Git-Workflow-Guide. The Consortium recommends that you keep your fork’s main branch in sync with the Consortium version and that you always work on branches. This is all documented in the Git-Workflow-Guide linked above. +You should fork the Icepack repository and create a new branch in your fork for development. This is documented in https://github.com/CICE-Consortium/About-Us/wiki/Git-Workflow-Guide. But basically, -Note: +* Create a github account for yourself +* Fork the Consortium Icepack repository using the "Fork" feature at https://github.com/CICE-Consortium/Icepack +* Clone your repository onto your machine +* Create a branch +* Checkout the branch +* Port the model and verify you can build and run the model -* The workflow guide is oriented toward setting up CICE rather than Icepack, but the same workflow applies to Icepack standalone. Icepack can be set up and run as an independent model following the same workflow. +Many of these steps are done once per user or machine. You may be able to leverage the conda port to build and run the model, you may be working on a supported machine, or you may have to port the model to your machine. Porting, setting up cases, building, running, and running test suites are all documented in the Icepack User Guide, https://cice-consortium-icepack.readthedocs.io/en/latest/index.html. There are many ways to setup and run the model. +**Note:** The workflow guide is oriented toward setting up CICE rather than Icepack, but the same workflow applies to Icepack standalone. -Clone Icepack -------------------- +To summarize the steps in greater detail **assuming use of conda in a Mac or Linux environment**. -Clone your Icepack repository fork (use the URL from your fork) to a local sandbox:: +* Create a github account for yourself if you don't have one already (done once per user) - mkdir ~/icepack-dirs - cd ~/icepack-dirs - git clone https://github.com//Icepack +* Fork the Consortium Icepack repository, go to https://github.com/CICE-Consortium/Icepack and click on the fork button (done once per user) -If you have completed this correctly there should be an “Icepack” directory in the icepack-dirs directory. This is the “sandbox” we will be working in locally on your machine. +* Clone Icepack, sync the main branch, and create a new branch from the main branch. This will create a branch based on the lastest version of main:: -Move to the Icepack directory and check which branch you are using. This should be main:: + mkdir ~/icepack-dirs + cd ~/icepack-dirs + git clone https://github.com//Icepack + cd Icepack + git status (Branch should be main) + git remote --v (Check the origin and NO upstream) + git remote add upstream https://github.com/CICE-Consortium/Icepack + git remote --v (Check upstream has been added) + git pull upstream main + git push origin main + git branch + git checkout + git status (Branch should be ) - cd Icepack - git status +* Setup local env and download input datasets (done once per machine):: -Take a minute to orient yourself to the big picture structure of the directories and files in Icepack. The documentation has information about the Icepack :ref:`dirstructure`. + mkdir -p ~/icepack-dirs/runs ~/icepack-dirs/input ~/icepack-dirs/baseline + cd ~/icepack-dirs/input + curl -O https://zenodo.org/records/3728287/files/Icepack_data-20200326.tar.gz + tar -xzf Icepack_data-20200326.tar.gz -Make sure your main is up to date and create a branch. You can also update your fork directly in github by clicking the Sync fork button. If your code is already up to date, you can skip this step:: +* Setup the conda environment (done once per machine), see :ref:`laptops`:: - git remote --v (Check the origin and NO upstream) - git remote add upstream https://github.com/CICE-Consortium/Icepack - git remote --v (Check upstream has been added) - git pull upstream main - git push origin main - git branch - git checkout + curl -L https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -o ~/Downloads/miniconda.sh + bash ~/Downloads/miniconda.sh + source $HOME/miniconda3/bin/activate + conda init bash + conda config --set auto_activate_base false + source $HOME/miniconda3/bin/activate + cd ~/icepack-dirs/Icepack + conda env create -f configuration/scripts/machines/environment.yml + conda activate icepack +**NOTE:** If you have a Windows machine, we recommend using the Ubuntu Linux application, https://ubuntu.com/desktop/wsl. -Conda and Laptop One-time Configuration ------------------------------------------- +Again, there are many options for setting up the model on hardware, see the Icepack User Guide for more details. -To build and run Icepack on your laptop, you need to install software via conda. Instructions on how to do that can be found in the Icepack user guide, :ref:`laptops`. If you have a Windows machine, we recommend using the Ubuntu Linux application, https://ubuntu.com/desktop/wsl. Make sure to follow the instructions for installing miniconda. If your laptop has a conda environment already installed, you will still need to activate the icepack environment, and you may need to do so using the recommended miniconda distribution. Return here after completing section :ref:`laptops` in the documentation. After installing miniconda, the main steps are:: +* Set Up an Icepack Simulation. See :ref:`quickstart` and :ref:`running_icepack`:: - cd ~/icepack-dirs/Icepack - conda env create -f configuration/scripts/machines/environment.yml - conda activate icepack + cd ~/Icepack + ./icepack.setup --case icepack_test0 --mach conda --env macos + cd ~/icepack-dirs/cases/icepack_test0 + ./icepack.build + ./icepack.submit -Before you can run Icepack, you have to set up a directory structure and download the input and forcing datasets:: +Several env variables are defined in **icepack.settings** and the Icepack namelist file is **icepack_in**. Output files are copied from the run directory to a logs directory under the case. If the run is successful, you will see the message “ICEPACK COMPLETED SUCCESSFULLY” in the icepack run log file. Note that this job runs quickly - you are running a column model with four grid cells! - mkdir -p ~/icepack-dirs/runs ~/icepack-dirs/input ~/icepack-dirs/baseline - cd ~/icepack-dirs/input - curl -O https://zenodo.org/records/3728287/files/Icepack_data-20200326.tar.gz - tar -xzf Icepack_data-20200326.tar.gz +Look at the output. Go to the ICE_RUNDIR (defined in **icepack.settings**). A successful model integration will create ice_diag.* files and a file in the “restart” directory called “iced.yyyy-mm-dd-sssss” where yyyy-mm-dd-sssss is a model date/time stamp. The Icepack documentation has more information about :ref:`history`. -You can also run Icepack on an external machine that is supported by the Consortium or to which you have ported the code. In this case, you do not need to port to your laptop. +* Plot some output using the timeseries script provided, see :ref:`testplotting`. The conda icepack environment must be activated:: + cd $ICE_RUNDIR + conda activate icepack + ${ICE_SANDBOX}/configurations/scripts/tests/timeseries.csh ice_diag.full_ITD -Set Up an Icepack Simulation ------------------------------ +**Note:** that you can run the plotting script on any of the four ice_diag.* files. The .png files are created in the ICE_RUNDIR directory. View the png files. -Use the online Icepack documentation and in particular the :ref:`quickstart` and :ref:`running_icepack` sections as guidance and for details on the command line settings:: +* Questions to think about while looking at the output. - cd ~/icepack-dirs - mkdir cases - cd ~/Icepack - ./icepack.setup --case ~/icepack-dirs/cases/icepack_test0 --mach --env + * What time period does an out-of-the-box run cover? + * What are the differences between the full_ITD plots and the icefree plots (or any other combination of the ice_diag.* output files)? Which fields are the same? Which are different? Why would this be? + * What happens to ice area and ice thickness around October 1, 2015? Why do you see this signal? + * How does your output compare to the sample output provided for this release? -Notes: - -* If you are doing this in the conda environment, the machine is “conda”. -* Similarly, the variable is set to the compiler on your machine. For the conda environment, this is “macos” or “linux”. - -The setup script creates a case consistent with the machine and other defined settings under ~/icepack-dirs/cases/ with the name you selected (icepack_test0). The case directory will contain build and run scripts, a namelist file, and other necessary files. Once the case is set up any of these files can be manually edited to refine the desired configuration. - -Move to the new case directory and examine the settings:: - - cd ~/icepack-dirs/cases/icepack_test0 - -Open the **icepack.settings** file and look at it briefly. Note the ICE_CASEDIR (it should match this directory) and the ICE_RUNDIR (where the model will be run and output created). Now look at the default namelist settings in **icepack_in**. - -Build the code:: - - ./icepack.build - -The build script basically runs gmake under the covers, but there are a number of other tasks that are handled by the script to make the build more robust. If the build is successful you will see the message “COMPILE SUCCESSFUL” at the bottom of the screen. You can also check the README.case file to check the status. - -Submit the job. The submit script just submits the run scripts. Look at both **icepack.run** and **icepack.submit** files to see more details. The out-of-the-box run has default settings for the physics and other options. You can have a look at **icepack_in** and **icepack.settings** to review those settings. Then:: - - ./icepack.submit - -If the run is successful, you will see the message “ICEPACK COMPLETED SUCCESSFULLY” in the icepack run log file. Note that this job runs quickly - you are running a column model with four grid cells! - -Look at the output! Go to the ICE_RUNDIR where output was created. A successful model integration will create ice_diag.* files and a file in the “restart” directory called “iced.2016-01-01-00000”. The Icepack documentation has more information about :ref:`history`. - -Follow the documentation to create some plots of the output using the tools provided with Icepack (:ref:`testplotting`). The conda icepack environment must be activated, if it isn’t already:: - - cd ~/icepack-dirs/Icepack/configuration/scripts/tests/ - conda activate icepack - ./timeseries.csh ~/icepack-dirs/runs/icepack_test0/ice_diag.full_ITD - -Note that you can run the plotting script on any of the four ice_diag.* files. The .png files are created in the ICE_RUNDIR directory. Open the files:: - - cd ~/icepack-dirs/runs/icepack_test0/ - open .png - -Or use your file browser to navigate to the directory and double click on the images. - -Questions to think about while looking at the output. - -* What time period does an out-of-the-box run cover? -* What are the differences between the full_ITD plots and the icefree plots (or any other combination of the ice_diag.* output files)? Which fields are the same? Which are different? Why would this be? -* What happens to ice area and ice thickness around October 1, 2015? Why do you see this signal? -* How does your output compare to the sample output provided for this release? (hint: see the wiki!) - -Take a step back and think about all the directories and files you have created. The Icepack “sandbox” was cloned from GitHub and has the actual Icepack code. - -* There is a particular case directory for building and launching the code, and some output (e.g. job log) are copied. -* There is a particular run directory for each case. This is where the model is run and big files are found. - - -Set Up a Longer Run ---------------------- - -Once you have had success with the previous step, you can run another, longer experiment to practice some basic changes for Icepack. Go back to your Icepack directory:: - - cd ~/icepack-dirs/Icepack/ - -You need to set up a new out-of-the-box case (icepack_test1):: - - ./icepack.setup --case ~/icepack-dirs/cases/icepack_test1 --mach --env - -Go into the cases/icepack_test1 directory, and build the case. -Change the following namelist settings in **icepack_in**, - - npt = 8760 - -How long is this setting the model to run? Change this to run for 10 years (hint: The timestep is one hour, and there are 24 steps per day, and 365 days per year). - -Details about namelist options are in the documentation (:ref:`case_settings`). - -Submit the job. Check the output and think about the following: - -* Over what dates did the model run this time? -* What date would the model restart from? - - -Modify a physics option ---------------------------- - -Set up another case:: - - ./icepack.setup --case ~/icepack-dirs/cases/icepack_test2 --mach --env - -Build the code. - -Change the thermodynamics option from ktherm = 2 to ktherm = 1 in **icepack_in**, and set sw_redist = .true. The intent here is to change the namelist option for the current experiment in the case directory. Think about what would happen if you changed **icepack_in** in the source code before creating the case instead (hint: this experiment should work the same, but what about future experiments?). -Submit the job. Have a look at the output. +Modify the Configuration or Code +------------------------------------ -* What is different compared to your first run? -* What happens if sw_redist = .false. with ktherm = 1? Why? +* Set up a longer Run. Modify ``npt`` in icepack_in. ``npt`` defines the number of timesteps to run. Details about namelist options are in the documentation (:ref:`case_settings`). +* Modify a physics option. Change the thermodynamics option from ktherm=2 to ktherm=1 in **icepack_in**, and set sw_redist=.true. The intent here is to change the namelist option for the current experiment in the case directory. What is different compared to your first run? What happens if sw_redist = .false. with ktherm = 1? Why? -Change a Parameter in the Fortran Code ------------------------------------------ +* Undo your latest **icepack_in** changes -Set up another case:: +* Change a Parameter in the Fortran Code. Edit **icepack_mechred.F90** and set - ./icepack.setup --case ~/icepack-dirs/cases/icepack_test3 --mach --env + ``fsnowrdg = c1 , & ! snow fraction that survives in ridging``. -Change to the source code directory:: + Rebuild the code before running. What is different about this run? What do you think the fsnowrdg parameter is doing here? - cd columnphysics +* Revert your latest code changes:: -Edit icepack_mechred.F90 to change the line + cd ~/Icepack + git status + git checkout columnphysics/icepack_mechred.F90 + git status - fsnowrdg = p5 , & ! snow fraction that survives in ridging +.. _tutorialfluff: -to +Add a New Tracer +-------------------------------------- - fsnowrdg = c1 , & ! snow fraction that survives in ridging +In this exercise, add a new tracer associated with fluffballs. +Call the tracer fluff and make it depend on ice area. Follow the step-by-step instructions in the :ref:`addtrcr` documentation. +Once you have implemented the model changes, be sure to add fluffballs output to the standard output diagnostics and turn on the +fluff tracer. Then update the timeseries plotting script to plot the fluffballs values over time. -Build the code and submit the job. +* First, set the initial value, physics, sources, and sinks of fluff to zero and make sure fluff values remain zero throughout the run -* What is different about this run? -* What do you think the fsnowrdg parameter is doing here? +* Add some constant atmospheric forcing and review results -Revert your code changes:: +* Change the dependency to ice volume, how do the results change? - cd ~/Icepack - git status - git checkout columnphysics/icepack_mechred.F90 - git status +* Modify the physics to create some physics processes, see isotopes or aerosols for some ideas +**NOTE:** The file, **doc/source/tutorial/fluff.diff** in the Icepack repository, demonstrates code differences for this fluffball activity as implemented in a version of Icepack from July, 2024. These code differences may not be directly applicable to other code versions, but they provide an example of the typical code modifications required to add the tracer, fluff. diff --git a/doc/source/developer_guide/dg_adding_tracers.rst b/doc/source/developer_guide/dg_adding_tracers.rst index 4f16ec0f3..3a1646af1 100755 --- a/doc/source/developer_guide/dg_adding_tracers.rst +++ b/doc/source/developer_guide/dg_adding_tracers.rst @@ -8,7 +8,7 @@ Adding tracers We require that any changes made to the code be implemented in such a way that they can be "turned off" through namelist flags. In most cases, code run with such changes should be bit-for-bit identical with the unmodified code. Occasionally, non-bit-for-bit changes -are necessary, e.g. associated with an unavoidable change in the order of operations. In +are necessary or unavoidable due to a change in the order of operations. In these cases, changes should be made in stages to isolate the non-bit-for-bit changes, so that those that should be bit-for-bit can be tested separately. @@ -16,10 +16,9 @@ Tracers added to Icepack will also require extensive modifications to the host sea ice model, including initialization on the horizontal grid, namelist flags and restart capabilities. Modifications to the Icepack driver should reflect the modifications needed in the host model but are not expected to match completely. -We recommend that the logical namelist variable -``tr_[tracer]`` be used for all calls involving the new tracer outside of -**ice\_[tracer].F90**, in case other users do not want to use that -tracer. +We recommend that a logical namelist variable +``tr_[tracer]`` be added and used for all calls involving the new tracer to provide +clean backwards compatibility. A number of optional tracers are available in the code, including ice age, first-year ice area, melt pond area and volume, brine height, @@ -45,54 +44,134 @@ the tracer dependencies (weights), which are tracked using the arrays ``trcr_depend`` (indicates dependency on area, ice volume or snow volume), ``trcr_base`` (a dependency mask), ``n_trcr_strata`` (the number of underlying tracer layers), and ``nt_strata`` (indices of underlying layers). -See subroutine *icepack_compute_tracers* in **icepack\_tracers.F90**. +See subroutine *icepack_compute_tracers* in **icepack_tracers.F90**. -To add a tracer, follow these steps using one of the existing tracers as -a pattern (e.g. age). +To add a tracer, follow these steps using one of the existing tracers, for example +age or isotopes, as an example. Lets call the new tracer xyz. Note that many +of the changes are defined in the Icepack driver or scripts. For CICE or other models +using Icepack, adding a new tracer may be done differently. However, changes to the +Icepack columnphyics should be similar. As you make changes, we recommend that you +build and run with the tracer off to ensure the code modifications are working properly. +Changes to setup, namelist, and build files either need to be tested by generating +a new case or by modifying the same files in an existing case before running. +Code changes can be tested by rebuilding and rerunning an existing case. -#. **icedrv\_domain\_size.F90**: increase ``max_ntrcr`` (can also add option - to **icepack.settings** and **icepack.build**) +The appendix has a tutorial activity, :ref:`tutorialfluff`, where a tracer is added to +Icepack. A set of code differences are provided there as an example of how this could +be done in practice. -#. **icepack\_tracers.F90**: +#. Define a new tracer. First, setup the tracer cpp in **configuration/scripts/icepack.settings** + and **configuration/scripts/icepack.build** - - declare ``nt_[tracer]`` and ``tr_[tracer]`` + - In **icepack.settings**, add:: - - add flags and indices to the init, query and write subroutines, and - call these routines as needed throughout the code + setenv NXYZ 1 # number of xyz tracers -#. **icepack\_[tracer].F90**: create physics routines + - In **icepack.build**, add:: -#. **icedrv\_init.F90**: (some of this may be done in **icepack\_[tracer].F90** - instead) + -DNXYZ=${NXYZ} - - declare ``tr_[tracer]`` and ``nt_[tracer]`` as needed + to the setenv ICE_CPPDEFS line - - add logical namelist variable ``tr_[tracer]`` +#. Define the new tracer dimension in **icedrv_domain_size.F90**. - - initialize namelist variable + - Add a new dimension:: - - print namelist variable to diagnostic output file + n_xyz = NXYZ, & ! number of xyz tracers - - increment number of tracers in use based on namelist input (``ntrcr``) + - Update the size of ``max_ntrcr`` by adding:: - - define tracer dependencies + + n_xyz & ! number of xyz tracers -#. **icedrv\_step\_mod.F90** (and elsewhere as needed): +#. Add the new tracer to **icepack_tracers.F90**: - - call physics routines in **icepack\_[tracer].F90** + - Define new variables:: -#. **icedrv\_restart.F90**: + tr_xyz=.false. + n_xyz=0 + nt_xyz=0 - - define restart variables + By default, these are turned off. + + - Add the new variables to the tracer init, query, and write subroutine arguments + (tracer_flags, tracer_sizes, and tracer_indices). The driver of Icepack will turn + this tracer on as needed. + +#. Update the driver code to initialize the tracer flag and size and allocate space + for the tracer. You will also + define dependency, whether the variable is dependent on ice area (aice), ice + volume (vice), snow volume (vsno), or something else. Edit **icedrv_init.F90**. + + - Add ``n_xyz`` to use icedrv_domain_size in subroutine input_data + + - Define ``tr_xyz`` and ``nt_xyz`` variables in subroutine input_data + + - Add a logical namelist variable ``tr_xyz` to tracer_nml + + - Add a line to initialize ``tr_xyz=.false.`` + + - Add a check that ``tr_xyz`` and ``n_xyz`` are consistent + + - Add code to increment the number of tracers in use, ``ntrcr``, based on namelist input + + - Add some code to print xyz tracer info to the output file + + - Add calls to subroutines icepack_init_tracer_sizes, icepack_init_tracer_flags, and + icepack_init_tracer_indices to initialize the xyz tracer information in Icepack. + + - Define the tracer dependency in subroutine init_state. Area tracers can be thought of in terms of averages across + the ice area (the tracer value itself) or averages over the grid cell area (tracer * aice). + Volume tracers can be considered in a similar way, but it can also be helpful to think of + the tracer as the “density” of the variable, which when multiplied by the ice or snow volume + gives the total content of the variable in that volume of the ice or snow. The “total content” + is often a conserved quantity that can be checked during the calculation. + +#. Add the tracer to the default namelist **configuration/scripts/icepack_in** + + - Add the namelist flag ``tr_xyz`` to *tracer_nml*. + Best practice is to set the default namelist values so that the + new capability is turned off. You can create an option file with your preferred + configuration in **configuration/scripts/options**. - - call routines to read, write tracer restart data +#. If your tracer depends on ocean or atmosphere forcing -#. **icepack\_in**: add namelist variables to *tracer\_nml* and - *icefields\_nml*. Best practice is to set the namelist values so that the - new capability is turned off, and create an option file with your preferred - configuration in **configuration/scripts/options**. + - Initialize the sources and sinks in **icedrv_flux.F90** -#. If strict conservation is necessary, add diagnostics as noted for - topo ponds in Section :ref:`ponds` + - Add a subroutine to generate these sources or sinks in **icedrv_forcing.F90** + or **icedrv_forcing_bgc.F90**. + + - Add the new tracer forcing calls in **icedrv_InitMod.F90** and **icedrv_RunMod.F90** + + - Always use the flag ``tr_xyz`` to determine whether to call these routines. + +#. Create a new physics file/module for your tracer, **icepack_xyz.F90**. + This subroutine handles a number of the processes within the + sea ice and snow which affect the distribution of the tracer. These processes could include + congelation growth, snow melt, sea ice melt, evaporation / sublimation, or snow-ice formation. + Note there is a more sophisticated vertical distribution of tracer under the zbgc package. + If your tracer is impacted by frazil ice growth or lateral melt, this is discussed later. + It’s often helpful to copy and modify existing modules such as icepack_age.F90 or icepack_isotope.F90. + +#. Add the physics calls to Icepack or the driver. + + - Depending on the physics implementation, the + new tracer physics calls might be done in **icepack_therm_vertical**, **icedrv_step.F90**, and/or + elsewhere. See use of subroutines ``update_aerosol``, ``update_isotope``, or ``increment_age``. + + - Pass tracer array into Icepack via public interfaces as needed + + - Always use the flag ``tr_xyz`` to determine whether to call these routines. + +#. Add the new tracer to the restart files. Edit **icedrv_restart.F90**, + + - define restart variables + + - call routines to read and write tracer restart data + +#. If strict conservation is necessary, add conservation diagnostics using the + topographical ponds as an example, :ref:`ponds` #. Update documentation, including **icepack_index.rst** and **ug_case_settings.rst** + +#. Test and validate. Verify backwards compatibility. + From 92be1226e1f3c88d2312a9b7fc8073b9d30725fd Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Fri, 2 Aug 2024 08:53:49 -0700 Subject: [PATCH 22/30] Port to Casper (#496) Port to NCAR's cluster, casper using the HTC nodes using standard cpus. This will support testing and development on another piece of hardware other than derecho and izumi and provides a good option for smaller test cases. Added intel, inteloneapi, and gnu compiler options. The -check debug option is very sensitive in this version of Inteloneapi, so it has been turned off. --- configuration/scripts/icepack.batch.csh | 15 ++++++ .../scripts/machines/Macros.casper_gnu | 47 +++++++++++++++++ .../scripts/machines/Macros.casper_intel | 49 ++++++++++++++++++ .../machines/Macros.casper_inteloneapi | 51 +++++++++++++++++++ configuration/scripts/machines/env.casper_gnu | 51 +++++++++++++++++++ .../scripts/machines/env.casper_intel | 51 +++++++++++++++++++ .../scripts/machines/env.casper_inteloneapi | 51 +++++++++++++++++++ 7 files changed, 315 insertions(+) create mode 100644 configuration/scripts/machines/Macros.casper_gnu create mode 100644 configuration/scripts/machines/Macros.casper_intel create mode 100644 configuration/scripts/machines/Macros.casper_inteloneapi create mode 100644 configuration/scripts/machines/env.casper_gnu create mode 100644 configuration/scripts/machines/env.casper_intel create mode 100644 configuration/scripts/machines/env.casper_inteloneapi diff --git a/configuration/scripts/icepack.batch.csh b/configuration/scripts/icepack.batch.csh index 2268d1267..ae49998c4 100755 --- a/configuration/scripts/icepack.batch.csh +++ b/configuration/scripts/icepack.batch.csh @@ -64,6 +64,21 @@ cat >> ${jobfile} << EOFB ###PBS -m be EOFB +else if (${ICE_MACHINE} =~ casper*) then +cat >> ${jobfile} << EOFB +#PBS -q ${ICE_MACHINE_QUEUE} +#PBS -l job_priority=regular +#PBS -N ${ICE_CASENAME} +#PBS -A ${acct} +#PBS -l select=${nnodes}:ncpus=${corespernode}:mpiprocs=${taskpernodelimit}:ompthreads=${nthrds} +#PBS -l walltime=${ICE_RUNLENGTH} +#PBS -j oe +#PBS -W umask=022 +#PBS -o ${ICE_CASEDIR} +###PBS -M username@domain.com +###PBS -m be +EOFB + else if (${ICE_MACHINE} =~ hobart*) then cat >> ${jobfile} << EOFB #PBS -j oe diff --git a/configuration/scripts/machines/Macros.casper_gnu b/configuration/scripts/machines/Macros.casper_gnu new file mode 100644 index 000000000..103ff8cdf --- /dev/null +++ b/configuration/scripts/machines/Macros.casper_gnu @@ -0,0 +1,47 @@ +#============================================================================== +# Makefile macros for NCAR derecho, gnu compiler +#============================================================================== + +CPP := ftn -E +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c + +FIXEDFLAGS := -ffixed-line-length-132 +FREEFLAGS := -ffree-form +FFLAGS := -fconvert=big-endian -fbacktrace -ffree-line-length-none -fallow-argument-mismatch +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -g -fcheck=bounds -finit-real=nan -fimplicit-none -ffpe-trap=invalid,zero,overflow --std f2008 +# FFLAGS += -O0 -g -fcheck=all -finit-real=snan -fimplicit-none -ffpe-trap=invalid,zero,overflow + CFLAGS += -O0 +endif + +SCC := gcc +SFC := gfortran +CC := $(SCC) +FC := $(SFC) +LD := $(FC) + +NETCDF_PATH := $(NETCDF) + +#PIO_CONFIG_OPTS:= --enable-filesystem-hints=gpfs + +#PNETCDF_PATH := $(PNETCDF) +#PNETCDF_PATH := /glade/u/apps/ch/opt/pio/2.2/mpt/2.15f/intel/17.0.1/lib + +INCLDIR := $(INCLDIR) + +LIB_NETCDF := $(NETCDF)/lib +#LIB_PNETCDF := $(PNETCDF_PATH)/lib +#LIB_MPI := $(IMPILIBDIR) + +#SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff -L$(LIB_PNETCDF) -lpnetcdf -lgptl +SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -qopenmp + CFLAGS += -qopenmp + FFLAGS += -qopenmp +endif + diff --git a/configuration/scripts/machines/Macros.casper_intel b/configuration/scripts/machines/Macros.casper_intel new file mode 100644 index 000000000..d8d5efc78 --- /dev/null +++ b/configuration/scripts/machines/Macros.casper_intel @@ -0,0 +1,49 @@ +#============================================================================== +# Makefile macros for NCAR derecho, intel compiler +#============================================================================== + +CPP := fpp +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c -O2 -fp-model precise -march=core-avx2 + +FIXEDFLAGS := -fixed -132 +FREEFLAGS := -free +FFLAGS := -fp-model precise -convert big_endian -assume byterecl -ftz -traceback -march=core-avx2 +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created -link_mpi=dbg +# FFLAGS += -O0 -g -check all -fpe0 -ftrapuv -fp-model except -check noarg_temp_created -link_mpi=dbg -stand f08 +# FFLAGS += -O0 -g -check all -fpe0 -ftrapuv -fp-model except -check noarg_temp_created -init=snan,arrays -link_mpi=dbg +else + FFLAGS += -O2 +endif + +SCC := icx +SFC := ifort +CC := $(SCC) +FC := $(SFC) +LD := $(FC) + +NETCDF_PATH := $(NETCDF) + +#PIO_CONFIG_OPTS:= --enable-filesystem-hints=gpfs + +#PNETCDF_PATH := $(PNETCDF) +#PNETCDF_PATH := /glade/u/apps/ch/opt/pio/2.2/mpt/2.15f/intel/17.0.1/lib + +INCLDIR := $(INCLDIR) + +LIB_NETCDF := $(NETCDF)/lib +#LIB_PNETCDF := $(PNETCDF_PATH)/lib +#LIB_MPI := $(IMPILIBDIR) + +#SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff -L$(LIB_PNETCDF) -lpnetcdf -lgptl +SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -qopenmp + CFLAGS += -qopenmp + FFLAGS += -qopenmp +endif + diff --git a/configuration/scripts/machines/Macros.casper_inteloneapi b/configuration/scripts/machines/Macros.casper_inteloneapi new file mode 100644 index 000000000..40a10bc6d --- /dev/null +++ b/configuration/scripts/machines/Macros.casper_inteloneapi @@ -0,0 +1,51 @@ +#============================================================================== +# Makefile macros for NCAR derecho, inteloneapi compiler +#============================================================================== + +CPP := fpp +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c -O2 -fp-model precise -march=core-avx2 + +FIXEDFLAGS := -fixed -132 +FREEFLAGS := -free +FFLAGS := -fp-model precise -convert big_endian -assume byterecl -ftz -traceback -march=core-avx2 +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -g -check bounds -check pointers -fpe0 -check noarg_temp_created -link_mpi=dbg +# FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created -link_mpi=dbg +# FFLAGS += -O0 -g -check all -fpe0 -ftrapuv -fp-model except -check noarg_temp_created -link_mpi=dbg -stand f08 +# FFLAGS += -O0 -g -check all -fpe0 -ftrapuv -fp-model except -check noarg_temp_created -init=snan,arrays -link_mpi=dbg +# LDFLAGS += -check uninit +else + FFLAGS += -O2 +endif + +SCC := icx +SFC := ifx +CC := $(SCC) +FC := $(SFC) +LD := $(FC) + +NETCDF_PATH := $(NETCDF) + +#PIO_CONFIG_OPTS:= --enable-filesystem-hints=gpfs + +#PNETCDF_PATH := $(PNETCDF) +#PNETCDF_PATH := /glade/u/apps/ch/opt/pio/2.2/mpt/2.15f/intel/17.0.1/lib + +INCLDIR := $(INCLDIR) + +LIB_NETCDF := $(NETCDF)/lib +#LIB_PNETCDF := $(PNETCDF_PATH)/lib +#LIB_MPI := $(IMPILIBDIR) + +#SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff -L$(LIB_PNETCDF) -lpnetcdf -lgptl +SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -qopenmp + CFLAGS += -qopenmp + FFLAGS += -qopenmp +endif + diff --git a/configuration/scripts/machines/env.casper_gnu b/configuration/scripts/machines/env.casper_gnu new file mode 100644 index 000000000..bcf881057 --- /dev/null +++ b/configuration/scripts/machines/env.casper_gnu @@ -0,0 +1,51 @@ +#!/bin/csh -f + +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source ${MODULESHOME}/init/csh + +module --force purge +module load ncarenv/23.10 +#module load craype +module load gcc/12.2.0 +module load ncarcompilers +#module load cray-mpich/8.1.25 +#module load hdf5/1.12.2 +module load netcdf/4.9.2 +#module load cray-libsci/23.02.1.1 + +# For perftools with mpiexec +# module load perftools-base +# module load perftools +#setenv PALS_TRANSFER FALSE + +endif + +limit coredumpsize unlimited +limit stacksize unlimited +setenv PALS_QUIET TRUE + +# May be needed for OpenMP memory +setenv OMP_STACKSIZE 64M +# OMP runtime diagnostics +#setenv OMP_DISPLAY_ENV TRUE + +setenv ICE_MACHINE_MACHNAME casper +setenv ICE_MACHINE_MACHINFO "NCAR cluster with Intel Cascade Lake 36 core nodes with Mellanox ConnectX-5" +setenv ICE_MACHINE_ENVNAME gnu +setenv ICE_MACHINE_ENVINFO "gcc 12.2.0 20220819, netcdf4.9.2" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS +setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg +setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE +setenv ICE_MACHINE_SUBMIT "qsub" +setenv ICE_MACHINE_ACCT P00000000 +setenv ICE_MACHINE_QUEUE "casper" +setenv ICE_MACHINE_TPNODE 36 +setenv ICE_MACHINE_BLDTHRDS 1 +setenv ICE_MACHINE_QSTAT "qstat " diff --git a/configuration/scripts/machines/env.casper_intel b/configuration/scripts/machines/env.casper_intel new file mode 100644 index 000000000..fdd55976c --- /dev/null +++ b/configuration/scripts/machines/env.casper_intel @@ -0,0 +1,51 @@ +#!/bin/csh -f + +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source ${MODULESHOME}/init/csh + +module --force purge +module load ncarenv/23.10 +#module load craype +module load intel/2023.2.1 +module load ncarcompilers +#module load cray-mpich/8.1.25 +#module load hdf5/1.12.2 +module load netcdf/4.9.2 +#module load cray-libsci/23.02.1.1 + +# For perftools with mpiexec +# module load perftools-base +# module load perftools +#setenv PALS_TRANSFER FALSE + +endif + +limit coredumpsize unlimited +limit stacksize unlimited +setenv PALS_QUIET TRUE + +# May be needed for OpenMP memory +setenv OMP_STACKSIZE 64M +# OMP runtime diagnostics +#setenv OMP_DISPLAY_ENV TRUE + +setenv ICE_MACHINE_MACHNAME casper +setenv ICE_MACHINE_MACHINFO "NCAR cluster with Intel Cascade Lake 36 core nodes with Mellanox ConnectX-5" +setenv ICE_MACHINE_ENVNAME intel +setenv ICE_MACHINE_ENVINFO "ifort 2021.10.0 20230609, netcdf4.9.2" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS +setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg +setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE +setenv ICE_MACHINE_SUBMIT "qsub" +setenv ICE_MACHINE_ACCT P00000000 +setenv ICE_MACHINE_QUEUE "casper" +setenv ICE_MACHINE_TPNODE 36 +setenv ICE_MACHINE_BLDTHRDS 1 +setenv ICE_MACHINE_QSTAT "qstat " diff --git a/configuration/scripts/machines/env.casper_inteloneapi b/configuration/scripts/machines/env.casper_inteloneapi new file mode 100644 index 000000000..3fec15b9a --- /dev/null +++ b/configuration/scripts/machines/env.casper_inteloneapi @@ -0,0 +1,51 @@ +#!/bin/csh -f + +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source ${MODULESHOME}/init/csh + +module --force purge +module load ncarenv/23.10 +#module load craype +module load intel-oneapi/2023.2.1 +module load ncarcompilers +#module load cray-mpich/8.1.25 +#module load hdf5/1.12.2 +module load netcdf/4.9.2 +#module load cray-libsci/23.02.1.1 + +# For perftools with mpiexec +# module load perftools-base +# module load perftools +#setenv PALS_TRANSFER FALSE + +endif + +limit coredumpsize unlimited +limit stacksize unlimited +setenv PALS_QUIET TRUE + +# May be needed for OpenMP memory +setenv OMP_STACKSIZE 64M +# OMP runtime diagnostics +#setenv OMP_DISPLAY_ENV TRUE + +setenv ICE_MACHINE_MACHNAME casper +setenv ICE_MACHINE_MACHINFO "NCAR cluster with Intel Cascade Lake 36 core nodes with Mellanox ConnectX-5" +setenv ICE_MACHINE_ENVNAME inteloneapi +setenv ICE_MACHINE_ENVINFO "oneAPI DPC++/C++/ifx 2023.2.0 20230721, netcdf4.9.2" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS +setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg +setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE +setenv ICE_MACHINE_SUBMIT "qsub" +setenv ICE_MACHINE_ACCT P00000000 +setenv ICE_MACHINE_QUEUE "casper" +setenv ICE_MACHINE_TPNODE 36 +setenv ICE_MACHINE_BLDTHRDS 1 +setenv ICE_MACHINE_QSTAT "qstat " From 4c87095256c1c599c3ccaa857a95744158751a60 Mon Sep 17 00:00:00 2001 From: Elizabeth Hunke Date: Wed, 7 Aug 2024 12:11:20 -0600 Subject: [PATCH 23/30] Alternative congelation formulation following Plante et al. 2024 (#494) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add congel_freeze namelist and add 'one-step' option to the default 'two-step' option. Namelist flag congel_freeze chooses which formulation to use. The original is ‘two-step’, since only the mushy boundary moves in the first step and the phase change happens in the next step. Plante et al. (‘one-step’) moves the boundary and performs the phase change in a single time step. Maintain 'two-step' as default for now. --- columnphysics/icepack_parameters.F90 | 52 +++++++++++++------ columnphysics/icepack_therm_vertical.F90 | 40 +++++++++----- configuration/driver/icedrv_init.F90 | 9 ++-- configuration/scripts/icepack_in | 1 + .../scripts/machines/env.chicoma_intel | 2 +- configuration/scripts/options/set_nml.congel | 1 + configuration/scripts/tests/base_suite.ts | 2 + doc/source/master_list.bib | 16 ++++-- doc/source/science_guide/sg_thermo.rst | 18 +++++-- doc/source/user_guide/ug_case_settings.rst | 2 + 10 files changed, 102 insertions(+), 41 deletions(-) create mode 100644 configuration/scripts/options/set_nml.congel diff --git a/columnphysics/icepack_parameters.F90 b/columnphysics/icepack_parameters.F90 index f875409b5..e76b23b09 100644 --- a/columnphysics/icepack_parameters.F90 +++ b/columnphysics/icepack_parameters.F90 @@ -161,6 +161,11 @@ module icepack_parameters ! only for use with tr_aero or tr_zaero conserv_check = .false. ! if true, do conservations checks and abort + character(len=char_len), public :: & + congel_freeze = 'two-step' ! congelation computation + ! 'two-step' = original formulation + ! 'one-step' = Plante et al, The Cryosphere, 2024 + character(len=char_len), public :: & tfrz_option = 'mushy' ! form of ocean freezing temperature ! 'minus1p8' = -1.8 C @@ -465,7 +470,7 @@ subroutine icepack_init_parameters( & atmbndy_in, calc_strair_in, formdrag_in, highfreq_in, natmiter_in, & atmiter_conv_in, calc_dragio_in, & tfrz_option_in, kitd_in, kcatbound_in, hs0_in, frzpnd_in, & - saltflux_option_in, & + saltflux_option_in, congel_freeze_in, & floeshape_in, wave_spec_in, wave_spec_type_in, nfreq_in, & dpscale_in, rfracmin_in, rfracmax_in, pndaspect_in, hs1_in, hp1_in, & bgc_flux_type_in, z_tracers_in, scale_bgc_in, solve_zbgc_in, & @@ -575,15 +580,20 @@ subroutine icepack_init_parameters( & phi_i_mushy_in ! liquid fraction of congelation ice character(len=*), intent(in), optional :: & - tfrz_option_in ! form of ocean freezing temperature - ! 'minus1p8' = -1.8 C - ! 'linear_salt' = -depressT * sss - ! 'mushy' conforms with ktherm=2 + congel_freeze_in ! congelation computation + ! 'two-step' = original formulation + ! 'one-step' = Plante et al, The Cryosphere, 2024 character(len=*), intent(in), optional :: & - saltflux_option_in ! Salt flux computation - ! 'constant' reference value of ice_ref_salinity - ! 'prognostic' prognostic salt flux + tfrz_option_in ! form of ocean freezing temperature + ! 'minus1p8' = -1.8 C + ! 'linear_salt' = -depressT * sss + ! 'mushy' conforms with ktherm=2 + + character(len=*), intent(in), optional :: & + saltflux_option_in ! Salt flux computation + ! 'constant' reference value of ice_ref_salinity + ! 'prognostic' prognostic salt flux !----------------------------------------------------------------------- ! Parameters for radiation @@ -949,6 +959,7 @@ subroutine icepack_init_parameters( & if (present(highfreq_in) ) highfreq = highfreq_in if (present(natmiter_in) ) natmiter = natmiter_in if (present(atmiter_conv_in) ) atmiter_conv = atmiter_conv_in + if (present(congel_freeze_in) ) congel_freeze = congel_freeze_in if (present(tfrz_option_in) ) tfrz_option = tfrz_option_in if (present(saltflux_option_in) ) saltflux_option = saltflux_option_in if (present(kitd_in) ) kitd = kitd_in @@ -1192,7 +1203,7 @@ subroutine icepack_query_parameters( & atmbndy_out, calc_strair_out, formdrag_out, highfreq_out, natmiter_out, & atmiter_conv_out, calc_dragio_out, & tfrz_option_out, kitd_out, kcatbound_out, hs0_out, frzpnd_out, & - saltflux_option_out, & + saltflux_option_out, congel_freeze_out, & floeshape_out, wave_spec_out, wave_spec_type_out, nfreq_out, & dpscale_out, rfracmin_out, rfracmax_out, pndaspect_out, hs1_out, hp1_out, & bgc_flux_type_out, z_tracers_out, scale_bgc_out, solve_zbgc_out, & @@ -1311,16 +1322,21 @@ subroutine icepack_query_parameters( & phi_i_mushy_out ! liquid fraction of congelation ice character(len=*), intent(out), optional :: & - tfrz_option_out ! form of ocean freezing temperature - ! 'minus1p8' = -1.8 C - ! 'constant' = Tocnfrz - ! 'linear_salt' = -depressT * sss - ! 'mushy' conforms with ktherm=2 + congel_freeze_out ! congelation computation + ! 'two-step' = original formulation + ! 'one-step' = Plante et al, The Cryosphere, 2024 + + character(len=*), intent(out), optional :: & + tfrz_option_out ! form of ocean freezing temperature + ! 'minus1p8' = -1.8 C + ! 'constant' = Tocnfrz + ! 'linear_salt' = -depressT * sss + ! 'mushy' conforms with ktherm=2 character(len=*), intent(out), optional :: & - saltflux_option_out ! Salt flux computation - ! 'constant' reference value of ice_ref_salinity - ! 'prognostic' prognostic salt flux + saltflux_option_out ! Salt flux computation + ! 'constant' reference value of ice_ref_salinity + ! 'prognostic' prognostic salt flux !----------------------------------------------------------------------- @@ -1719,6 +1735,7 @@ subroutine icepack_query_parameters( & if (present(highfreq_out) ) highfreq_out = highfreq if (present(natmiter_out) ) natmiter_out = natmiter if (present(atmiter_conv_out) ) atmiter_conv_out = atmiter_conv + if (present(congel_freeze_out) ) congel_freeze_out = congel_freeze if (present(tfrz_option_out) ) tfrz_option_out = tfrz_option if (present(saltflux_option_out) ) saltflux_option_out = saltflux_option if (present(kitd_out) ) kitd_out = kitd @@ -1926,6 +1943,7 @@ subroutine icepack_write_parameters(iounit) write(iounit,*) " highfreq = ", highfreq write(iounit,*) " natmiter = ", natmiter write(iounit,*) " atmiter_conv = ", atmiter_conv + write(iounit,*) " congel_freeze = ", trim(congel_freeze) write(iounit,*) " tfrz_option= ", trim(tfrz_option) write(iounit,*) " saltflux_option = ", trim(saltflux_option) write(iounit,*) " kitd = ", kitd diff --git a/columnphysics/icepack_therm_vertical.F90 b/columnphysics/icepack_therm_vertical.F90 index 7cd9f2533..233e38546 100644 --- a/columnphysics/icepack_therm_vertical.F90 +++ b/columnphysics/icepack_therm_vertical.F90 @@ -27,7 +27,7 @@ module icepack_therm_vertical use icepack_parameters, only: ustar_min, fbot_xfer_type, formdrag, calc_strair use icepack_parameters, only: rfracmin, rfracmax, dpscale, frzpnd, snwgrain, snwlvlfac use icepack_parameters, only: phi_i_mushy, floeshape, floediam, use_smliq_pnd, snwredist - use icepack_parameters, only: saltflux_option + use icepack_parameters, only: saltflux_option, congel_freeze use icepack_parameters, only: icepack_chkoptargflag use icepack_tracers, only: tr_iage, tr_FY, tr_aero, tr_pond, tr_fsd, tr_iso @@ -46,6 +46,7 @@ module icepack_therm_vertical use icepack_mushy_physics, only: icepack_mushy_temperature_mush use icepack_mushy_physics, only: liquidus_temperature_mush use icepack_mushy_physics, only: icepack_enthalpy_mush, enthalpy_of_melting + use icepack_mushy_physics, only: enthalpy_mush_liquid_fraction, enthalpy_brine use icepack_aerosol, only: update_aerosol use icepack_isotope, only: update_isotope @@ -85,7 +86,7 @@ subroutine thermo_vertical (nilyr, nslyr, & fsnow, fpond, & fbot, Tbot, & Tsnice, sss, & - rsnw, & + sst, rsnw, & lhcoef, shcoef, & fswsfc, fswint, & Sswabs, Iswabs, & @@ -164,6 +165,7 @@ subroutine thermo_vertical (nilyr, nslyr, & real (kind=dbl_kind), intent(in) :: & fbot , & ! ice-ocean heat flux at bottom surface (W/m^2) Tbot , & ! ice bottom surface temperature (deg C) + sst , & ! sea surface temperature (C) sss ! ocean salinity ! coupler fluxes to atmosphere @@ -403,6 +405,7 @@ subroutine thermo_vertical (nilyr, nslyr, & congel, snoice, & mlt_onset, frz_onset, & zSin, sss, & + sst, & dsnow, rsnw) if (icepack_warnings_aborted(subname)) return @@ -1013,6 +1016,7 @@ subroutine thickness_changes (nilyr, nslyr, & congel, snoice, & mlt_onset, frz_onset,& zSin, sss, & + sst, & dsnow, rsnw) integer (kind=int_kind), intent(in) :: & @@ -1082,6 +1086,7 @@ subroutine thickness_changes (nilyr, nslyr, & zSin ! ice layer salinity (ppt) real (kind=dbl_kind), intent(in) :: & + sst , & ! sea surface temperature (C) sss ! ocean salinity (PSU) ! local variables @@ -1131,9 +1136,9 @@ subroutine thickness_changes (nilyr, nslyr, & qmlt ! enthalpy of melted ice (J m-3) = zero in BL99 formulation real (kind=dbl_kind) :: & - qbotm , & - qbotp , & - qbot0 , & + qbotm , & ! enthalpy of newly formed congelation ice + qbotp , & ! enthalpy needed to grow new congelation ice (includes ocean enthalpy) + qbotw , & ! enthalpy transferred to ocean during congelation freezing mass , & ! total mass from snow density tracers (kg/m^2) massi , & ! ice mass change factor tmp1 ! temporary scalar @@ -1254,15 +1259,22 @@ subroutine thickness_changes (nilyr, nslyr, & if (ktherm == 2) then - qbotm = icepack_enthalpy_mush(Tbot, sss) - qbotp = -Lfresh * rhoi * (c1 - phi_i_mushy) - qbot0 = qbotm - qbotp - - dhi = ebot_gro / qbotp ! dhi > 0 - + if (congel_freeze == 'one-step') then + ! Plante et al., The Cryosphere, 18, 1685-1708, 2024 + qbotm = enthalpy_mush_liquid_fraction(Tbot, phi_i_mushy) + qbotw = enthalpy_brine(sst) + qbotp = qbotm - qbotw + dhi = ebot_gro / qbotp ! dhi > 0 + hstot = dzi(nilyr)*zSin(nilyr) + dhi*sss*phi_i_mushy + else ! two-step + qbotm = icepack_enthalpy_mush(Tbot, sss) + qbotp = -Lfresh * rhoi * (c1 - phi_i_mushy) + qbotw = qbotm - qbotp + dhi = ebot_gro / qbotp ! dhi > 0 + hstot = dzi(nilyr)*zSin(nilyr) + dhi*sss + endif hqtot = dzi(nilyr)*zqin(nilyr) + dhi*qbotm - hstot = dzi(nilyr)*zSin(nilyr) + dhi*sss - emlt_ocn = emlt_ocn - qbot0 * dhi + emlt_ocn = emlt_ocn - qbotw * dhi else @@ -2653,7 +2665,7 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & fsnow=fsnow, fpond=fpond, & fbot=fbot, Tbot=Tbot, & Tsnice=Tsnice, sss=sss, & - rsnw=rsnw, & + sst=sst, rsnw=rsnw, & lhcoef=lhcoef, shcoef=shcoef, & fswsfc=fswsfcn (n), fswint=fswintn (n), & Sswabs=Sswabsn(:,n), Iswabs=Iswabsn (:,n), & diff --git a/configuration/driver/icedrv_init.F90 b/configuration/driver/icedrv_init.F90 index c1e738ce6..b64284104 100644 --- a/configuration/driver/icedrv_init.F90 +++ b/configuration/driver/icedrv_init.F90 @@ -99,7 +99,7 @@ subroutine input_data natmiter, kitd, kcatbound character (len=char_len) :: shortwave, albedo_type, conduct, fbot_xfer_type, & - cpl_frazil, tfrz_option, saltflux_option, & + cpl_frazil, congel_freeze, tfrz_option, saltflux_option, & frzpnd, atmbndy, wave_spec_type, snwredist, snw_aging_table logical (kind=log_kind) :: sw_redist, use_smliq_pnd, snwgrain, update_ocn_f @@ -174,12 +174,12 @@ subroutine input_data update_ocn_f, l_mpond_fresh, ustar_min, & fbot_xfer_type, oceanmixed_ice, emissivity, & formdrag, highfreq, natmiter, & - atmiter_conv, calc_dragio, & + atmiter_conv, calc_dragio, congel_freeze, & tfrz_option, saltflux_option, ice_ref_salinity, & default_season, wave_spec_type, cpl_frazil, & precip_units, fyear_init, ycycle, & atm_data_type, ocn_data_type, bgc_data_type, & - lateral_flux_type, & + lateral_flux_type, & atm_data_file, ocn_data_file, bgc_data_file, & ice_data_file, & atm_data_format, ocn_data_format, bgc_data_format, & @@ -225,6 +225,7 @@ subroutine input_data dSdt_slow_mode_out=dSdt_slow_mode, & phi_c_slow_mode_out=phi_c_slow_mode, Tliquidus_max_out=Tliquidus_max, & phi_i_mushy_out=phi_i_mushy, conserv_check_out=conserv_check, & + congel_freeze_out=congel_freeze, & tfrz_option_out=tfrz_option, saltflux_option_out=saltflux_option, & ice_ref_salinity_out=ice_ref_salinity, kalg_out=kalg, & fbot_xfer_type_out=fbot_xfer_type, puny_out=puny, & @@ -791,6 +792,7 @@ subroutine input_data write(nu_diag,1005) ' hi_min = ', hi_min write(nu_diag,1030) ' fbot_xfer_type = ', trim(fbot_xfer_type) write(nu_diag,1010) ' oceanmixed_ice = ', oceanmixed_ice + write(nu_diag,1030) ' congel_freeze = ', trim(congel_freeze) write(nu_diag,1030) ' tfrz_option = ', trim(tfrz_option) write(nu_diag,*) ' saltflux_option = ', & trim(saltflux_option) @@ -979,6 +981,7 @@ subroutine input_data dSdt_slow_mode_in=dSdt_slow_mode, & phi_c_slow_mode_in=phi_c_slow_mode, Tliquidus_max_in=Tliquidus_max, & phi_i_mushy_in=phi_i_mushy, conserv_check_in=conserv_check, & + congel_freeze_in=congel_freeze, & tfrz_option_in=tfrz_option, saltflux_option_in=saltflux_option, & ice_ref_salinity_in=ice_ref_salinity, kalg_in=kalg, & fbot_xfer_type_in=fbot_xfer_type, & diff --git a/configuration/scripts/icepack_in b/configuration/scripts/icepack_in index bbf7a5973..4ac97ad81 100644 --- a/configuration/scripts/icepack_in +++ b/configuration/scripts/icepack_in @@ -113,6 +113,7 @@ cpl_frazil = 'fresh_ice_correction' update_ocn_f = .false. l_mpond_fresh = .false. + congel_freeze = 'two-step' tfrz_option = 'mushy' ice_ref_salinity = 4.0 saltflux_option = 'constant' diff --git a/configuration/scripts/machines/env.chicoma_intel b/configuration/scripts/machines/env.chicoma_intel index 182280f95..cb7f12679 100755 --- a/configuration/scripts/machines/env.chicoma_intel +++ b/configuration/scripts/machines/env.chicoma_intel @@ -63,7 +63,7 @@ setenv ICE_MACHINE_WKDIR /lustre/scratch5/$user/ICEPACK_RUNS setenv ICE_MACHINE_INPUTDATA /usr/projects/climate/eclare/DATA/Consortium setenv ICE_MACHINE_BASELINE /lustre/scratch5/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "sbatch " -setenv ICE_MACHINE_ACCT t23_cice +setenv ICE_MACHINE_ACCT t24_cice setenv ICE_MACHINE_QUEUE "debug" setenv ICE_MACHINE_TPNODE 128 # tasks per node setenv ICE_MACHINE_BLDTHRDS 12 diff --git a/configuration/scripts/options/set_nml.congel b/configuration/scripts/options/set_nml.congel new file mode 100644 index 000000000..a71cda48b --- /dev/null +++ b/configuration/scripts/options/set_nml.congel @@ -0,0 +1 @@ + congel_freeze = 'one-step' diff --git a/configuration/scripts/tests/base_suite.ts b/configuration/scripts/tests/base_suite.ts index 43e405dab..3a68d7dd7 100644 --- a/configuration/scripts/tests/base_suite.ts +++ b/configuration/scripts/tests/base_suite.ts @@ -23,6 +23,7 @@ smoke col 1x1 debug,run1year,fluxopenw smoke col 1x1 debug,run1year,dyn,fluxopenw smoke col 1x1 debug,run1year,debug,snicartest smoke col 1x1 debug,run1year,debug,snicar +smoke col 1x1 debug,run1year,debug,congel restart col 1x1 debug restart col 1x1 diag1 restart col 1x1 pondlvl @@ -43,4 +44,5 @@ restart col 1x1 modal restart col 1x1 fluxopenw restart col 1x1 snicartest restart col 1x1 snicar +restart col 1x1 congel diff --git a/doc/source/master_list.bib b/doc/source/master_list.bib index 7ffb0a841..445bf758c 100644 --- a/doc/source/master_list.bib +++ b/doc/source/master_list.bib @@ -32,7 +32,7 @@ @string{JGR @string{JGRO = {J. Geophys. Res. Oceans}} @string{JGRB = {J. Geophys. Res. Biogeo.}} @string{JGRA = {J. Geophys. Res. Atmos.}} -@string{JCT = {J. Comput. Phys.}} +@string{TC = {The Cryosphere}} @string{QJRMS = {Quart. J. Royal Met. Soc.}} @string{GRL = {Geophys. Res. Lett.}} @string{JAS = {J. Atmos. Sci.}} @@ -244,7 +244,7 @@ @Article{Maykut95 @Article{Murray96 author = "R.J. Murray", title = "{Explicit generation of orthogonal grids for ocean models}", - journal = JCT, + journal = JCP, year = {1996}, volume = {126}, pages = {251-273}, @@ -805,13 +805,23 @@ @article{Roberts19 @article{Dang19, author = {Dang, C. and Zender, C. S. and Flanner, M. G.}, title = {Intercomparison and improvement of two-stream shortwave radiative transfer schemes in Earth system models for a unified treatment of cryospheric surfaces}, -journal = {The Cryosphere}, +journal = {TC}, volume = 13, pages = {2325--2343}, doi = {10.5194/tc-13-2325-2019}, year = {2019} } +@article{Plante24, +author = {Plante, M. and J.-F. Lemieux and L. B. Tremblay and A. Tivy and J. Angnatok and F. Roy and G. Smith and F. Dupont and A. K. Turner}, +title = {Using Icepack to reproduce ice mass balance buoy observations in landfast ice: improvements from the mushy-layer thermodynamcis}, +journal = {TC}, +volume = 18, +pages = {1685--1708}, +doi = {10.5194/tc-18-1685-2024}, +year = {20124} +} + % ********************************************** % For new entries, see example entry in BIB_TEMPLATE.txt % ********************************************** diff --git a/doc/source/science_guide/sg_thermo.rst b/doc/source/science_guide/sg_thermo.rst index d12b90cfe..1577a7e5e 100755 --- a/doc/source/science_guide/sg_thermo.rst +++ b/doc/source/science_guide/sg_thermo.rst @@ -1737,9 +1737,21 @@ conductive heat flux at the bottom surface: If ice is melting at the bottom surface, :math:`q` in Equation :eq:`bottom-melting` is the enthalpy of the bottom ice layer. If -ice is growing, :math:`q` is the enthalpy of new ice with temperature -:math:`T_f` and salinity :math:`S_{max}` (``ktherm`` = 1) or ocean surface -salinity (``ktherm`` = 2). This ice is added to the bottom layer. +ice is growing, :math:`q` is the enthalpy of new ice added to the bottom layer with +temperature :math:`T_f` and salinity :math:`S_{max}` (``ktherm`` = 1) for the Bitz99 +:cite:`Bitz99` formulation. The original mushy thermodynamics +(``ktherm`` = 2, ``congel_freeze`` = 'two-step') formed new ice in two steps, first +moving the lower ice boundary into the ocean to form a mushy layer with an initial +liquid fraction :math:`phi_{init}`, then freezing the new ice in the next step. In +this case, the freezing temperature is calculated using the ocean surface salinity +:math:`SSS`. A second mushy thermo method +(``ktherm`` = 2, ``congel_freeze`` = 'one-step') freezes the ice immediately using +the brine salinity :math:`phi_{init} * SSS` :cite:`Plante24`. +In the two-step method, enthalpy not +yet used to freeze the ice is returned to the ocean, causing frazil ice to form +instead. Together, the congelation and frazil ice add up to a similar total amount +of new ice, but the differing freezing mechanism complicates comparisons with observational +data and there is an unnecessary lag in ice-ocean coupling. In general, frazil ice formed in the ocean is added to the thinnest ice category. The new ice is grown in the open water area of the grid cell diff --git a/doc/source/user_guide/ug_case_settings.rst b/doc/source/user_guide/ug_case_settings.rst index 0b7e4fa31..cb5e5cb67 100644 --- a/doc/source/user_guide/ug_case_settings.rst +++ b/doc/source/user_guide/ug_case_settings.rst @@ -344,6 +344,8 @@ forcing_nml "``calc_strair``", "``.false.``", "read wind stress and speed from files", "``.true.``" "", "``.true.``", "calculate wind stress and speed", "" "``calc_Tsfc``", "logical", "calculate surface temperature", "``.true.``" + "``congel_freeze``", "``one-step``", "immediately freeze congelation ice", "``two-step``" + "", "``two-step``", "delayed freezing of congelation ice", "" "``cpl_frazil``", "``external``", "frazil water/salt fluxes are handled outside of Icepack", "``fresh_ice_correction``" "", "``fresh_ice_correction``", "correct fresh-ice frazil water/salt fluxes for mushy physics", "" "", "``internal``", "send full frazil water/salt fluxes for mushy physics", "" From 05ac0ec3ea666080eed36e67f6cf8ce1255b243f Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Sun, 15 Sep 2024 13:53:33 -0700 Subject: [PATCH 24/30] BGC update (#497) This is a significant update in the BGC including refactoring Icepack interfaces. Deprecate skl BGC but leave code alone for now hoping we get help from the community to validate the latest code. Add BGC parameters to icepack_parameters.F90 Update BGC physics, consistent with https://github.com/E3SM-Project/E3SM/pull/6457. Remove redundant arguments in BGC interfaces. icepack_aerosol.F90 revised subroutine update_snow_bgc icepack_algae.F90 revised subroutine zbio revised subroutine z_biogeochemistry revised subroutine algal_dyn add subroutine bgc_carbon_sum icepack_brine.F90 revise subroutine prepare_hbrine revise subroutine update_hbrine icepack_mechred.F90 add mbio calculation to subroutine ridge_shift add flux_bio calculation to subroutine ridge_ice icepack_therm_itd.F90 update calculation of dvssl and dvint in subroutine lateral_melt icepack_zbgc.F90 lots of stuff icepack_zbgc_shared.F90 lots of stuff Remove redundant arguments in non-BGC interfaces. icepack_atmo.F90 icepack_fsd.F90 icepack_isotope.F90 icepack_itd.F90 icepack_meltpond_topo.F90 icepack_mushy_physics.F90 icepack_snow.F90 icepack_therm_bl99.F90 icepack_therm_mushy.F90 icepack_therm_shared.F90 icepack_therm_vertical.F90 icepack_tracers.F90 icepack_wavefracspec.F90 Generalize merge_fluxes to make all arguments optional Fix bug in subroutine snow_redist computation of hsn_new when nslyr=1 Update the Icepack driver consistent with Icepack interface changes Update zbgc initialization in the Icepack driver, move bgc parameter intiialization to icepack_init_parameters, update icepack_init_zbgc call. Update some calls to icepack_warnings_setabort to add file and line number. Update warning package to improve OpenMP robustness. Fixes potential race conditions that show up when lots of output is produced. Modified congel implementation in subroutine thickness_changes in icepack_therm_vertical.F90 to recover bit-for-bit results. New congel and new bgc implementation were bit-for-bit independently, but when combining the changes, the intel compiler (with -O2) introduces non bit-for-bit changes (roundoff). Update bgc namelist defaults and settings in icepack_in Update bgc tracer sizing in set_env files Update testing, remove skl tests, add zaero tests. --------- Co-authored-by: Elizabeth Hunke Co-authored-by: David Bailey Co-authored-by: Nicole Jeffery --- columnphysics/icepack_aerosol.F90 | 243 ++-- columnphysics/icepack_algae.F90 | 1079 +++++++++++------ columnphysics/icepack_atmo.F90 | 7 +- columnphysics/icepack_brine.F90 | 211 ++-- columnphysics/icepack_flux.F90 | 134 +- columnphysics/icepack_fsd.F90 | 79 +- columnphysics/icepack_isotope.F90 | 6 +- columnphysics/icepack_itd.F90 | 180 +-- columnphysics/icepack_mechred.F90 | 134 +- columnphysics/icepack_meltpond_topo.F90 | 27 +- columnphysics/icepack_mushy_physics.F90 | 6 +- columnphysics/icepack_parameters.F90 | 787 +++++++++++- columnphysics/icepack_shortwave.F90 | 12 +- columnphysics/icepack_snow.F90 | 47 +- columnphysics/icepack_therm_bl99.F90 | 28 +- columnphysics/icepack_therm_itd.F90 | 204 +--- columnphysics/icepack_therm_mushy.F90 | 255 +--- columnphysics/icepack_therm_shared.F90 | 11 +- columnphysics/icepack_therm_vertical.F90 | 86 +- columnphysics/icepack_tracers.F90 | 10 +- columnphysics/icepack_warnings.F90 | 44 +- columnphysics/icepack_wavefracspec.F90 | 29 +- columnphysics/icepack_zbgc.F90 | 993 ++++++++------- columnphysics/icepack_zbgc_shared.F90 | 112 +- configuration/driver/icedrv_InitMod.F90 | 13 +- configuration/driver/icedrv_MAIN.F90 | 23 +- configuration/driver/icedrv_RunMod.F90 | 4 +- configuration/driver/icedrv_arrays_column.F90 | 15 - configuration/driver/icedrv_diagnostics.F90 | 4 +- configuration/driver/icedrv_domain_size.F90 | 1 - configuration/driver/icedrv_init.F90 | 14 +- configuration/driver/icedrv_init_column.F90 | 553 ++++----- configuration/driver/icedrv_restart.F90 | 4 +- configuration/driver/icedrv_step.F90 | 61 +- configuration/driver/icedrv_system.F90 | 22 +- configuration/scripts/icepack_in | 96 +- .../scripts/options/set_env.bgcispol | 7 +- configuration/scripts/options/set_env.bgcnice | 8 +- .../scripts/options/set_env.bgcsklnice | 2 +- configuration/scripts/options/set_env.zaero | 6 + .../scripts/options/set_nml.bgcispol | 10 +- configuration/scripts/options/set_nml.bgcnice | 10 +- configuration/scripts/options/set_nml.zaero | 3 + configuration/scripts/tests/base_suite.ts | 6 +- configuration/scripts/tests/travis_suite.ts | 3 +- doc/source/conf.py | 3 +- doc/source/master_list.bib | 23 +- doc/source/science_guide/sg_bgc.rst | 206 ++-- doc/source/user_guide/ug_case_settings.rst | 237 ++-- 49 files changed, 3378 insertions(+), 2680 deletions(-) create mode 100644 configuration/scripts/options/set_env.zaero create mode 100644 configuration/scripts/options/set_nml.zaero diff --git a/columnphysics/icepack_aerosol.F90 b/columnphysics/icepack_aerosol.F90 index 8e6a4933c..dd80a81be 100644 --- a/columnphysics/icepack_aerosol.F90 +++ b/columnphysics/icepack_aerosol.F90 @@ -8,9 +8,9 @@ module icepack_aerosol use icepack_kinds - use icepack_parameters, only: c0, c1, c2, puny, rhoi, rhos, hs_min - use icepack_parameters, only: hi_ssl, hs_ssl - use icepack_tracers, only: max_aero + use icepack_parameters, only: c0, c1, c2, p5, puny, rhoi, rhos, hs_min + use icepack_parameters, only: hi_ssl, hs_ssl, hs_ssl_min + use icepack_tracers, only: max_aero, nilyr, nslyr, nblyr, ntrcr, nbtrcr, n_aero use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted @@ -27,12 +27,10 @@ module icepack_aerosol !======================================================================= -! Increase aerosol in ice or snow surface due to deposition -! and vertical cycling +! Deposition and vertical cycling of aerosol in ice or snow +! Called from icepack_step_therm1 when tr_aero=T (not used for zbgc tracers) subroutine update_aerosol(dt, & - nilyr, nslyr, & - n_aero, & meltt, melts, & meltb, congel, & snoice, & @@ -43,9 +41,6 @@ subroutine update_aerosol(dt, & vicen, vsnon, aicen, & faero_atm, faero_ocn) - integer (kind=int_kind), intent(in) :: & - nilyr, nslyr, n_aero - real (kind=dbl_kind), intent(in) :: & dt, & ! time step meltt, & ! thermodynamic melt/growth rates @@ -128,6 +123,7 @@ subroutine update_aerosol(dt, & hs = vsnon*ar hi = vicen*ar + ! fluxes were divided by aice for thermo, not yet multiplied by aice dhs_melts = -melts dhi_snoice = snoice dhs_snoice = dhi_snoice*rhoi/rhos @@ -424,30 +420,24 @@ end subroutine update_aerosol !======================================================================= -! Increase aerosol in snow surface due to deposition -! and vertical cycling : after update_aerosol +! Aerosol in snow for vertical biogeochemistry with mushy thermodynamics +! Called from icepack_algae.F90 when z_tracers=T (replaces update_aerosol) - subroutine update_snow_bgc (dt, nblyr, & - nslyr, & + subroutine update_snow_bgc(dt, & meltt, melts, & meltb, congel, & - snoice, nbtrcr, & - fsnow, ntrcr, & + snoice, fsnow, & trcrn, bio_index, & aice_old, zbgc_snow, & vice_old, vsno_old, & vicen, vsnon, & aicen, flux_bio_atm,& - zbgc_atm, flux_bio) - - integer (kind=int_kind), intent(in) :: & - nbtrcr, & ! number of distinct snow tracers - nblyr, & ! number of bio layers - nslyr, & ! number of snow layers - ntrcr ! number of tracers + zbgc_atm, flux_bio, & + bio_index_o) integer (kind=int_kind), dimension (nbtrcr), intent(in) :: & - bio_index + bio_index, & + bio_index_o ! provides index of scavenging (kscavz) data array real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -466,9 +456,11 @@ subroutine update_snow_bgc (dt, nblyr, & vice_old, & vsno_old - real (kind=dbl_kind),dimension(nbtrcr), intent(inout) :: & + real (kind=dbl_kind), dimension(nbtrcr), intent(out) :: & zbgc_snow, & ! aerosol contribution from snow to ice - zbgc_atm, & ! and atm to ice concentration * volume (kg or mmol/m^3*m) + zbgc_atm ! and atm to ice concentration * volume (kg or mmol/m^3*m) + + real (kind=dbl_kind),dimension(nbtrcr), intent(inout) :: & flux_bio ! total ocean tracer flux (mmol/m^2/s) real (kind=dbl_kind), dimension(nbtrcr), intent(in) :: & @@ -484,6 +476,9 @@ subroutine update_snow_bgc (dt, nblyr, & real (kind=dbl_kind) :: & dzssl, dzssl_new, & ! snow ssl thickness dzint, dzint_new, & ! snow interior thickness + dz, & ! + hi, & ! ice thickness (m) + hilyr, & ! ice layer thickness (m) hs, & ! snow thickness (m) dhs_evap, & ! snow thickness change due to evap dhs_melts, & ! ... due to surface melt @@ -516,38 +511,53 @@ subroutine update_snow_bgc (dt, nblyr, & zbgc_atm(:) = c0 hs_old = vsno_old/aice_old + if (aice_old .gt. puny) then + hs_old = vsno_old/aice_old + else + hs_old = c0 + end if hslyr_old = hs_old/real(nslyr,kind=dbl_kind) - dzssl = min(hslyr_old/c2, hs_ssl) + dzssl = hslyr_old/c2 dzint = hs_old - dzssl if (aicen > c0) then ar = c1/aicen hs = vsnon*ar - dhs_melts = -melts - dhs_snoice = snoice*rhoi/rhos + hi = vicen*ar else ! ice disappeared during time step ar = c1 - hs = vsnon/aice_old - dhs_melts = -melts - dhs_snoice = snoice*rhoi/rhos + hs = c0 + hi = c0 + if (aice_old > c0) hs = vsnon/aice_old endif - + hilyr = hi/real(nblyr,kind=dbl_kind) + hslyr = hs/real(nslyr,kind=dbl_kind) + dzssl_new = hslyr/c2 + dhs_melts = -melts + dhs_snoice = snoice*rhoi/rhos dhs_evap = hs - (hs_old + dhs_melts - dhs_snoice & + fsnow/rhos*dt) ! trcrn() has units kg/m^3 - if ((vsno_old .le. puny) .or. (vsnon .le. puny)) then - + if (dzssl_new .lt. hs_ssl_min) then ! Put atm BC/dust flux directly into the sea ice do k=1,nbtrcr - flux_bio(k) = flux_bio(k) + & + flux_bio_o(k) = flux_bio(k) + if (hilyr .lt. hs_ssl_min) then + flux_bio(k) = flux_bio(k) + & (trcrn(bio_index(k)+ nblyr+1)*dzssl+ & trcrn(bio_index(k)+ nblyr+2)*dzint)/dt + flux_bio(k) = flux_bio(k) + flux_bio_atm(k) + else + zbgc_snow(k) = zbgc_snow(k) + & + (trcrn(bio_index(k)+ nblyr+1)*dzssl+ & + trcrn(bio_index(k)+ nblyr+2)*dzint) + zbgc_atm(k) = zbgc_atm(k) & + + flux_bio_atm(k)*dt + end if trcrn(bio_index(k) + nblyr+1) = c0 trcrn(bio_index(k) + nblyr+2) = c0 - zbgc_atm(k) = zbgc_atm(k) & - + flux_bio_atm(k)*dt enddo else @@ -565,6 +575,48 @@ subroutine update_snow_bgc (dt, nblyr, & !------------------------------------------------------------------- dzint = dzint + min(dzssl + dhs_evap, c0) dzssl = max(dzssl + dhs_evap, c0) + if (dzssl <= puny) then + do k = 1,nbtrcr + aerosno(k,2) = aerosno(k,2) + aerosno(k,1) + aerosno(k,1) = c0 + end do + end if + if (dzint <= puny) then + do k = 1,nbtrcr + zbgc_snow(k) = zbgc_snow(k) + (aerosno(k,2) + aerosno(k,1)) + aerosno(k,2) = c0 + aerosno(k,1) = c0 + end do + end if + + !------------------------------------------------------------------ + ! snowfall + !------------------------------------------------------------------- + if (fsnow > c0) then + sloss1 = c0 + dz = min(fsnow/rhos*dt,dzssl) + do k = 1, nbtrcr + if (dzssl > puny) & + sloss1 = aerosno(k,1)*dz/dzssl + aerosno(k,1) = max(c0,aerosno(k,1) - sloss1) + aerosno(k,2) = aerosno(k,2) + sloss1 + end do + dzssl = dzssl - dz + fsnow/rhos*dt + dzint = dzint + dz + end if + if (dzssl <= puny) then + do k = 1,nbtrcr + aerosno(k,2) = aerosno(k,2) + aerosno(k,1) + aerosno(k,1) = c0 + end do + end if + if (dzint <= puny) then + do k = 1,nbtrcr + zbgc_snow(k) = zbgc_snow(k) + (aerosno(k,2) + aerosno(k,1)) + aerosno(k,2) = c0 + aerosno(k,1) = c0 + end do + end if !------------------------------------------------------------------- ! surface snow melt @@ -573,38 +625,37 @@ subroutine update_snow_bgc (dt, nblyr, & do k = 1, nbtrcr sloss1 = c0 sloss2 = c0 - if (dzssl > puny) & - sloss1 = kscavz(k)*aerosno(k,1) & - *min(-dhs_melts,dzssl)/dzssl - aerosno(k,1) = aerosno(k,1) - sloss1 - if (dzint > puny) & - sloss2 = kscavz(k)*aerosno(k,2) & - *max(-dhs_melts-dzssl,c0)/dzint - aerosno(k,2) = aerosno(k,2) - sloss2 - zbgc_snow(k) = zbgc_snow(k) + (sloss1+sloss2) - enddo ! + if (dzssl > puny) & + sloss1 = kscavz(bio_index_o(k))*aerosno(k,1) & + *min(-dhs_melts,dzssl)/dzssl + aerosno(k,1) = max(c0,aerosno(k,1) - sloss1) + if (dzint > puny) & + sloss2 = kscavz(bio_index_o(k))*aerosno(k,2) & + *max(-dhs_melts-dzssl,c0)/dzint + aerosno(k,2) = max(c0,aerosno(k,2) - sloss2) + zbgc_snow(k) = zbgc_snow(k) + (sloss1+sloss2) ! all not scavenged ends in ice + enddo ! update snow thickness dzint=dzint+min(dzssl+dhs_melts, c0) dzssl=max(dzssl+dhs_melts, c0) - if ( dzssl <= puny ) then ! ssl melts away - aerosno(:,2) = aerosno(:,1) + aerosno(:,2) - aerosno(:,1) = c0 + if ( dzssl .le. puny ) then ! ssl melts away + do k = 1,nbtrcr + aerosno(k,2) = aerosno(k,1) + aerosno(k,2) + aerosno(k,1) = c0 + end do dzssl = max(dzssl, c0) endif - if (dzint <= puny ) then ! all snow melts away - zbgc_snow(:) = zbgc_snow(:) & - + max(c0,aerosno(:,1) + aerosno(:,2)) - aerosno(:,:) = c0 + if (dzint .le. puny ) then ! all snow melts away + do k = 1,nbtrcr + zbgc_snow(k) = zbgc_snow(k) & + + aerosno(k,1) + aerosno(k,2) + aerosno(k,:) = c0 + enddo dzint = max(dzint, c0) endif - endif - - !------------------------------------------------------------------- - ! snowfall - !------------------------------------------------------------------- - if (fsnow > c0) dzssl = dzssl + fsnow/rhos*dt + endif ! -dhs_melts > puny !------------------------------------------------------------------- ! snow-ice formation @@ -613,39 +664,41 @@ subroutine update_snow_bgc (dt, nblyr, & do k = 1, nbtrcr sloss1 = c0 sloss2 = c0 - if (dzint > puny) & - sloss2 = min(dhs_snoice, dzint) & - *aerosno(k,2)/dzint - aerosno(k,2) = aerosno(k,2) - sloss2 - if (dzssl > puny) & + if (dzint > puny .and. aerosno(k,2) > c0) & + sloss2 = min(dhs_snoice, dzint) & + *aerosno(k,2)/dzint + aerosno(k,2) = max(c0,aerosno(k,2) - sloss2) + if (dzssl > puny .and. aerosno(k,1) > c0) & sloss1 = max(dhs_snoice-dzint, c0) & *aerosno(k,1)/dzssl - aerosno(k,1) = aerosno(k,1) - sloss1 + + aerosno(k,1) = max(c0,aerosno(k,1) - sloss1) + flux_bio(k) = flux_bio(k) & + + kscavz(bio_index_o(k)) * (sloss2+sloss1)/dt zbgc_snow(k) = zbgc_snow(k) & - + (sloss2+sloss1) + + (c1-kscavz(bio_index_o(k)))*(sloss2+sloss1) enddo - dzssl = dzssl - max(dhs_snoice-dzint, c0) + dzssl = max(c0,dzssl - max(dhs_snoice-dzint, c0)) dzint = max(dzint-dhs_snoice, c0) - endif + endif ! dhs_snowice > puny !------------------------------------------------------------------- ! aerosol deposition !------------------------------------------------------------------- - if (aicen > c0) then - hs = vsnon * ar - else - hs = c0 - endif - if (hs >= hs_min) then !should this really be hs_min or 0? - ! should use same hs_min value as in radiation + ! Spread out the atm dust flux in the snow interior for small snow surface layers + if (dzssl .ge. hs_ssl*p5) then + do k=1,nbtrcr aerosno(k,1) = aerosno(k,1) & + flux_bio_atm(k)*dt enddo else + dz = (hs_ssl*p5 - dzssl)/(hs_ssl*p5) do k=1,nbtrcr - zbgc_atm(k) = zbgc_atm(k) & - + flux_bio_atm(k)*dt + aerosno(k,1) = aerosno(k,1) & + + flux_bio_atm(k)*dt*(c1-dz) + aerosno(k,2) = aerosno(k,2) & + + flux_bio_atm(k)*dt*dz enddo endif @@ -665,30 +718,31 @@ subroutine update_snow_bgc (dt, nblyr, & endif if (dzint <= puny) then ! nothing in Snow Int do k = 1, nbtrcr - zbgc_snow(k) = zbgc_snow(k) + max(c0,aerosno(k,2)) + zbgc_snow(k) = zbgc_snow(k) + max(c0,aerosno(k,2)+aerosno(k,1)) + aerosno(k,1) = c0 aerosno(k,2) = c0 enddo endif hslyr = hs/real(nslyr,kind=dbl_kind) - dzssl_new = min(hslyr/c2, hs_ssl) - dzint_new = hs - dzssl_new + dzssl_new = hslyr/c2 + dzint_new = max(c0,hs - dzssl_new) - if (hs > hs_min) then !should this really be hs_min or 0? + if (hs > hs_min) then do k = 1, nbtrcr dznew = min(dzssl_new-dzssl, c0) sloss1 = c0 - if (dzssl > puny) & + if (dzssl > puny .and. aerosno(k,1) > c0) & sloss1 = dznew*aerosno(k,1)/dzssl ! not neccesarily a loss - dznew = max(dzssl_new-dzssl, c0) - if (dzint > puny) & - sloss1 = sloss1 + aerosno(k,2)*dznew/dzint - aerosno(k,1) = aerosno(k,1) + sloss1 - aerosno(k,2) = aerosno(k,2) - sloss1 + dznew = max(dzssl_new-dzssl, c0) + if (dzint > puny .and. aerosno(k,2) > c0) & + sloss1 = aerosno(k,2)*dznew/dzint + aerosno(k,1) = max(c0,aerosno(k,1) + sloss1) + aerosno(k,2) = max(c0,aerosno(k,2) - sloss1) enddo else zbgc_snow(:) = zbgc_snow(:) & - + max(c0,aerosno(:,1) + aerosno(:,2)) + + aerosno(:,1) + aerosno(:,2) aerosno(:,:) = c0 endif @@ -701,6 +755,11 @@ subroutine update_snow_bgc (dt, nblyr, & aero_cons(k) = aerotot(k)-aerotot0(k) & - ( flux_bio_atm(k) & - (flux_bio(k)-flux_bio_o(k))) * dt + if (aerotot0(k) > aerotot(k) .and. aerotot0(k) > c0) then + aero_cons(k) = aero_cons(k)/aerotot0(k) + else if (aerotot(k) > c0) then + aero_cons(k) = aero_cons(k)/aerotot(k) + end if if (aero_cons(k) > puny .or. zbgc_snow(k) + zbgc_atm(k) < c0) then write(warnstr,*) subname, 'Conservation failure: aerosols in snow' call icepack_warnings_add(warnstr) @@ -729,18 +788,18 @@ subroutine update_snow_bgc (dt, nblyr, & !------------------------------------------------------------------- ! reload tracers !------------------------------------------------------------------- - if (vsnon > puny) then + if (dzssl_new > puny .and. dzint_new > puny .and. vsnon > puny) then do k = 1,nbtrcr trcrn(bio_index(k)+nblyr+1)=aerosno(k,1)/dzssl_new trcrn(bio_index(k)+nblyr+2)=aerosno(k,2)/dzint_new enddo else do k = 1,nbtrcr - zbgc_snow(k) = (zbgc_snow(k) + aerosno(k,1) + aerosno(k,2)) trcrn(bio_index(k)+nblyr+1)= c0 trcrn(bio_index(k)+nblyr+2)= c0 enddo endif + !------------------------------------------------------------------- ! check for negative values !------------------------------------------------------------------- diff --git a/columnphysics/icepack_algae.F90 b/columnphysics/icepack_algae.F90 index 0ffd880a2..7a958ee82 100644 --- a/columnphysics/icepack_algae.F90 +++ b/columnphysics/icepack_algae.F90 @@ -10,11 +10,11 @@ module icepack_algae use icepack_kinds - use icepack_parameters, only: p05, p5, c0, c1, c2, c6, c10 + use icepack_parameters, only: p05, p5, c0, c1, c2, c6, c10, p1 use icepack_parameters, only: pi, secday, puny use icepack_parameters, only: hs_ssl, sk_l - use icepack_parameters, only: dEdd_algae, solve_zbgc + use icepack_parameters, only: dEdd_algae, solve_zbgc, use_atm_dust_iron use icepack_parameters, only: R_dFe2dust, dustFe_sol, algal_vel use icepack_parameters, only: bgc_flux_type use icepack_parameters, only: grid_o @@ -27,11 +27,14 @@ module icepack_algae use icepack_parameters, only: y_sk_DMS , t_sk_conv use icepack_parameters, only: t_sk_ox - use icepack_tracers, only: ntrcr, bio_index + use icepack_tracers, only: nblyr, nilyr, nslyr, ntrcr, nbtrcr + use icepack_tracers, only: n_algae, n_doc, n_dic, n_don, n_fed, n_fep, n_zaero + use icepack_tracers, only: bio_index, bio_index_o use icepack_tracers, only: nt_bgc_N, nt_fbri, nt_zbgc_frac use icepack_tracers, only: tr_brine + use icepack_tracers, only: nt_bgc_DON, nt_bgc_hum, nt_bgc_DOC use icepack_tracers, only: tr_bgc_Nit, tr_bgc_Am, tr_bgc_Sil - use icepack_tracers, only: tr_bgc_DMS, tr_bgc_PON + use icepack_tracers, only: tr_bgc_DMS, tr_bgc_PON, tr_bgc_hum use icepack_tracers, only: tr_bgc_N, tr_bgc_C, tr_bgc_chl use icepack_tracers, only: tr_bgc_DON, tr_bgc_Fe, tr_zaero use icepack_tracers, only: nlt_bgc_Nit, nlt_bgc_Am, nlt_bgc_Sil @@ -39,21 +42,23 @@ module icepack_algae use icepack_tracers, only: nlt_bgc_N, nlt_bgc_C, nlt_bgc_chl use icepack_tracers, only: nlt_bgc_DOC, nlt_bgc_DON, nlt_bgc_DIC use icepack_tracers, only: nlt_zaero , nlt_bgc_DMSPp,nlt_bgc_DMSPd - use icepack_tracers, only: nlt_bgc_Fed, nlt_bgc_Fep + use icepack_tracers, only: nlt_bgc_Fed, nlt_bgc_Fep, nlt_bgc_hum use icepack_zbgc_shared, only: remap_zbgc, regrid_stationary use icepack_zbgc_shared, only: merge_bgc_fluxes use icepack_zbgc_shared, only: merge_bgc_fluxes_skl + use icepack_zbgc_shared, only: bgrid, cgrid, igrid, icgrid use icepack_zbgc_shared, only: phi_sk, bgc_tracer_type use icepack_zbgc_shared, only: zbgc_init_frac use icepack_zbgc_shared, only: zbgc_frac_init use icepack_zbgc_shared, only: tau_rel, tau_ret, thinS - use icepack_zbgc_shared, only: r_Si2N, R_Fe2N, R_S2N, R_chl2N + use icepack_zbgc_shared, only: r_Si2N, R_Fe2N, R_S2N, R_C2N_DON use icepack_zbgc_shared, only: chlabs, alpha2max_low, beta2max, mu_max use icepack_zbgc_shared, only: k_exude, K_Nit, K_Am, K_Sil, K_Fe use icepack_zbgc_shared, only: grow_Tdep, fr_graze, mort_pre, mort_Tdep use icepack_zbgc_shared, only: f_don, kn_bac, f_don_Am use icepack_zbgc_shared, only: f_doc, f_exude, k_bac, R_chl2N, R_C2N + use icepack_zbgc_shared, only: graze_exponent, graze_conc, large_bgc use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted @@ -66,63 +71,53 @@ module icepack_algae public :: zbio, sklbio real (kind=dbl_kind), parameter :: & - exp_argmax = c10 ! maximum argument of exponential - + exp_argmax = c10, & ! maximum argument of exponential + accuracy = 1.0e-13_dbl_kind ! accuracy parameter for bgc tracers !======================================================================= contains !======================================================================= - subroutine zbio (dt, nblyr, & - nslyr, nilyr, & + subroutine zbio (dt, & meltt, melts, & meltb, congel, & - snoice, nbtrcr, & - fsnow, ntrcr, & + snoice, fsnow, & trcrn, bio_index, & - aice_old, & + bio_index_o, aice_old, & vice_old, vsno_old, & vicen, vsnon, & aicen, flux_bio_atm,& - n_cat, n_algae, & - n_doc, n_dic, & - n_don, & - n_fed, n_fep, & - n_zaero, first_ice, & + n_cat, first_ice, & hice_old, ocean_bio, & + ocean_bio_dh, & bphin, iphin, & - iDin, & + iDin, & fswthrul, & dh_top, dh_bot, & zfswin, & hbri, hbri_old, & -! darcy_V, darcy_V_chl, & - darcy_V, & - bgrid, & - igrid, icgrid, & + darcy_V, & bphi_min, & - iTin, & + iTin, & Zoo, & flux_bio, dh_direct, & upNO, upNH, & fbio_snoice, fbio_atmice, & PP_net, ice_bio_net, & - snow_bio_net, grow_net ) + snow_bio_net, grow_net, & + totalChla, & + flux_bion, iSin, & + bioPorosityIceCell, & + bioSalinityIceCell, & + bioTemperatureIceCell ) integer (kind=int_kind), intent(in) :: & - nblyr, & ! number of bio layers - nslyr, & ! number of snow layers - nilyr, & ! number of ice layers - nbtrcr, & ! number of distinct bio tracers - n_cat, & ! category number - n_algae, & ! number of autotrophs - n_zaero, & ! number of aerosols - n_doc, n_dic, n_don, n_fed, n_fep, & - ntrcr ! number of tracers + n_cat ! category number integer (kind=int_kind), dimension (nbtrcr), intent(in) :: & - bio_index + bio_index, & ! references index of bio tracer (nbtrcr) to tracer array (ntrcr) + bio_index_o ! references index of data arrays (eg. kscavz) real (kind=dbl_kind), intent(in) :: & dt, & ! time step @@ -152,22 +147,19 @@ subroutine zbio (dt, nblyr, & ice_bio_net, & ! net bio tracer in ice (mmol/m^2) fbio_atmice, & ! bio flux from atm to ice (mmol/m^2/s) fbio_snoice, & ! bio flux from snow to ice (mmol/m^2/s) - flux_bio ! total ocean tracer flux (mmol/m^2/s) + flux_bio, & ! total ocean tracer flux (mmol/m^2/s) + flux_bion ! category ocean tracer flux (mmol/m^2/s) - real (kind=dbl_kind), intent(inout) :: & + real (kind=dbl_kind), intent(in) :: & hbri_old ! brine height (m) - real (kind=dbl_kind), dimension (nblyr+2), intent(inout) :: & - bgrid ! biology nondimensional vertical grid points - real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: & - igrid , & ! biology vertical interface points iTin , & ! salinity vertical interface points iphin , & ! Porosity on the igrid - iDin ! Diffusivity/h on the igrid (1/s) + iDin , & ! Diffusivity/h on the igrid (1/s) + iSin ! Salinity on vertical interface points (ppt) real (kind=dbl_kind), dimension (nilyr+1), intent(in) :: & - icgrid , & ! CICE interface coordinate fswthrul ! visible short wave radiation on icgrid (W/m^2) real (kind=dbl_kind), dimension(nbtrcr), intent(in) :: & @@ -187,6 +179,10 @@ subroutine zbio (dt, nblyr, & !change to inout when updating ocean fields ocean_bio ! ocean concentrations (mmol/m^3) + real (kind=dbl_kind), optional, dimension (:), intent(out) :: & + !change to inout when updating ocean fields + ocean_bio_dh ! ocean concentrations * hbrine * phi (mmol/m^2) + real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: & bphin ! Porosity on the bgrid @@ -196,6 +192,14 @@ subroutine zbio (dt, nblyr, & upNO , & ! tot nitrate uptake rate (mmol/m^2/d) times aice upNH ! tot ammonium uptake rate (mmol/m^2/d) times aice + real (kind=dbl_kind), optional, intent(inout):: & + totalChla ! total chla (mg chla/m^2) + + real (kind=dbl_kind), optional, dimension (:), intent(inout):: & ! diagnostics (nblyr+1) + bioPorosityIceCell , & ! porosity on vertical interface points + bioSalinityIceCell , & ! salinity on vertical interface points (ppt) + bioTemperatureIceCell ! temperature on vertical interface points (oC) + logical (kind=log_kind), intent(in) :: & first_ice ! initialized values should be used @@ -209,9 +213,6 @@ subroutine zbio (dt, nblyr, & upNHn , & ! algal ammonium uptake rate (mmol/m^3/s) grow_alg ! algal growth rate (mmol/m^3/s) - real (kind=dbl_kind), dimension (nbtrcr) :: & - flux_bion !tracer flux to ocean - real (kind=dbl_kind),dimension(nbtrcr) :: & zbgc_snown, & ! aerosol contribution from snow to ice zbgc_atmn ! and atm to ice concentration * volume (mmol/m^3*m) @@ -223,13 +224,17 @@ subroutine zbio (dt, nblyr, & real (kind=dbl_kind) :: & hsnow_i, & ! initial snow thickness (m) - hsnow_f ! final snow thickness (m) - - logical (kind=log_kind) :: & - write_flux_diag + hsnow_f, & ! final snow thickness (m) + carbonError ! carbon conservation error (mmol/m2) real (kind=dbl_kind) :: & - a_ice + carbonInitial, & ! initial carbon content (mmol/m2) + carbonFinal, & ! final carbon content (mmol/m2) + carbonFlux ! carbon flux (mmol/m2/s) + + logical (kind=log_kind) :: & + write_flux_diag, & + write_carbon_errors character(len=*),parameter :: subname='(zbio)' @@ -239,58 +244,55 @@ subroutine zbio (dt, nblyr, & flux_bio_sno(:) = c0 Tot_BGC_i (:) = c0 Tot_BGC_f (:) = c0 + Zoo (:) = c0 hsnow_i = c0 hsnow_f = c0 write_flux_diag = .false. + write_carbon_errors = .true. + if (.not. tr_bgc_C) write_carbon_errors = .false. - if (write_flux_diag) then - if (aice_old > c0) then - hsnow_i = vsno_old/aice_old - do mm = 1,nbtrcr - call bgc_column_sum (nblyr, nslyr, hsnow_i, hbri_old, & + call bgc_carbon_sum(hbri_old, trcrn(:), carbonInitial) + if (icepack_warnings_aborted(subname)) return + + if (aice_old > puny) then + hsnow_i = vsno_old/aice_old + do mm = 1,nbtrcr + call bgc_column_sum (hsnow_i, hbri_old, & trcrn(bio_index(mm):bio_index(mm)+nblyr+2), & Tot_BGC_i(mm)) - if (icepack_warnings_aborted(subname)) return - enddo - endif + if (icepack_warnings_aborted(subname)) return + enddo endif - call update_snow_bgc (dt, nblyr, & - nslyr, & + call update_snow_bgc (dt, & meltt, melts, & meltb, congel, & - snoice, nbtrcr, & - fsnow, ntrcr, & + snoice, fsnow, & trcrn, bio_index, & aice_old, zbgc_snown, & vice_old, vsno_old, & vicen, vsnon, & aicen, flux_bio_atm, & - zbgc_atmn, flux_bio_sno) + zbgc_atmn, flux_bio_sno, & + bio_index_o) + if (icepack_warnings_aborted(subname)) return call z_biogeochemistry (n_cat, dt, & - nilyr, & - nblyr, nbtrcr, & - n_algae, n_doc, & - n_dic, n_don, & - n_fed, n_fep, & - n_zaero, first_ice, & + first_ice, & aicen, vicen, & hice_old, ocean_bio, & + ocean_bio_dh, & flux_bion, bphin, & iphin, trcrn, & - iDin, & + iDin, & fswthrul, grow_alg, & upNOn, upNHn, & dh_top, dh_bot, & zfswin, hbri, & hbri_old, darcy_V, & -! darcy_V_chl, bgrid, & - bgrid, & - igrid, icgrid, & bphi_min, zbgc_snown,& - zbgc_atmn, & + zbgc_atmn, & iTin, dh_direct, & Zoo, meltb, & congel ) @@ -300,11 +302,71 @@ subroutine zbio (dt, nblyr, & flux_bion(mm) = flux_bion(mm) + flux_bio_sno(mm) enddo + call bgc_carbon_sum(hbri, trcrn(:), carbonFinal) + if (icepack_warnings_aborted(subname)) return + call bgc_carbon_flux(flux_bio_atm,flux_bion,carbonFlux) + if (icepack_warnings_aborted(subname)) return + + carbonError = carbonInitial-carbonFlux*dt-carbonFinal + + if (abs(carbonError) > max(puny,accuracy * maxval ((/carbonInitial, carbonFinal/))) .and. write_carbon_errors) then + write(warnstr,*) subname, 'carbonError:', carbonError + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'carbonInitial:', carbonInitial + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'carbonFinal:', carbonFinal + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'carbonFlux (positive into ocean):', carbonFlux + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'accuracy * maxval ((/carbonInitial, carbonFinal/:)', accuracy * maxval ((/carbonInitial, carbonFinal/)) + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'puny', puny + call icepack_warnings_add(warnstr) + if (aicen > c0) then + hsnow_f = vsnon/aicen + write(warnstr,*) subname, 'after z_biogeochemistry' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'Remaining carbon after algal_dyn: Zoo' + call icepack_warnings_add(warnstr) + do mm = 1,nblyr+1 + write(warnstr,*) subname, 'layer mm, Zoo(mm)' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, mm,Zoo(mm) + call icepack_warnings_add(warnstr) + end do + do mm = 1,nbtrcr + call bgc_column_sum (hsnow_f, hbri, & + trcrn(bio_index(mm):bio_index(mm)+nblyr+2), & + Tot_BGC_f(mm)) + write(warnstr,*) subname, 'mm, Tot_BGC_i(mm), Tot_BGC_f(mm)' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, mm, Tot_BGC_i(mm), Tot_BGC_f(mm) + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'flux_bion(mm), flux_bio_atm(mm)' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, flux_bion(mm), flux_bio_atm(mm) + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'zbgc_snown(mm),zbgc_atmn(mm)' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, zbgc_snown(mm),zbgc_atmn(mm) + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'Tot_BGC_i(mm) + flux_bio_atm(mm)*dt - flux_bion(mm)*dt' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, Tot_BGC_i(mm) + flux_bio_atm(mm)*dt - flux_bion(mm)*dt + call icepack_warnings_add(warnstr) + enddo + endif + !call icepack_warnings_add(warnstr) + !call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + call icepack_warnings_add(subname//" zbio: Carbon conservation failure after z_biogeochemistry") + endif + if (icepack_warnings_aborted(subname)) return + if (write_flux_diag) then if (aicen > c0) then hsnow_f = vsnon/aicen do mm = 1,nbtrcr - call bgc_column_sum (nblyr, nslyr, hsnow_f, hbri, & + call bgc_column_sum (hsnow_f, hbri, & trcrn(bio_index(mm):bio_index(mm)+nblyr+2), & Tot_BGC_f(mm)) write(warnstr,*) subname, 'mm, Tot_BGC_i(mm), Tot_BGC_f(mm)' @@ -326,16 +388,14 @@ subroutine zbio (dt, nblyr, & enddo endif endif - if (icepack_warnings_aborted(subname)) return - call merge_bgc_fluxes (dt, nblyr, & - nslyr, & - bio_index, n_algae, & - nbtrcr, aicen, & + call merge_bgc_fluxes (dt, & + bio_index, & + aicen, & vicen, vsnon, & - iphin, & - trcrn, & + iphin, &! ntrcr + trcrn, aice_old, &!aice_old flux_bion, flux_bio, & upNOn, upNHn, & upNO, upNH, & @@ -343,13 +403,15 @@ subroutine zbio (dt, nblyr, & fbio_snoice, fbio_atmice,& PP_net, ice_bio_net,& snow_bio_net, grow_alg, & - grow_net) + grow_net, totalChla, & + iTin, iSin, & + bioPorosityIceCell, & + bioSalinityIceCell, & + bioTemperatureIceCell) if (icepack_warnings_aborted(subname)) return if (write_flux_diag) then if (aicen > c0) then - if (n_cat .eq. 1) a_ice = c0 - a_ice = a_ice + aicen write(warnstr,*) subname, 'after merge_bgc_fluxes, n_cat:', n_cat call icepack_warnings_add(warnstr) do mm = 1,nbtrcr @@ -361,21 +423,18 @@ subroutine zbio (dt, nblyr, & call icepack_warnings_add(warnstr) write(warnstr,*) subname, 'flux_bio_atm(mm)', flux_bio_atm(mm) call icepack_warnings_add(warnstr) - write(warnstr,*) subname, 'flux_bio_atm(mm)*a_ice', flux_bio_atm(mm)*a_ice + write(warnstr,*) subname, 'flux_bio_atm(mm)*aicen', flux_bio_atm(mm)*aicen call icepack_warnings_add(warnstr) enddo endif endif + if (icepack_warnings_aborted(subname)) return end subroutine zbio !======================================================================= - subroutine sklbio (dt, ntrcr, & - nbtrcr, n_algae, & - n_doc, & - n_dic, n_don, & - n_fed, n_fep, & + subroutine sklbio (dt, Tf, & flux_bio, ocean_bio, & aicen, & meltb, congel, & @@ -384,19 +443,12 @@ subroutine sklbio (dt, ntrcr, & PP_net, upNO, & upNH, grow_net ) - integer (kind=int_kind), intent(in) :: & - nbtrcr, & ! number of distinct bio tracers - n_algae, & ! number of autotrophs - n_doc, n_dic, & ! number of dissolved organic, inorganic carbon - n_don, & ! number of dissolved organic nitrogen - n_fed, n_fep, & ! number of iron - ntrcr ! number of tracers - logical (kind=log_kind), intent(in) :: & first_ice ! initialized values should be used real (kind=dbl_kind), intent(in) :: & dt, & ! time step + Tf, & ! basal freezing temperature (C) ! hmix, & ! mixed layer depth (m) aicen, & ! ice area fraction meltb, & ! bottom melt (m) @@ -437,19 +489,16 @@ subroutine sklbio (dt, ntrcr, & grow_alg (:) = c0 call skl_biogeochemistry (dt, & - n_doc, & - n_dic, n_don, & - n_fed, n_fep, & - nbtrcr, n_algae, & flux_bion, ocean_bio, & ! hmix, aicen, & meltb, congel, & fswthru, first_ice, & trcrn, upNOn, & - upNHn, grow_alg) + upNHn, grow_alg, & + Tf) if (icepack_warnings_aborted(subname)) return - call merge_bgc_fluxes_skl (nbtrcr, n_algae, & + call merge_bgc_fluxes_skl ( & aicen, trcrn, & flux_bion, flux_bio, & PP_net, upNOn, & @@ -465,20 +514,13 @@ end subroutine sklbio ! skeletal layer biochemistry ! subroutine skl_biogeochemistry (dt, & - n_doc, & - n_dic, n_don, & - n_fed, n_fep, & - nbtrcr, n_algae, & flux_bio, ocean_bio, & ! hmix, aicen, & meltb, congel, & fswthru, first_ice, & trcrn, upNOn, & - upNHn, grow_alg_skl) - - integer (kind=int_kind), intent(in) :: & - n_doc, n_dic, n_don, n_fed, n_fep, & - nbtrcr , n_algae ! number of bgc tracers and number algae + upNHn, grow_alg_skl, & + Tf) real (kind=dbl_kind), intent(in) :: & dt , & ! time step @@ -486,6 +528,7 @@ subroutine skl_biogeochemistry (dt, & ! aicen , & ! ice area meltb , & ! bottom ice melt congel , & ! bottom ice growth + Tf , & ! bottom freezing temperature fswthru ! shortwave passing through ice to ocean logical (kind=log_kind), intent(in) :: & @@ -530,20 +573,20 @@ subroutine skl_biogeochemistry (dt, & grow_val , & ! (m/x) rphi_sk , & ! 1 / skeletal layer porosity cinit_tmp , & ! temporary variable for concentration (mmol/m^2) - Nerror ! change in total nitrogen from reactions + Cerror , & ! change in total carbon from reactions (mmol/m^3) + nitrification ! nitrate from nitrification (mmol/m^3) real (kind=dbl_kind), parameter :: & PVc = 1.e-6_dbl_kind , & ! type 'constant' piston velocity for interface (m/s) PV_scale_growth = p5 , & ! scale factor in Jin code PV during ice growth PV_scale_melt = p05 , & ! scale factor in Jin code PV during ice melt growth_max = 1.85e-5_dbl_kind , & ! PVt function reaches maximum here. (m/s) - Tin_bot = -1.8_dbl_kind , & ! temperature of the ice bottom (oC) MJ1 = 9.667e-9_dbl_kind , & ! (m/s) coefficients in Jin2008 MJ2 = 38.8_dbl_kind , & ! (1) from:4.49e-4_dbl_kind*secday MJ3 = 1.04e7_dbl_kind , & ! 1/(m/s) from: 1.39e-3_dbl_kind*secday^2 PV_frac_max = 0.9_dbl_kind ! Maximum Piston velocity is 90% of skeletal layer/dt - logical (kind=log_kind) :: conserve_N + logical (kind=log_kind) :: conserve_C character(len=*),parameter :: subname='(skl_biogeochemistry)' @@ -551,11 +594,12 @@ subroutine skl_biogeochemistry (dt, & ! Initialize !----------------------------------------------------------------- - conserve_N = .true. + conserve_C = .true. Zoo_skl = c0 rphi_sk = c1/phi_sk PVt = c0 - iTin = Tin_bot + iTin = Tf + ice_growth = (congel-meltb)/dt do nn = 1, nbtrcr cinit (nn) = c0 @@ -577,10 +621,6 @@ subroutine skl_biogeochemistry (dt, & cling (nn) = c1 endif - ice_growth = (congel-meltb)/dt - if (first_ice) then - trcrn(bio_index(nn)) = ocean_bio(nn) ! * sk_l*rphi_sk - endif ! first_ice cinit (nn) = trcrn(bio_index(nn)) * sk_l * rphi_sk cinit_v(nn) = cinit(nn)/sk_l if (cinit(nn) < c0) then @@ -588,7 +628,7 @@ subroutine skl_biogeochemistry (dt, & nn,nbtrcr,cinit(nn) call icepack_warnings_add(warnstr) call icepack_warnings_add(subname//' cinit < c0') - call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + !call icepack_warnings_setabort(.true.,__FILE__,__LINE__) return endif enddo ! nbtrcr @@ -657,16 +697,16 @@ subroutine skl_biogeochemistry (dt, & react(:) = c0 grow_alg_skl(:) = c0 - call algal_dyn (dt, & - n_doc, n_dic, n_don, n_fed, n_fep, & - dEdd_algae, & + call algal_dyn (dt, & + dEdd_algae, & fswthru, react, & - cinit_v, & - grow_alg_skl(:), n_algae, & + cinit_v, & + grow_alg_skl(:), & iTin, & - upNOn(:), upNHn(:), & + upNOn(:), upNHn(:), & Zoo_skl, & - Nerror, conserve_N) + Cerror, conserve_C,& + nitrification) if (icepack_warnings_aborted(subname)) return !----------------------------------------------------------------- @@ -697,8 +737,8 @@ subroutine skl_biogeochemistry (dt, & ! Currently not coupled with ocean biogeochemistry ! ocean_bio(nn) = ocean_bio(nn) + flux_bio(nn)/hmix*aicen - if (.not. conserve_N) then - write(warnstr,*) subname, 'N not conserved in skl_bgc, Nerror:',Nerror + if (.not. conserve_C) then + write(warnstr,*) subname, 'C not conserved in skl_bgc, Cerror:',Cerror call icepack_warnings_add(warnstr) write(warnstr,*) subname, 'sk_bgc < 0 after algal fluxes, nn,cinit,flux_bio',& nn,cinit(nn),flux_bio(nn) @@ -711,7 +751,7 @@ subroutine skl_biogeochemistry (dt, & write(warnstr,*) subname, 'congel, meltb: ',congel,meltb call icepack_warnings_add(warnstr) call icepack_warnings_add(subname//' N not conserved in skl_bgc') - call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + !call icepack_warnings_setabort(.true.,__FILE__,__LINE__) elseif (cinit(nn) < c0) then write(warnstr,*) subname, 'sk_bgc < 0 after algal fluxes, nn,cinit,flux_bio',& nn,cinit(nn),flux_bio(nn) @@ -724,7 +764,7 @@ subroutine skl_biogeochemistry (dt, & write(warnstr,*) subname, 'congel, meltb: ',congel,meltb call icepack_warnings_add(warnstr) call icepack_warnings_add(subname//'sk_bgc < 0 after algal fluxes') - call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + !call icepack_warnings_setabort(.true.,__FILE__,__LINE__) endif if (icepack_warnings_aborted(subname)) return @@ -751,38 +791,26 @@ end subroutine skl_biogeochemistry ! subroutine z_biogeochemistry (n_cat, dt, & - nilyr, & - nblyr, nbtrcr, & - n_algae, n_doc, & - n_dic, n_don, & - n_fed, n_fep, & - n_zaero, first_ice, & + first_ice, & aicen, vicen, & hice_old, ocean_bio, & + ocean_bio_dh, & flux_bio, bphin, & iphin, trcrn, & - iDin, & + iDin, & fswthrul, grow_alg, & upNOn, upNHn, & dh_top, dh_bot, & zfswin, hbri, & hbri_old, darcy_V, & -! darcy_V_chl, bgrid, & - bgrid, & - i_grid, ic_grid, & bphi_min, zbgc_snow, & - zbgc_atm, & + zbgc_atm, & iTin, dh_direct, & Zoo, meltb, & congel ) integer (kind=int_kind), intent(in) :: & - n_cat, & ! category number - nilyr, & ! number of ice layers - nblyr, & ! number of bio layers - nbtrcr, n_algae, & ! number of bgc tracers, number of autotrophs - n_zaero, & ! number of aerosols - n_doc, n_dic, n_don, n_fed, n_fep + n_cat ! category number logical (kind=log_kind), intent(in) :: & first_ice ! initialized values should be used @@ -797,13 +825,11 @@ subroutine z_biogeochemistry (n_cat, dt, & meltb , & ! bottom melt in dt (m) congel , & ! bottom growth in dt (m) darcy_V , & ! darcy velocity -! darcy_V_chl, & ! darcy velocity for algae dh_bot , & ! change in brine bottom (m) dh_top , & ! change in brine top (m) dh_direct ! surface flooding or runoff (m) real (kind=dbl_kind), dimension (:), intent(inout) :: & - bgrid , & ! biology nondimensional vertical grid points flux_bio , & ! total ocean tracer flux (mmol/m^2/s) zfswin , & ! visible Short wave flux on igrid (W/m^2) Zoo , & ! N losses to the system from reaction terms @@ -811,18 +837,19 @@ subroutine z_biogeochemistry (n_cat, dt, & trcrn ! bulk tracer concentration (mmol/m^3) real (kind=dbl_kind), dimension (:), intent(in) :: & - i_grid , & ! biology vertical interface points iTin , & ! salinity vertical interface points iphin , & ! Porosity on the igrid iDin , & ! Diffusivity/h on the igrid (1/s) - ic_grid , & ! CICE interface coordinate fswthrul , & ! visible short wave radiation on icgrid (W/m^2) zbgc_snow , & ! tracer input from snow (mmol/m^3*m) zbgc_atm , & ! tracer input from atm (mmol/m^3 *m) ocean_bio , & ! ocean concentrations (mmol/m^3) bphin ! Porosity on the bgrid - real (kind=dbl_kind), intent(inout) :: & + real (kind=dbl_kind), optional, dimension (:), intent(out) :: & + ocean_bio_dh ! ocean concentrations * hbrine * phi (mmol/m^2) + + real (kind=dbl_kind), intent(in) :: & hbri_old ! brine height (m) real (kind=dbl_kind), dimension (:,:), intent(out) :: & @@ -846,6 +873,7 @@ subroutine z_biogeochemistry (n_cat, dt, & hin , & ! ice thickness (m) hin_old , & ! ice thickness before current melt/growth (m) ice_conc , & ! algal concentration in ice above hin > hinS + sum_initial , & ! sum_old , & ! sum_new , & ! sum_tot , & ! @@ -869,7 +897,7 @@ subroutine z_biogeochemistry (n_cat, dt, & D_spdiag , & ! artificial diffusion matrix D_sbdiag , & ! artificial diffusion matrix biomat_low , & ! Low order solution - Nerror ! Change in N after reactions + Cerror ! Change in N after reactions real (kind=dbl_kind), dimension(nblyr+1,nbtrcr):: & react ! biological sources and sinks for equation matrix @@ -897,7 +925,7 @@ subroutine z_biogeochemistry (n_cat, dt, & trtmp ! temporary, remapped tracers logical (kind=log_kind), dimension(nblyr+1) :: & - conserve_N + conserve_C real (kind=dbl_kind), dimension(nblyr+1):: & ! temporary variables for Diff , & ! diffusivity @@ -905,7 +933,9 @@ subroutine z_biogeochemistry (n_cat, dt, & biocons , & ! new concentration dmobile , & ! initcons_mobile,&! - initcons_stationary + initcons_stationary, & + dz , & ! normalized vertical grid spacing + nitrification ! nitrate produced from nitrification (mmol/m3) real (kind=dbl_kind):: & top_conc ! 1% (min_bgc) of surface concentration @@ -924,20 +954,21 @@ subroutine z_biogeochemistry (n_cat, dt, & V_alg ! volume of algae (um^3) real (kind=dbl_kind), dimension(nbtrcr) :: & - mobile ! c1 if mobile, c0 otherwise + mobile , & ! c1 if mobile, c0 otherwise + flux_bio_tmp ! local parameters real (kind=dbl_kind), parameter :: & - accuracy = 1.0e-14_dbl_kind, & r_c = 3.0e3_dbl_kind , & ! ice crystal radius (um) - r_bac= 15.0_dbl_kind , & ! diatom large radius (um) + r_bac= 4.7_dbl_kind , & ! diatom large radius (um) r_alg= 10.0_dbl_kind , & ! diatom small radius (um) - N_vol = 0.04e-12_dbl_kind , & ! (g) Nitrogen per um^3 - Ng_to_mmol =0.0140067_dbl_kind , & ! (g/mmol) Nitrogen - f_s = c1 , & ! fracton of sites available for saturation - f_a = c1 , & ! fraction of collector available for attachment - f_v = 0.7854 ! fraction of algal coverage on area availabel for attachment + Nquota_A = 0.88_dbl_kind, & ! slope in Nitrogen quota to cell volume fit + ! (Lomas et al. 2019, Edwards et al. 2012) + Nquota_I = 0.0408_dbl_kind, & ! Intercept in N quota to cell volume fit + f_s = p1, & ! fracton of sites available for saturation + f_a = 0.3_dbl_kind, & !c1 , & ! fraction of collector available for attachment + f_v = 0.7854_dbl_kind ! fraction of algal coverage on area availabel for attachment ! 4(pi r^2)/(4r)^2 [Johnson et al, 1995, water res. research] integer, parameter :: & @@ -945,19 +976,32 @@ subroutine z_biogeochemistry (n_cat, dt, & character(len=*),parameter :: subname='(z_biogeochemistry)' + logical (kind=log_kind) :: & + write_carbon_errors + !------------------------------------- ! Initialize !----------------------------------- + write_carbon_errors = .true. + if (.not. tr_bgc_C) write_carbon_errors = .false. + zspace = c1/real(nblyr,kind=dbl_kind) + dz(:) = zspace + dz(1) = zspace/c2 + dz(nblyr+1) = zspace/c2 in_init_cons(:,:) = c0 atm_add_cons(:) = c0 dhtop = c0 dhbot = c0 darcyV = c0 C_top(:) = c0 + C_bot(:) = c0 + if (present(ocean_bio_dh)) ocean_bio_dh(:) = c0 mobile(:) = c0 - conserve_N(:) = .true. + conserve_C(:) = .true. + nitrification(:) = c0 + flux_bio_tmp(:) = c0 do m = 1, nbtrcr do k = 1, nblyr+1 @@ -967,15 +1011,13 @@ subroutine z_biogeochemistry (n_cat, dt, & iphin_N(k) = iphin(k) bphin_N(1) = bphi_min - if (first_ice) then - trcrn(bio_index(m) + k-1) = ocean_bio(m)*zbgc_init_frac(m) - in_init_cons(k,m) = trcrn(bio_index(m) + k-1)*hbri_old - elseif (abs(trcrn(bio_index(m) + k-1)) < puny) then + if (abs(trcrn(bio_index(m) + k-1)) < accuracy) then + flux_bio_tmp(m) = trcrn(bio_index(m) + k-1)* hbri_old * dz(k)/dt trcrn(bio_index(m) + k-1) = c0 in_init_cons(k,m) = c0 else in_init_cons(k,m) = trcrn(bio_index(m) + k-1)* hbri_old - endif ! first_ice + endif if (trcrn(bio_index(m) + k-1) < c0 ) then write(warnstr,*) subname,'zbgc initialization error, first ice = ', first_ice @@ -991,7 +1033,7 @@ subroutine z_biogeochemistry (n_cat, dt, & write(warnstr,*) subname, trcrn(bio_index(m) + k-1) call icepack_warnings_add(warnstr) call icepack_warnings_add(subname//' zbgc initialization error') - call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + !call icepack_warnings_setabort(.true.,__FILE__,__LINE__) endif if (icepack_warnings_aborted(subname)) return enddo !k @@ -1012,18 +1054,17 @@ subroutine z_biogeochemistry (n_cat, dt, & phi_max = maxval(bphin_N(2:nblyr+1)) S_col = 4.0_dbl_kind*pi*r_c**2 P_b = pi*r_bac**2 !*10-6 for colloids - V_c = 4.0_dbl_kind*pi*r_c**3/3.0_dbl_kind*(1.0e-6_dbl_kind)**3 ! (m^3) sphere + V_c = 4.0_dbl_kind*pi*r_c**3/3.0_dbl_kind ! (m^3) sphere V_alg = pi/6.0_dbl_kind*r_bac*r_alg**2 ! prolate spheroid (*10-9 for colloids) - Sat_conc= f_s*f_a*f_v*(c1-phi_max)/V_c*S_col/P_b*N_vol*V_alg/Ng_to_mmol - !mmol/m^3 (algae, don, hum...) and umols/m^3 for colloids - + Sat_conc= f_s*f_a*f_v*(c1-phi_max)/V_c*S_col/P_b*(V_alg)**Nquota_A*Nquota_I * 1.0e9_dbl_kind + !mmol/m^3 (algae, don, hum...) and umols/m^3 for colloids !----------------------------------------------------------------- ! convert surface dust flux (n_zaero > 2) to dFe(1) flux !----------------------------------------------------------------- dust_Fe(:) = c0 - if (tr_zaero .and. n_zaero > 2 .and. tr_bgc_Fe) then + if (tr_zaero .and. n_zaero > 2 .and. tr_bgc_Fe .and. use_atm_dust_iron) then do m = 3,n_zaero dust_Fe(nlt_bgc_Fed(1)) = dust_Fe(nlt_bgc_Fed(1)) + & (zbgc_snow(nlt_zaero(m)) + zbgc_atm(nlt_zaero(m))) * & @@ -1080,6 +1121,7 @@ subroutine z_biogeochemistry (n_cat, dt, & endif C_bot(m) = ocean_bio(m)*hbri_old*iphin_N(nblyr+1) + if (present(ocean_bio_dh)) ocean_bio_dh(m) = C_bot(m) enddo ! m @@ -1103,8 +1145,8 @@ subroutine z_biogeochemistry (n_cat, dt, & trtmp0(1:ntrcr), trtmp(1:ntrcr+2), & 0, nblyr+1, & hin, hbri, & - ic_grid(1:nilyr+1), & - i_grid(1:nblyr+1),ice_conc ) + icgrid(1:nilyr+1), & + igrid(1:nblyr+1),ice_conc ) if (icepack_warnings_aborted(subname)) return @@ -1134,14 +1176,16 @@ subroutine z_biogeochemistry (n_cat, dt, & if (hbri_old > thinS .and. hbri > thinS) then do k = 1,nblyr+1 initcons_mobile(k) = in_init_cons(k,mm)*trcrn(nt_zbgc_frac+mm-1) - initcons_stationary(k) = mobile(mm)*(in_init_cons(k,mm)-initcons_mobile(k)) + initcons_stationary(k) = max(c0,in_init_cons(k,mm)-initcons_mobile(k)) + ! Allow release of Nitrate/silicate to mobile phase, but not adsorption dmobile(k) = mobile(mm)*(initcons_mobile(k)*(exp_ret(mm)-c1) + & - initcons_stationary(k)*(c1-exp_rel(mm))) + initcons_stationary(k)*(c1-exp_rel(mm))) + & + (1-mobile(mm))*initcons_stationary(k)*(c1-exp_rel(mm)) initcons_mobile(k) = max(c0,initcons_mobile(k) + dmobile(k)) initcons_stationary(k) = max(c0,initcons_stationary(k) - dmobile(k)) if (initcons_stationary(k)/hbri_old > Sat_conc) then initcons_mobile(k) = initcons_mobile(k) + initcons_stationary(k) - Sat_conc*hbri_old - initcons_stationary(k) = Sat_conc*hbri_old + initcons_stationary(k) = Sat_conc*hbri_old endif Diff(k) = iDin(k) @@ -1150,9 +1194,9 @@ subroutine z_biogeochemistry (n_cat, dt, & enddo call compute_FCT_matrix & - (initcons,sbdiagz, dt, nblyr, & - diagz, spdiagz, rhsz, bgrid, & - darcyV, dhtop, & + (initcons,sbdiagz, dt, & + diagz, spdiagz, rhsz, & + darcyV, dhtop, & dhbot, iphin_N, & Diff, hbri_old, & atm_add_cons(mm), bphin_N, & @@ -1177,13 +1221,11 @@ subroutine z_biogeochemistry (n_cat, dt, & Sink_bot(mm), & Sink_top(mm), & dt, flux_bio(mm), & - nblyr, & source(mm)) if (icepack_warnings_aborted(subname)) return call compute_FCT_corr & - (initcons, & - biocons, dt, nblyr, & + (initcons, biocons, dt, & D_sbdiag, D_spdiag, ML_diag) if (icepack_warnings_aborted(subname)) return @@ -1196,9 +1238,8 @@ subroutine z_biogeochemistry (n_cat, dt, & call regrid_stationary & (initcons_stationary, hbri_old, & hbri, dt, & - ntrcr, & - nblyr, top_conc, & - i_grid, flux_bio(mm),& + top_conc, & + igrid, flux_bio(mm),& meltb, congel) if (icepack_warnings_aborted(subname)) return @@ -1208,9 +1249,8 @@ subroutine z_biogeochemistry (n_cat, dt, & call regrid_stationary & (initcons_stationary, hbri_old, & hbri, dt, & - ntrcr, & - nblyr, top_conc, & - i_grid, flux_bio(mm),& + top_conc, & + igrid, flux_bio(mm),& meltb, congel) if (icepack_warnings_aborted(subname)) return @@ -1219,40 +1259,38 @@ subroutine z_biogeochemistry (n_cat, dt, & biomat_cons(:,mm) = biocons(:) + initcons_stationary(:) + sum_initial = (in_init_cons(1,mm) + in_init_cons(nblyr+1,mm))*zspace/c2 sum_old = (biomat_low(1) + biomat_low(nblyr+1))*zspace/c2 sum_new = (biocons(1)+ biocons(nblyr+1))*zspace/c2 sum_tot = (biomat_cons(1,mm) + biomat_cons(nblyr+1,mm))*zspace/c2 do k = 2,nblyr + sum_initial = sum_initial + in_init_cons(k,mm)*zspace sum_old = sum_old + biomat_low(k)*zspace sum_new = sum_new + biocons(k)*zspace sum_tot = sum_tot + biomat_cons(k,mm)*zspace enddo trcrn(nt_zbgc_frac+mm-1) = zbgc_frac_init(mm) - if (sum_tot > c0 .and. mobile(mm) > c0) trcrn(nt_zbgc_frac+mm-1) = sum_new/sum_tot + if (sum_tot > c0) trcrn(nt_zbgc_frac+mm-1) = sum_new/sum_tot - if (abs(sum_new-sum_old) > accuracy*sum_old .or. & - minval(biocons(:)) < c0 .or. minval(initcons_stationary(:)) < c0 & + if ((abs((sum_initial-sum_tot+source(mm))/dt-flux_bio(mm)) > max(puny, accuracy*abs(flux_bio(mm)))) & + .or. (minval(biocons(:)) < c0) .or. (minval(initcons_stationary(:)) < c0) & .or. icepack_warnings_aborted()) then - write(warnstr,*) subname,'zbgc FCT tracer solution failed' + write(warnstr,*) subname,'zbgc FCT tracer solution failed, mm:', mm call icepack_warnings_add(warnstr) - write(warnstr,*) subname,'sum_new,sum_old:',sum_new,sum_old + write(warnstr,*)'sum_new,sum_tot,sum_initial,flux_bio(mm),source(mm):' call icepack_warnings_add(warnstr) - write(warnstr,*) subname,'mm,biocons(:):',mm,biocons(:) + write(warnstr,*)sum_new,sum_tot,sum_initial,flux_bio(mm),source(mm) call icepack_warnings_add(warnstr) - write(warnstr,*) subname,'biomat_low:',biomat_low + write(warnstr,*)'error = (sum_initial-sum_tot+source(mm))/dt-flux_bio(mm)' call icepack_warnings_add(warnstr) - write(warnstr,*) subname,'Diff(:):',Diff(:) + write(warnstr,*)(sum_initial-sum_tot+source(mm))/dt-flux_bio(mm) call icepack_warnings_add(warnstr) - write(warnstr,*) subname,'dmobile(:):',dmobile(:) + write(warnstr,*) subname,'sum_new,sum_old:',sum_new,sum_old call icepack_warnings_add(warnstr) write(warnstr,*) subname,'mobile(mm):',mobile(mm) call icepack_warnings_add(warnstr) - write(warnstr,*) subname,'initcons_stationary(:):',initcons_stationary(:) - call icepack_warnings_add(warnstr) write(warnstr,*) subname, 'trcrn(nt_zbgc_frac+mm-1):',trcrn(nt_zbgc_frac+mm-1) call icepack_warnings_add(warnstr) - write(warnstr,*) subname, 'in_init_cons(:,mm):',in_init_cons(:,mm) - call icepack_warnings_add(warnstr) write(warnstr,*) subname, 'exp_ret( mm),exp_rel( mm)',exp_ret( mm),exp_rel( mm) call icepack_warnings_add(warnstr) write(warnstr,*) subname,'darcyV,dhtop,dhbot' @@ -1262,7 +1300,7 @@ subroutine z_biogeochemistry (n_cat, dt, & write(warnstr,*) subname,'Category,mm:',n_cat,mm call icepack_warnings_add(warnstr) call icepack_warnings_add(subname//'zbgc FCT tracer solution failed') - call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + !call icepack_warnings_setabort(.true.,__FILE__,__LINE__) endif if (icepack_warnings_aborted(subname)) return @@ -1270,7 +1308,7 @@ subroutine z_biogeochemistry (n_cat, dt, & call thin_ice_flux(hbri,hbri_old,biomat_cons(:,mm), & flux_bio(mm),source(mm), & - dt, nblyr,ocean_bio(mm)) + dt, ocean_bio(mm)) if (icepack_warnings_aborted(subname)) return endif ! thin or not @@ -1285,16 +1323,16 @@ subroutine z_biogeochemistry (n_cat, dt, & if (solve_zbgc) then do k = 1, nblyr+1 - call algal_dyn (dt, & - n_doc, n_dic, n_don, n_fed, n_fep, & - dEdd_algae, & + call algal_dyn (dt, & + dEdd_algae, & zfswin(k), react(k,:), & - biomat_brine(k,:), & - grow_alg(k,:), n_algae, & + biomat_brine(k,:), & + grow_alg(k,:), & iTin(k), & upNOn(k,:), upNHn(k,:), & Zoo(k), & - Nerror(k), conserve_N(k)) + Cerror(k), conserve_C(k), & + nitrification(k)) if (icepack_warnings_aborted(subname)) return enddo ! k @@ -1304,14 +1342,46 @@ subroutine z_biogeochemistry (n_cat, dt, & ! Update the tracer variable !----------------------------------------------------------------- + sum_new = c0 + sum_tot = c0 + do m = 1,nbtrcr do k = 1,nblyr+1 ! back to bulk quantity bio_tmp = (biomat_brine(k,m) + react(k,m))*iphin_N(k) - if (.not. conserve_N(k)) then - write(warnstr,*) subname, 'N in algal_dyn not conserved' + if (tr_bgc_C .and. m .eq. nlt_bgc_DIC(1) .and. bio_tmp .le. -accuracy) then ! satisfy DIC demands from ocean + !Uncomment for additional diagnostics + !write(warnstr,*) subname, 'DIC demand from ocean' + !call icepack_warnings_add(warnstr) + !write(warnstr,*) subname, 'm, k, nlt_bgc_DIC(1), bio_tmp, react(k,m):' + !call icepack_warnings_add(warnstr) + !write(warnstr,*) subname, m, k, nlt_bgc_DIC(1), bio_tmp, react(k,m) + !call icepack_warnings_add(warnstr) + !write(warnstr,*) subname, 'flux_bio(m), hbri, hbri_old:' + !call icepack_warnings_add(warnstr) + !write(warnstr,*) subname, flux_bio(m), hbri, hbri_old + !call icepack_warnings_add(warnstr) + flux_bio(m) = flux_bio(m) + bio_tmp*dz(k)*hbri/dt + bio_tmp = c0 + !write(warnstr,*) subname, 'flux_bio(m) Final:' + !call icepack_warnings_add(warnstr) + !write(warnstr,*) subname, flux_bio(m) + !call icepack_warnings_add(warnstr) + end if + if (m .eq. nlt_bgc_Nit) then + initcons_mobile(k) = max(c0,(biomat_brine(k,m)-nitrification(k) + & + react(k,m))*iphin_N(k)*trcrn(nt_zbgc_frac+m-1)) + initcons_stationary(k) = max(c0,((c1-trcrn(nt_zbgc_frac+m-1))*(biomat_brine(k,m)- & + nitrification(k) + react(k,m)) + nitrification(k))*iphin_N(k)) + + sum_new = sum_new + initcons_mobile(k)*dz(k) + sum_tot = sum_tot + (initcons_mobile(k) + initcons_stationary(k))*dz(k) + + end if ! m .eq. nlt_bgc_Nit + if (.not. conserve_C(k) .and. write_carbon_errors) then + write(warnstr,*) subname, 'C in algal_dyn not conserved' call icepack_warnings_add(warnstr) - write(warnstr,*) subname, 'Nerror(k):', Nerror(k) + write(warnstr,*) subname, 'Cerror(k):', Cerror(k) call icepack_warnings_add(warnstr) write(warnstr,*) subname, 'k,m,hbri,hbri_old,bio_tmp,biomat_cons(k,m),ocean_bio(m)' call icepack_warnings_add(warnstr) @@ -1321,11 +1391,12 @@ subroutine z_biogeochemistry (n_cat, dt, & call icepack_warnings_add(warnstr) write(warnstr,*) subname, react(k,m),iphin_N(k),biomat_brine(k,m) call icepack_warnings_add(warnstr) - call icepack_warnings_add(subname//' N in algal_dyn not conserved') - call icepack_warnings_setabort(.true.,__FILE__,__LINE__) - elseif (abs(bio_tmp) < puny) then + call icepack_warnings_add(subname//' C in algal_dyn not conserved') + !call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + elseif (abs(bio_tmp) < accuracy) then + flux_bio(m) = flux_bio(m) + bio_tmp*dz(k)*hbri/dt bio_tmp = c0 - elseif (bio_tmp > 1.0e6_dbl_kind) then + elseif (bio_tmp > large_bgc) then write(warnstr,*) subname, 'very large bgc value' call icepack_warnings_add(warnstr) write(warnstr,*) subname, 'k,m,hbri,hbri_old,bio_tmp,biomat_cons(k,m),ocean_bio(m)' @@ -1337,7 +1408,7 @@ subroutine z_biogeochemistry (n_cat, dt, & write(warnstr,*) subname, react(k,m),iphin_N(k),biomat_brine(k,m) call icepack_warnings_add(warnstr) call icepack_warnings_add(subname//' very large bgc value') - call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + !call icepack_warnings_setabort(.true.,__FILE__,__LINE__) elseif (bio_tmp < c0) then write(warnstr,*) subname, 'negative bgc' call icepack_warnings_add(warnstr) @@ -1356,38 +1427,28 @@ subroutine z_biogeochemistry (n_cat, dt, & write(warnstr,*) subname, 'exp_ret( m),exp_ret( m)',exp_ret( m),exp_ret( m) call icepack_warnings_add(warnstr) call icepack_warnings_add(subname//'negative bgc') - call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + !call icepack_warnings_setabort(.true.,__FILE__,__LINE__) endif + trcrn(bio_index(m)+k-1) = max(c0, bio_tmp) if (icepack_warnings_aborted()) then write(warnstr,*) subname, 'trcrn(nt_zbgc_frac+m-1):',trcrn(nt_zbgc_frac+m-1) call icepack_warnings_add(warnstr) write(warnstr,*) subname, 'in_init_cons(k,m):',in_init_cons(k,m) call icepack_warnings_add(warnstr) - write(warnstr,*) subname, 'trcrn(bio_index(m) + k-1)' + write(warnstr,*) subname, 'trcrn(bio_index(m) + k-1), bio_tmp' call icepack_warnings_add(warnstr) - write(warnstr,*) subname, trcrn(bio_index(m) + k-1) + write(warnstr,*) subname, trcrn(bio_index(m) + k-1), bio_tmp call icepack_warnings_add(warnstr) write(warnstr,*) subname, 'Category,m:',n_cat,m call icepack_warnings_add(warnstr) return endif - trcrn(bio_index(m)+k-1) = max(c0, bio_tmp) - if (ocean_bio(m) .le. c0 .and. flux_bio(m) < c0) then - ! if (flux_bio(m) < -1.0e-12_dbl_kind) then - ! write(warnstr,*) subname, 'no ocean_bio but flux_bio < c0' - ! call icepack_warnings_add(warnstr) - ! write(warnstr,*) subname, 'm,ocean_bio(m),flux_bio(m)' - ! call icepack_warnings_add(warnstr) - ! write(warnstr,*) subname, m,ocean_bio(m),flux_bio(m) - ! call icepack_warnings_add(warnstr) - ! write(warnstr,*) subname, 'setting flux_bio(m) = c0' - ! call icepack_warnings_add(warnstr) - ! call icepack_warnings_add(subname//' flux_bio < 0 when ocean_bio = 0') - ! call icepack_warnings_setabort(.true.,__FILE__,__LINE__) - ! endif - flux_bio(m) = max(c0,flux_bio(m)) - endif enddo ! k + if (m .eq. nlt_bgc_Nit .and. MAXVAL(nitrification) > c0) then + trcrn(nt_zbgc_frac+m-1) = zbgc_frac_init(m) + if (sum_tot > c0) trcrn(nt_zbgc_frac+m-1) = sum_new/sum_tot + end if + flux_bio(m) = flux_bio(m) + flux_bio_tmp(m) enddo ! m end subroutine z_biogeochemistry @@ -1398,20 +1459,16 @@ end subroutine z_biogeochemistry ! authors: Scott Elliott, LANL ! Nicole Jeffery, LANL - subroutine algal_dyn (dt, & - n_doc, n_dic, n_don, n_fed, n_fep, & - dEdd_algae, & + subroutine algal_dyn (dt, & + dEdd_algae, & fswthru, reactb, & - ltrcrn, & - grow_alg, n_algae, & + ltrcrn, & + grow_alg, & T_bot, & upNOn, upNHn, & Zoo, & - Nerror, conserve_N) - - integer (kind=int_kind), intent(in) :: & - n_doc, n_dic, n_don, n_fed, n_fep, & - n_algae ! number of autotrophic types + Cerror, conserve_C, & + nitrification) real (kind=dbl_kind), intent(in) :: & dt , & ! time step @@ -1420,7 +1477,8 @@ subroutine algal_dyn (dt, & real (kind=dbl_kind), intent(inout) :: & Zoo, & ! N losses from zooplankton/bacteria... (mmol/m^3) - Nerror ! Change in N after reactions (mmol/m^3) + Cerror, & ! Change in C after reactions (mmol/m^3) + nitrification ! nitrate produced through nitrification (mmol/m3) real (kind=dbl_kind), dimension (:), intent(out) :: & grow_alg,& ! algal growth rate (mmol/m^3/s) @@ -1434,7 +1492,7 @@ subroutine algal_dyn (dt, & ltrcrn ! brine concentrations in layer (mmol/m^3) logical (kind=log_kind), intent(inout) :: & - conserve_N + conserve_C logical (kind=log_kind), intent(in) :: & dEdd_algae ! .true. chla impact on shortwave computed in dEdd @@ -1451,21 +1509,18 @@ subroutine algal_dyn (dt, & ! nt_bgc_Sil -> silicate, nt_bgc_Fe -> dissolved iron ! -------------------------------------------------------------------------------------- -! real (kind=dbl_kind), parameter, dimension(max_algae) :: & -! alpha2max_high = (/ 0.25_dbl_kind, 0.25_dbl_kind, 0.25_dbl_kind/) ! light limitation (1/(W/m^2)) - integer (kind=int_kind) :: k, n real (kind=dbl_kind), dimension(n_algae) :: & Nin , & ! algal nitrogen concentration on volume (mmol/m^3) -! Cin , & ! algal carbon concentration on volume (mmol/m^3) + Cin , & ! algal carbon concentration on volume (mmol/m^3) chlin ! algal chlorophyll concentration on volume (mg/m^3) real (kind=dbl_kind), dimension(n_doc) :: & DOCin ! dissolved organic carbon concentration on volume (mmolC/m^3) -! real (kind=dbl_kind), dimension(n_dic) :: & -! DICin ! dissolved inorganic carbon concentration on volume (mmolC/m^3) + real (kind=dbl_kind), dimension(n_dic) :: & + DICin ! dissolved inorganic carbon concentration on volume (mmolC/m^3) real (kind=dbl_kind), dimension(n_don) :: & !proteins DONin ! dissolved organic nitrogen concentration on volume (mmolN/m^3) @@ -1483,7 +1538,7 @@ subroutine algal_dyn (dt, & ! DMSPpin , & ! DMSPp concentration on volume (mmol/m^3) DMSPdin , & ! DMSPd concentration on volume (mmol/m^3) DMSin , & ! DMS concentration on volume (mmol/m^3) -! PONin , & ! PON concentration on volume (mmol/m^3) + ! PONin , & ! PON concentration on volume (mmol/m^3) op_dep , & ! bottom layer attenuation exponent (optical depth) Iavg_loc ! bottom layer attenuated Fswthru (W/m^2) @@ -1498,7 +1553,6 @@ subroutine algal_dyn (dt, & fr_Am , & ! fraction of local ecological growth as ammonia growmax_N, & ! maximum growth rate in N currency (mmol/m^3/s) grow_N , & ! true growth rate in N currency (mmol/m^3/s) -! potU_Nit , & ! potential nitrate uptake (mmol/m^3/s) potU_Am , & ! potential ammonium uptake (mmol/m^3/s) U_Nit , & ! actual nitrate uptake (mmol/m^3/s) U_Am , & ! actual ammonium uptake (mmol/m^3/s) @@ -1523,11 +1577,6 @@ subroutine algal_dyn (dt, & exude_C , & ! total carbon exuded by algae (mmol C/m^3) resp_N , & ! total N in respiration (mmol N/m^3) growth_N ! total algal growth (mmol N/m^3) -! fr_graze_p , & ! fraction of N grazed that becomes protein -! ! (rest is assimilated) < (1-fr_graze_a) -! ! and fr_graze_a*fr_graze_e becomes ammonia -! fr_mort_p ! fraction of N mortality that becomes protein -! ! < (1-fr_mort2min) real (kind=dbl_kind), dimension(n_algae) :: & resp , & ! respiration (mmol/m^3/s) @@ -1544,6 +1593,10 @@ subroutine algal_dyn (dt, & DOC_r , & ! net DOC removal (mmol/m^3) DOC_s ! net DOC sources (mmol/m^3) + real (kind=dbl_kind), dimension(n_dic) :: & + DIC_r , & ! net DIC removal (mmol/m^3) + DIC_s ! net DIC sources (mmol/m^3) + real (kind=dbl_kind), dimension(n_don) :: & DON_r , & ! net DON removal (mmol/m^3) DON_s ! net DON sources (mmol/m^3) @@ -1561,12 +1614,12 @@ subroutine algal_dyn (dt, & real (kind=dbl_kind) :: & dN , & ! change in N (mmol/m^3) -! N_s_p , & ! algal nitrogen photosynthesis (mmol/m^3) -! N_r_g , & ! algal nitrogen losses to grazing (mmol/m^3) -! N_r_r , & ! algal nitrogen losses to respiration (mmol/m^3) -! N_r_mo , & ! algal nitrogen losses to mortality (mmol/m^3) + dC , & ! change in Carbon (mmol C/m^3) + N_s_p , & ! algal nitrogen photosynthesis (mmol/m^3) + N_r_g , & ! algal nitrogen losses to grazing (mmol/m^3) + N_r_r , & ! algal nitrogen losses to respiration (mmol/m^3) + N_r_mo , & ! algal nitrogen losses to mortality (mmol/m^3) Nit_s_n , & ! nitrate from nitrification (mmol/m^3) -! Nit_s_r , & ! nitrate from respiration (mmol/m^3) Nit_r_p , & ! nitrate uptake by algae (mmol/m^3) Nit_s , & ! net nitrate sources (mmol/m^3) Nit_r , & ! net nitrate removal (mmol/m^3) @@ -1609,19 +1662,18 @@ subroutine algal_dyn (dt, & ! Initialize !----------------------------------------------------------------------- - conserve_N = .true. + conserve_C = .true. Nin(:) = c0 -! Cin(:) = c0 + Cin(:) = c0 chlin(:) = c0 DOCin(:) = c0 -! DICin(:) = c0 + DICin(:) = c0 DONin(:) = c0 Fedin(:) = c0 Fepin(:) = c0 Nitin = c0 Amin = c0 Silin = c0 -! DMSPpin = c0 DMSPdin = c0 DMSin = c0 U_Am_tot = c0 @@ -1634,7 +1686,6 @@ subroutine algal_dyn (dt, & U_Fe_f(:) = c0 DOC_s(:) = c0 DOC_r(:) = c0 -! DOC_r_c = c0 nitrif = c0 mort_N = c0 mort_C = c0 @@ -1658,9 +1709,11 @@ subroutine algal_dyn (dt, & Fed_tot_s = c0 rFed(:) = c0 Fep_tot = c0 -! Fep_tot_r = c0 Fep_tot_s = c0 rFep(:) = c0 + DIC_r(:) = c0 + DIC_s(:) = c0 + Zoo = c0 Nitin = ltrcrn(nlt_bgc_Nit) op_dep = c0 @@ -1676,9 +1729,9 @@ subroutine algal_dyn (dt, & do k = 1, n_doc DOCin(k)= ltrcrn(nlt_bgc_DOC(k)) enddo -! do k = 1, n_dic -! DICin(k)= ltrcrn(nlt_bgc_DIC(k)) -! enddo + do k = 1, n_dic + DICin(k)= ltrcrn(nlt_bgc_DIC(k)) + enddo endif if (tr_bgc_Am) Amin = ltrcrn(nlt_bgc_Am) if (tr_bgc_Sil) Silin = ltrcrn(nlt_bgc_Sil) @@ -1687,10 +1740,10 @@ subroutine algal_dyn (dt, & DMSPdin = ltrcrn(nlt_bgc_DMSPd) DMSin = ltrcrn(nlt_bgc_DMS) endif -! if (tr_bgc_PON) then +! if (tr_bgc_PON) then ! PONin = c0 ! PONin = ltrcrn(nlt_bgc_PON) -! endif +! endif if (tr_bgc_DON) then do k = 1, n_don DONin(k) = ltrcrn(nlt_bgc_DON(k)) @@ -1773,7 +1826,11 @@ subroutine algal_dyn (dt, & !---------------------------------------------------------------------------- growmax_N(k) = mu_max(k) / secday * exp(grow_Tdep(k) * dTemp)* Nin(k) *fsal - grow_N(k) = min(L_lim(k), N_lim(k), Sil_lim(k), Fe_lim(k)) * growmax_N(k) + if (n_fed == 0) then + grow_N(k) = min(L_lim(k), N_lim(k), Sil_lim(k)) * growmax_N(k) + else + grow_N(k) = min(L_lim(k), N_lim(k), Sil_lim(k), Fe_lim(k)) * growmax_N(k) + endif ! potU_Nit(k) = Nit_lim(k)* growmax_N(k) potU_Am(k) = Am_lim(k)* growmax_N(k) U_Am(k) = min(grow_N(k), potU_Am(k)) @@ -1804,10 +1861,12 @@ subroutine algal_dyn (dt, & U_Sil(k) = U_Sil_f(k)*U_Sil_tot U_Fe(k) = U_Fe_f(k)*U_Fe_tot - if (R_Si2N(k) > c0) then - grow_N(k) = min(U_Sil(k)/R_Si2N(k),U_Nit(k) + U_Am(k), U_Fe(k)/R_Fe2N(k)) - else - grow_N(k) = min(U_Nit(k) + U_Am(k),U_Fe(k)/R_Fe2N(k)) + if (n_fed == 0) then + if (R_Si2N(k) > c0) then + grow_N(k) = min(U_Sil(k)/R_Si2N(k),U_Nit(k) + U_Am(k), U_Fe(k)/R_Fe2N(k)) + else + grow_N(k) = min(U_Nit(k) + U_Am(k),U_Fe(k)/R_Fe2N(k)) + endif endif fr_Am(k) = c0 @@ -1834,11 +1893,13 @@ subroutine algal_dyn (dt, & !-------------------------------------------------------------------- ! Algal reaction term - ! N_react = (grow_N*(c1 - fr_graze-fr_resp) - mort)*dt + ! v1: N_react = (grow_N*(c1 - fr_graze-fr_resp) - mort)*dt + ! v2: N_react = (grow_N*(c1 - fr_graze * (N/graze_conc)**graze_exp-fr_resp) - mort)*dt + ! with maximum grazing less than max_loss * Nin(k)/dt !-------------------------------------------------------------------- resp(k) = fr_resp * grow_N(k) - graze(k) = fr_graze(k) * grow_N(k) + graze(k) = min(max_loss * Nin(k)/dt, grow_N(k) * fr_graze(k) * (Nin(k)/graze_conc)**graze_exponent(k)) mort(k) = min(max_loss * Nin(k)/dt, & mort_pre(k)*exp(mort_Tdep(k)*dTemp) * Nin(k)/secday) @@ -1847,13 +1908,12 @@ subroutine algal_dyn (dt, & upNOn(k) = U_Nit(k) upNHn(k) = U_Am(k) -! N_s_p = grow_N(k) * dt -! N_r_g = graze(k) * dt -! N_r_r = resp(k) * dt -! N_r_mo = mort(k) * dt - N_s(k) = (c1- fr_resp - fr_graze(k)) * grow_N(k) *dt !N_s_p - N_r(k) = mort(k) * dt !N_r_g + N_r_mo + N_r_r - + N_s_p = grow_N(k) * dt + N_r_g = graze(k) * dt + N_r_r = resp(k) * dt + N_r_mo = mort(k) * dt + N_s(k) = N_s_p + N_r(k) = N_r_g + N_r_mo + N_r_r graze_N = graze_N + graze(k) graze_C = graze_C + R_C2N(k)*graze(k) mort_N = mort_N + mort(k) @@ -1885,16 +1945,18 @@ subroutine algal_dyn (dt, & Fe_r_p = U_Fe (k) * dt Fed_tot_r = Fed_tot_r + Fe_r_p exude_C = exude_C + k_exude(k)* R_C2N(k)*Nin(k) / secday + DIC_r(1) = DIC_r(1) + (c1-fr_resp)*grow_N(k) * R_C2N(k) * dt enddo !-------------------------------------------------------------------- ! nitrification !-------------------------------------------------------------------- - nitrif = k_nitrif /secday * Amin - Am_r = Am_r + nitrif*dt - Nit_s_n = nitrif * dt ! source from NH4 - Nit_s = Nit_s_n + nitrification = c0 + nitrif = k_nitrif /secday * Amin + Am_r = Am_r + nitrif*dt + Nit_s_n = nitrif * dt ! source from NH4 + Nit_s = Nit_s_n !-------------------------------------------------------------------- ! PON: currently using PON to shadow nitrate @@ -1928,10 +1990,11 @@ subroutine algal_dyn (dt, & if (tr_bgc_DON) then do n = 1, n_don DON_r(n) = kn_bac(n)/secday * DONin(n) * dt - DON_s(n) = graze_N*f_don(n)*fr_graze_s * dt + DON_s(n) = graze_N*dt - Am_s_e + mort_N*dt - Am_s_mo Zoo_s_s = Zoo_s_s - DON_s(n) Zoo_s_b = Zoo_s_b + DON_r(n)*(c1-f_don_Am(n)) - !Am_s = Am_s + DON_r(n)*f_don_Am(n) + Am_s = Am_s + DON_r(n)*f_don_Am(n) + DIC_s(1) = DIC_s(1) + DON_r(n) * R_C2N_DON(n) enddo endif @@ -1945,8 +2008,10 @@ subroutine algal_dyn (dt, & do n = 1, n_doc DOC_r(n) = k_bac(n)/secday * DOCin(n) * dt - DOC_s(n) = f_doc(n)*(fr_graze_s *graze_C + mort_C)*dt & - + f_exude(n)*exude_C +! DOC_s(n) = f_doc(n)*(fr_graze_s *graze_C + mort_C)*dt & +! + f_exude(n)*exude_C + DOC_s(n) = f_doc(n) * (graze_C*dt + mort_C*dt - DON_s(1) * R_C2N_DON(1)) + DIC_s(1) = DIC_s(1) + DOC_r(n) enddo !-------------------------------------------------------------------- @@ -1963,16 +2028,16 @@ subroutine algal_dyn (dt, & if (tr_bgc_C .and. tr_bgc_Fe) then if (DOCin(1) > c0) then - if (Fed_tot/DOCin(1) > max_dfe_doc1) then - do n = 1,n_fed ! low saccharid:dFe ratio leads to - Fed_r_l(n) = Fedin(n)/t_iron_conv*dt/secday ! loss of bioavailable Fe to particulate fraction - Fep_tot_s = Fep_tot_s + Fed_r_l(n) - Fed_r(n) = Fed_r_l(n) ! removal due to particulate scavenging - enddo - do n = 1,n_fep - Fep_s(n) = rFep(n)* Fep_tot_s ! source from dissolved Fe - enddo - elseif (Fed_tot/DOCin(1) < max_dfe_doc1) then + !if (Fed_tot/DOCin(1) > max_dfe_doc1) then + ! do n = 1,n_fed ! low saccharid:dFe ratio leads to + ! Fed_r_l(n) = Fedin(n)/t_iron_conv*dt/secday ! loss of bioavailable Fe to particulate fraction + ! Fep_tot_s = Fep_tot_s + Fed_r_l(n) + ! Fed_r(n) = Fed_r_l(n) ! removal due to particulate scavenging + ! enddo + ! do n = 1,n_fep + ! Fep_s(n) = rFep(n)* Fep_tot_s ! source from dissolved Fe + ! enddo + if (Fed_tot/DOCin(1) < max_dfe_doc1) then do n = 1,n_fep ! high saccharid:dFe ratio leads to Fep_r(n) = Fepin(n)/t_iron_conv*dt/secday ! gain of bioavailable Fe from particulate fraction Fed_tot_s = Fed_tot_s + Fep_r(n) @@ -1982,7 +2047,8 @@ subroutine algal_dyn (dt, & enddo endif endif !Docin(1) > c0 - elseif (tr_bgc_Fe) then + endif + if (tr_bgc_Fe) then do n = 1,n_fed Fed_r(n) = Fed_r(n) + rFed(n)*Fed_tot_r ! scavenging + uptake enddo @@ -2032,9 +2098,11 @@ subroutine algal_dyn (dt, & !----------------------------------------------------------------------- dN = c0 + dC = c0 do k = 1,n_algae reactb(nlt_bgc_N(k)) = N_s(k) - N_r(k) dN = dN + reactb(nlt_bgc_N(k)) + dC = dC + reactb(nlt_bgc_N(k)) * R_C2N(k) enddo if (tr_bgc_C) then ! do k = 1,n_algae @@ -2042,10 +2110,16 @@ subroutine algal_dyn (dt, & ! enddo do k = 1,n_doc reactb(nlt_bgc_DOC(k))= DOC_s(k) - DOC_r(k) + dC = dC + reactb(nlt_bgc_DOC(k)) + enddo + do k = 1,n_dic + reactb(nlt_bgc_DIC(k))= DIC_s(k) - DIC_r(k) + dC = dC + reactb(nlt_bgc_DIC(k)) enddo endif - reactb(nlt_bgc_Nit) = Nit_s - Nit_r - dN = dN + reactb(nlt_bgc_Nit) + reactb(nlt_bgc_Nit) = Nit_s - Nit_r + nitrification = Nit_s_n + dN = dN + reactb(nlt_bgc_Nit) if (tr_bgc_Am) then reactb(nlt_bgc_Am) = Am_s - Am_r dN = dN + reactb(nlt_bgc_Am) @@ -2057,8 +2131,10 @@ subroutine algal_dyn (dt, & do k = 1,n_don reactb(nlt_bgc_DON(k))= DON_s(k) - DON_r(k) dN = dN + reactb(nlt_bgc_DON(k)) + dC = dC + reactb(nlt_bgc_DON(k)) * R_C2N_DON(k) enddo endif + Cerror = dC if (tr_bgc_Fe ) then do k = 1,n_fed reactb(nlt_bgc_Fed(k))= Fed_s (k) - Fed_r (k) @@ -2071,25 +2147,75 @@ subroutine algal_dyn (dt, & reactb(nlt_bgc_DMSPd) = DMSPd_s - DMSPd_r reactb(nlt_bgc_DMS) = DMS_s - DMS_r endif - Nerror = dN + Zoo - ! if (abs(Nerror) > max(reactb(:))*1.0e-5) then - ! conserve_N = .false. - ! write(warnstr,*) subname, 'Conservation error!' - ! call icepack_warnings_add(warnstr) - ! write(warnstr,*) subname, 'Nerror,dN, DONin(1),kn_bac(1),secday,dt,n_doc' - ! call icepack_warnings_add(warnstr) - ! write(warnstr,*) subname, Nerror,dN, DONin(1),kn_bac(1),secday,dt,n_doc - ! call icepack_warnings_add(warnstr) - ! write(warnstr,*) subname, 'reactb(nlt_bgc_Nit),reactb(nlt_bgc_N(1)),reactb(nlt_bgc_N(2)' - ! call icepack_warnings_add(warnstr) - ! write(warnstr,*) subname, reactb(nlt_bgc_Nit),reactb(nlt_bgc_N(1)),reactb(nlt_bgc_N(2)) - ! call icepack_warnings_add(warnstr) - ! write(warnstr,*) subname, 'reactb(nlt_bgc_Am),reactb(nlt_bgc_DON(1)), DON_r(1),DON_s(1)' - ! call icepack_warnings_add(warnstr) - ! write(warnstr,*) subname, reactb(nlt_bgc_Am),reactb(nlt_bgc_DON(1)),DON_r(1),DON_s(1) - ! call icepack_warnings_add(warnstr) - ! write(warnstr,*) subname, 'Zoo:',Zoo - ! endif + + if (tr_bgc_C) then + if (abs(dC) > max(puny,maxval(abs(reactb(:)))*accuracy) .or. & + abs(dN) > max(puny,maxval(abs(reactb(:)))*accuracy)) then + conserve_C = .false. + write(warnstr,*) subname, 'Conservation error!' + call icepack_warnings_add(warnstr) + if (tr_bgc_DON) then + write(warnstr,*) subname, 'dN,DONin(1), kn_bac(1),secday,dt,n_doc' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, dN, DONin(1),kn_bac(1),secday,dt,n_doc + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'reactb(nlt_bgc_DON(1)), DON_r(1),DON_s(1)' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, reactb(nlt_bgc_DON(1)),DON_r(1),DON_s(1) + call icepack_warnings_add(warnstr) + end if + write(warnstr,*) subname, 'dN,secday,dt,n_doc' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, dN,secday,dt,n_doc + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'reactb(nlt_bgc_Nit),reactb(nlt_bgc_N(n_algae))' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, reactb(nlt_bgc_Nit),reactb(nlt_bgc_N(n_algae)) + call icepack_warnings_add(warnstr) + if (tr_bgc_Am) then + write(warnstr,*) subname, 'reactb(nlt_bgc_Am),Am_r, Am_s' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, reactb(nlt_bgc_Am),Am_r, Am_s + call icepack_warnings_add(warnstr) + end if + write(warnstr,*) subname, 'dC' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, dC + call icepack_warnings_add(warnstr) + do k = 1,n_doc + write(warnstr,*) subname, 'DOCin' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, DOCin(k) + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'reactb(nlt_bgc_DOC)' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, reactb(nlt_bgc_DOC(k)) + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'DOC_r(k),DOC_s(k),k' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, DOC_r(k),DOC_s(k),k + call icepack_warnings_add(warnstr) + end do + do k = 1,n_dic + write(warnstr,*) subname, 'DICin' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, DICin(k) + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'reactb(nlt_bgc_DIC)' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, reactb(nlt_bgc_DIC(k)) + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'DIC_r(k),DIC_s(k),k' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, DIC_r(k),DIC_s(k),k + call icepack_warnings_add(warnstr) + end do + write(warnstr,*) subname, 'Zoo' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, Zoo + call icepack_warnings_add(warnstr) + endif + endif end subroutine algal_dyn @@ -2101,11 +2227,7 @@ end subroutine algal_dyn ! authors Nicole Jeffery, LANL subroutine thin_ice_flux (hin, hin_old, Cin, flux_o_tot, & - source, dt, nblyr, & - ocean_bio) - - integer (kind=int_kind), intent(in) :: & - nblyr ! number of bio layers + source, dt, ocean_bio) real (kind=dbl_kind), dimension(nblyr+1), intent(inout) :: & Cin ! initial concentration*hin_old*phin @@ -2141,7 +2263,7 @@ subroutine thin_ice_flux (hin, hin_old, Cin, flux_o_tot, & sum_bio = c0 dh = hin-hin_old - if (dh .le. c0) then ! keep the brine concentration fixed + if (dh .le. c0 .and. hin_old > puny) then ! keep the brine concentration fixed sum_bio = (Cin(1)+Cin(nblyr+1))/hin_old*zspace*p5 Cin(1) = Cin(1)/hin_old*hin Cin(nblyr+1) = Cin(nblyr+1)/hin_old*hin @@ -2149,7 +2271,7 @@ subroutine thin_ice_flux (hin, hin_old, Cin, flux_o_tot, & sum_bio = sum_bio + Cin(k)/hin_old*zspace Cin(k) = Cin(k)/hin_old*hin + dC enddo - else + else ! spread evenly in ice layers dC = dh*ocean_bio do k = 1, nblyr+1 Cin(k) = Cin(k) + dC @@ -2167,21 +2289,18 @@ end subroutine thin_ice_flux ! ! July, 2014 by N. Jeffery ! - subroutine compute_FCT_matrix (C_in, sbdiag, dt, nblyr, & - diag, spdiag, rhs, bgrid, & - darcyV, dhtop, dhbot, & + subroutine compute_FCT_matrix (C_in, sbdiag, dt, & + diag, spdiag, rhs, & + darcyV, dhtop, dhbot, & iphin_N, iDin, hbri_old, & atm_add, bphin_N, & C_top, C_bot, Qbot, Qtop, & Sink_bot, Sink_top, & D_sbdiag, D_spdiag, ML) - integer (kind=int_kind), intent(in) :: & - nblyr ! number of bio layers - real (kind=dbl_kind), dimension(nblyr+1), intent(in) :: & C_in ! Initial (bulk) concentration*hbri_old (mmol/m^2) - ! conserved quantity on i_grid + ! conserved quantity on igrid real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -2193,8 +2312,7 @@ subroutine compute_FCT_matrix (C_in, sbdiag, dt, nblyr, & iphin_N ! Porosity with min condition on igrid real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: & - bphin_N, & ! Porosity with min condition on igrid - bgrid + bphin_N ! Porosity with min condition on igrid real (kind=dbl_kind), dimension (nblyr+1), intent(out) :: & sbdiag , & ! sub-diagonal matrix elements @@ -2366,11 +2484,8 @@ end subroutine compute_FCT_matrix ! ! July, 2014 by N. Jeffery ! - subroutine compute_FCT_corr (C_in, C_low, dt, nblyr, & - D_sbdiag, D_spdiag, ML) - - integer (kind=int_kind), intent(in) :: & - nblyr ! number of bio layers + subroutine compute_FCT_corr(C_in, C_low, dt, & + D_sbdiag, D_spdiag, ML) real (kind=dbl_kind), dimension(nblyr+1), intent(in) :: & C_in ! Initial (bulk) concentration*hbri_old (mmol/m^2) @@ -2494,7 +2609,7 @@ end subroutine compute_FCT_corr ! authors William H. Lipscomb, LANL ! C. M. Bitz, UW ! - subroutine tridiag_solverz (nmat, sbdiag, & + subroutine tridiag_solverz(nmat, sbdiag, & diag, spdiag, & rhs, xout) @@ -2544,11 +2659,7 @@ end subroutine tridiag_solverz subroutine check_conservation_FCT (C_init, C_new, C_low, S_top, & S_bot, L_bot, L_top, dt, & - fluxbio, nblyr, & - source) - - integer (kind=int_kind), intent(in) :: & - nblyr ! number of bio layers + fluxbio, source) real (kind=dbl_kind), dimension(nblyr+1), intent(in) :: & C_init , & ! initial bulk concentration * h_old (mmol/m^2) @@ -2578,7 +2689,8 @@ subroutine check_conservation_FCT (C_init, C_new, C_low, S_top, & C_init_tot , & C_new_tot , & zspace , & !1/nblyr - accuracy ! centered difference is Order(zspace^2) + accuracyC , & ! centered difference is Order(zspace^2) + var_tmp ! temporary variable character(len=*),parameter :: subname='(check_conservation_FCT)' @@ -2598,33 +2710,82 @@ subroutine check_conservation_FCT (C_init, C_new, C_low, S_top, & C_low(k) = C_new(k) enddo - accuracy = 1.0e-14_dbl_kind*max(c1, C_init_tot, C_new_tot) - fluxbio = (C_init_tot - C_new_tot + source)/dt + accuracyC = 1.0e-11_dbl_kind*max(c1, C_init_tot, C_new_tot) + fluxbio = fluxbio + (C_init_tot - C_new_tot + source)/dt diff_dt =C_new_tot - C_init_tot - (S_top+S_bot+L_bot*C_new(nblyr+1)+L_top*C_new(1))*dt if (minval(C_low) < c0) then write(warnstr,*) subname, 'Positivity of zbgc low order solution failed: C_low:',C_low - call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + call icepack_warnings_add(warnstr) + !call icepack_warnings_setabort(.true.,__FILE__,__LINE__) endif - if (abs(diff_dt) > accuracy ) then - call icepack_warnings_setabort(.true.,__FILE__,__LINE__) - write(warnstr,*) subname, 'Conservation of zbgc low order solution failed: diff_dt:',& - diff_dt - write(warnstr,*) subname, 'Total initial tracer', C_init_tot - write(warnstr,*) subname, 'Total final1 tracer', C_new_tot - write(warnstr,*) subname, 'bottom final tracer', C_new(nblyr+1) - write(warnstr,*) subname, 'top final tracer', C_new(1) - write(warnstr,*) subname, 'Near bottom final tracer', C_new(nblyr) - write(warnstr,*) subname, 'Near top final tracer', C_new(2) - write(warnstr,*) subname, 'Top flux*dt into ice:', S_top*dt - write(warnstr,*) subname, 'Bottom flux*dt into ice:', S_bot*dt - write(warnstr,*) subname, 'Remaining bot flux*dt into ice:', L_bot*C_new(nblyr+1)*dt + if (abs(diff_dt) > accuracyC ) then + write(warnstr,*) subname, '' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'Conservation of zbgc low order solution failed: diff_dt:' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, diff_dt + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'Total initial tracer' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, C_init_tot + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'Total final1 tracer' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, C_new_tot + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'bottom final tracer' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, C_new(nblyr+1) + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'top final tracer' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, C_new(1) + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'Near bottom final tracer' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, C_new(nblyr) + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'Near top final tracer' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, C_new(2) + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'Top flux*dt into ice:' + call icepack_warnings_add(warnstr) + var_tmp = S_top*dt + write(warnstr,*) subname, var_tmp + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'Bottom flux*dt into ice:' + call icepack_warnings_add(warnstr) + var_tmp = S_bot*dt + write(warnstr,*) subname, var_tmp + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'Remaining bot flux*dt into ice:' + call icepack_warnings_add(warnstr) + var_tmp = L_bot*C_new(nblyr+1)*dt + write(warnstr,*) subname, var_tmp + call icepack_warnings_add(warnstr) write(warnstr,*) subname, 'S_bot*dt + L_bot*C_new(nblyr+1)*dt' - write(warnstr,*) subname, S_bot*dt + L_bot*C_new(nblyr+1)*dt - write(warnstr,*) subname, 'fluxbio*dt:', fluxbio*dt - write(warnstr,*) subname, 'fluxbio:', fluxbio - write(warnstr,*) subname, 'Remaining top flux*dt into ice:', L_top*C_new(1)*dt + call icepack_warnings_add(warnstr) + var_tmp = S_bot*dt + L_bot*C_new(nblyr+1)*dt + write(warnstr,*) subname, var_tmp + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'fluxbio*dt:' + call icepack_warnings_add(warnstr) + var_tmp = fluxbio*dt + write(warnstr,*) subname, var_tmp + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'fluxbio:' + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, fluxbio + call icepack_warnings_add(warnstr) + write(warnstr,*) subname, 'Remaining top flux*dt into ice:' + call icepack_warnings_add(warnstr) + var_tmp = L_top*C_new(1)*dt + write(warnstr,*) subname, var_tmp + call icepack_warnings_add(warnstr) + !call icepack_warnings_setabort(.true.,__FILE__,__LINE__) endif end subroutine check_conservation_FCT @@ -2635,11 +2796,7 @@ end subroutine check_conservation_FCT ! ! author: Nicole Jeffery, LANL - subroutine bgc_column_sum (nblyr, nslyr, hsnow, hbrine, xin, xout) - - integer (kind=int_kind), intent(in) :: & - nblyr, & ! number of ice layers - nslyr ! number of snow layers + subroutine bgc_column_sum (hsnow, hbrine, xin, xout) real (kind=dbl_kind), dimension(nblyr+3), intent(in) :: & xin ! input field @@ -2665,7 +2822,7 @@ subroutine bgc_column_sum (nblyr, nslyr, hsnow, hbrine, xin, xout) character(len=*),parameter :: subname='(bgc_column_sum)' hslyr = hsnow/real(nslyr,kind=dbl_kind) - dzssl = min(hslyr*p5, hs_ssl) + dzssl = hslyr*p5 dzint = max(c0,hsnow - dzssl) zspace = c1/real(nblyr,kind=dbl_kind) @@ -2678,6 +2835,138 @@ subroutine bgc_column_sum (nblyr, nslyr, hsnow, hbrine, xin, xout) end subroutine bgc_column_sum +!======================================================================= + +! Find the total carbon concentration by summing the appropriate +! biogeochemical tracers in units of mmol C/m2 +! +! author: Nicole Jeffery, LANL + + subroutine bgc_carbon_sum (hbrine, xin, xout) + + real (kind=dbl_kind), dimension(:), intent(in) :: & + xin ! input field, all tracers and column + + real (kind=dbl_kind), intent(in) :: & + hbrine ! brine height + + real (kind=dbl_kind), intent(out) :: & + xout ! output field mmol/m2 carbon + + ! local variables + + real (kind=dbl_kind), dimension(nblyr+1) :: & + zspace ! brine layer thickness/hbrine + + integer (kind=int_kind) :: & + n, m, iBioCount, iLayer, nBGC ! category/layer index + + character(len=*),parameter :: subname='(bgc_carbon_sum)' + + zspace(:) = c1/real(nblyr,kind=dbl_kind) + zspace(1) = p5*zspace(1) + zspace(nblyr+1) = zspace(1) + + xout = c0 + + if (tr_bgc_N) then + iBioCount = c0 + do m = 1, n_algae + nBGC = nt_bgc_N(1) + do n = 1, nblyr+1 + iLayer = iBioCount + n-1 + xout = xout + xin(nBGC+iLayer)*zspace(n)*hbrine*R_C2N(m) + enddo + iBioCount = iBioCount + nblyr+3 + enddo + endif + if (tr_bgc_C) then + iBioCount = c0 + nBGC = nt_bgc_DOC(1) + do m = 1, n_doc + do n = 1, nblyr+1 + iLayer = iBioCount + n-1 + xout = xout + xin(nBGC+iLayer)*zspace(n)*hbrine + enddo + iBioCount = iBioCount + nblyr+3 + enddo + do m = 1, n_dic + do n = 1, nblyr+1 + iLayer = iBioCount + n-1 + xout = xout + xin(nBGC+iLayer)*zspace(n)*hbrine + enddo + iBioCount = iBioCount + nblyr+3 + enddo + endif + + if (tr_bgc_DON) then + iBioCount = c0 + do m = 1, n_don + nBGC = nt_bgc_DON(1) + do n = 1, nblyr+1 + iLayer = iBioCount + n-1 + xout = xout + xin(nBGC+iLayer)*zspace(n)*hbrine*R_C2N_DON(m) + enddo + iBioCount = iBioCount + nblyr+3 + enddo + endif + if (tr_bgc_hum) then + nBGC = nt_bgc_hum + do n = 1, nblyr+1 + iLayer = n-1 + xout = xout + xin(nBGC+iLayer)*zspace(n)*hbrine + enddo + endif + + end subroutine bgc_carbon_sum + +!======================================================================= + +! Find the total carbon flux by summing the fluxes for the appropriate +! biogeochemical each grid cell, sum field over all ice and snow layers +! +! author: Nicole Jeffery, LANL + + subroutine bgc_carbon_flux (flux_bio_atm, flux_bion, Tot_Carbon_flux) + + real (kind=dbl_kind), dimension(:), intent(in) :: & + flux_bio_atm, & ! input field, all tracers and column + flux_bion + + real (kind=dbl_kind), intent(out) :: & + Tot_Carbon_flux ! output field mmol/m2/s carbon + + ! local variables + integer (kind=int_kind) :: & + m ! biology index + + character(len=*),parameter :: subname='(bgc_carbon_flux)' + + Tot_Carbon_flux = c0 + + if (tr_bgc_N) then + do m = 1, n_algae + Tot_Carbon_flux = Tot_Carbon_flux - (flux_bio_atm(nlt_bgc_N(m)) - flux_bion(nlt_bgc_N(m)))*R_C2N(m) + enddo + endif + if (tr_bgc_C) then + do m = 1, n_doc + Tot_Carbon_flux = Tot_Carbon_flux - flux_bio_atm(nlt_bgc_DOC(m)) + flux_bion(nlt_bgc_DOC(m)) + enddo + do m = 1, n_dic + Tot_Carbon_flux = Tot_Carbon_flux - flux_bio_atm(nlt_bgc_DIC(m)) + flux_bion(nlt_bgc_DIC(m)) + enddo + endif + if (tr_bgc_DON) then + do m = 1, n_don + Tot_Carbon_flux = Tot_Carbon_flux - (flux_bio_atm(nlt_bgc_DON(m)) - flux_bion(nlt_bgc_DON(m)))*R_C2N_DON(m) + enddo + endif + if (tr_bgc_hum) & + Tot_Carbon_flux = Tot_Carbon_flux - flux_bio_atm(nlt_bgc_hum) + flux_bion(nlt_bgc_hum) + + end subroutine bgc_carbon_flux + !======================================================================= end module icepack_algae diff --git a/columnphysics/icepack_atmo.F90 b/columnphysics/icepack_atmo.F90 index b4a97e0a4..f85b7794b 100644 --- a/columnphysics/icepack_atmo.F90 +++ b/columnphysics/icepack_atmo.F90 @@ -21,7 +21,7 @@ module icepack_atmo use icepack_parameters, only: pih, dragio, rhoi, rhos, rhow use icepack_parameters, only: atmbndy, calc_strair, formdrag use icepack_parameters, only: icepack_chkoptargflag - use icepack_tracers, only: n_iso + use icepack_tracers, only: ncat, n_iso use icepack_tracers, only: tr_iso use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted @@ -521,13 +521,10 @@ subroutine neutral_drag_coeffs (apnd, hpnd, & hdraft, hridge, & distrdg, hkeel, & dkeel, lfloe, & - dfloe, ncat) + dfloe) use icepack_tracers, only: tr_pond - integer (kind=int_kind), intent(in) :: & - ncat - real (kind=dbl_kind), dimension (:), intent(in) :: & apnd ,& ! melt pond fraction of sea ice hpnd ,& ! mean melt pond depth over sea ice diff --git a/columnphysics/icepack_brine.F90 b/columnphysics/icepack_brine.F90 index 98aea58da..f4738a4d8 100644 --- a/columnphysics/icepack_brine.F90 +++ b/columnphysics/icepack_brine.F90 @@ -7,19 +7,19 @@ module icepack_brine use icepack_kinds - use icepack_parameters, only: p01, p001, p5, c0, c1, c2, c1p5, puny + use icepack_parameters, only: p01, p001, p5, c0, c1, c2, c1p5, puny, p25 use icepack_parameters, only: gravit, rhoi, rhow, rhos, depressT use icepack_parameters, only: salt_loss, min_salin, rhosi use icepack_parameters, only: dts_b, l_sk - use icepack_tracers, only: ntrcr, nt_qice, nt_sice + use icepack_tracers, only: nilyr, nblyr, ntrcr, nt_qice, nt_sice use icepack_tracers, only: nt_Tsfc use icepack_zbgc_shared, only: k_o, exp_h, Dm, Ra_c, viscos_dynamic, thinS + use icepack_zbgc_shared, only: bgrid, cgrid, igrid, swgrid, icgrid use icepack_zbgc_shared, only: remap_zbgc use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted use icepack_mushy_physics, only: icepack_mushy_temperature_mush, icepack_mushy_liquid_fraction - use icepack_therm_shared, only: calculate_Tin_from_qin implicit none @@ -62,7 +62,7 @@ subroutine preflushing_changes (aicen, vicen, vsnon, & meltb, meltt, congel, & snoice, hice_old, dhice, & fbri, dhbr_top, dhbr_bot, & - hbr_old, hin,hsn, firstice ) + hbr_old, hin, hsn) real (kind=dbl_kind), intent(in) :: & aicen , & ! concentration of ice @@ -87,9 +87,6 @@ subroutine preflushing_changes (aicen, vicen, vsnon, & dhbr_bot , & ! brine change in bottom for diagnostics (m) hice_old ! old ice thickness (m) - logical (kind=log_kind), intent(in) :: & - firstice ! if true, initialized values should be used - ! local variables real (kind=dbl_kind) :: & @@ -117,14 +114,6 @@ subroutine preflushing_changes (aicen, vicen, vsnon, & dhbr_top = meltt - snoice - dhice dhbr_bot = congel - meltb - if ((hice_old < puny) .OR. (hin_old < puny) .OR. firstice) then - hice_old = hin - dhbr_top = c0 - dhbr_bot = c0 - dhice = c0 - fbri = c1 - endif - hbr_old = fbri * hice_old end subroutine preflushing_changes @@ -135,28 +124,13 @@ end subroutine preflushing_changes ! NOTE: This subroutine uses thermosaline_vertical output to compute ! average ice permeability and the surface ice porosity - subroutine compute_microS_mushy (nilyr, nblyr, & - bgrid, cgrid, igrid, & - trcrn, hice_old, hbr_old, & + subroutine compute_microS_mushy (trcrn, hice_old, hbr_old, & sss, sst, bTin, & iTin, bphin, & - kperm, bphi_min, & + kperm, bphi_min, & bSin, brine_sal, brine_rho, & iphin, ibrine_rho, ibrine_sal, & - sice_rho, iDin ) - - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nblyr ! number of bio layers - - real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: & - bgrid ! biology nondimensional vertical grid points - - real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: & - igrid ! biology vertical interface points - - real (kind=dbl_kind), dimension (nilyr+1), intent(in) :: & - cgrid ! CICE vertical coordinate + iDin, iSin) real (kind=dbl_kind), intent(in) :: & hice_old , & ! previous timestep ice height (m) @@ -170,7 +144,7 @@ subroutine compute_microS_mushy (nilyr, nblyr, & kperm , & ! average ice permeability (m^2) bphi_min ! surface porosity - real (kind=dbl_kind), intent(inout) :: & + real (kind=dbl_kind), intent(in) :: & hbr_old ! previous timestep brine height (m) real (kind=dbl_kind), dimension (nblyr+1), intent(inout) :: & @@ -180,7 +154,8 @@ subroutine compute_microS_mushy (nilyr, nblyr, & iphin , & ! porosity on the igrid ibrine_rho , & ! brine rho on interface ibrine_sal , & ! brine sal on interface - iTin ! Temperature on the igrid (oC) + iTin , & ! Temperature on the igrid (oC) + iSin ! Salinity on the igrid (ppt) real (kind=dbl_kind), dimension (nblyr+2), intent(inout) :: & bSin , & ! bulk salinity (ppt) on bgrid @@ -191,10 +166,15 @@ subroutine compute_microS_mushy (nilyr, nblyr, & bTin , & ! Temperature on bgrid bphin ! porosity on bgrid - real (kind=dbl_kind), intent(inout) :: & - sice_rho ! average ice density + ! local variables + + real (kind=dbl_kind), dimension (nilyr) :: & + cSin , & ! bulk salinity (ppt) + cqin ! enthalpy () real (kind=dbl_kind), dimension (nblyr+2) :: & + zTin , & ! Temperature of ice layers on bgrid (C) + zSin , & ! Salinity of ice layers on bgrid (C) bqin ! enthalpy on the bgrid () real (kind=dbl_kind), dimension (nblyr+1) :: & @@ -205,7 +185,8 @@ subroutine compute_microS_mushy (nilyr, nblyr, & real (kind=dbl_kind) :: & surface_S , & ! salinity of ice above hin > hbr - hinc_old ! mean ice thickness before current melt/growth (m) + hinc_old , & ! mean ice thickness before current melt/growth (m) + hbrc_old ! mean brine thickness before current melt/growth (m) real (kind=dbl_kind), dimension (ntrcr+2) :: & ! nblyr+2) trtmp_s , & ! temporary, remapped tracers @@ -227,9 +208,13 @@ subroutine compute_microS_mushy (nilyr, nblyr, & trtmp_q(:) = c0 iDin(:) = c0 + do k = 1, nilyr + cSin(k) = trcrn(nt_sice+k-1) + cqin(k) = trcrn(nt_qice+k-1) + enddo + ! map Sin and qin (cice) profiles to bgc grid surface_S = min_salin - hbr_old = min(hbr_old, maxhbr*hice_old) hinc_old = hice_old call remap_zbgc(nilyr, & @@ -269,18 +254,15 @@ subroutine compute_microS_mushy (nilyr, nblyr, & ! Define ice multiphase structure !----------------------------------------------------------------- - call prepare_hbrine (nblyr, & - bSin, bTin, iTin, & + call prepare_hbrine (bSin, bTin, iTin, & brine_sal, brine_rho, & ibrine_sal, ibrine_rho, & - sice_rho, & bphin, iphin, & - kperm, bphi_min, & - igrid, sss) + kperm, bphi_min, & + sss, iSin) if (icepack_warnings_aborted(subname)) return - call calculate_drho(nblyr, igrid, bgrid, & - brine_rho, ibrine_rho, drho) + call calculate_drho(brine_rho, ibrine_rho, drho) if (icepack_warnings_aborted(subname)) return do k= 2, nblyr+1 @@ -295,21 +277,16 @@ end subroutine compute_microS_mushy !======================================================================= - subroutine prepare_hbrine (nblyr, & - bSin, bTin, iTin, & + subroutine prepare_hbrine (bSin, bTin, iTin, & brine_sal, brine_rho, & ibrine_sal, ibrine_rho, & - sice_rho, bphin, iphin,& + bphin, iphin, & kperm, bphi_min, & - i_grid, sss) - - integer (kind=int_kind), intent(in) :: & - nblyr ! number of bio layers + sss, iSin) real (kind=dbl_kind), dimension (:), intent(in) :: & bSin , & ! salinity of ice layers on bio grid (ppt) - bTin , & ! temperature of ice layers on bio grid for history (C) - i_grid ! biology grid interface points + bTin ! temperature of ice layers on bio grid for history (C) real (kind=dbl_kind), dimension (:), intent(inout) :: & brine_sal , & ! equilibrium brine salinity (ppt) @@ -318,7 +295,8 @@ subroutine prepare_hbrine (nblyr, & ibrine_sal , & ! brine salinity on interface (ppt) iphin , & ! porosity on interface iTin , & ! Temperature on interface - bphin ! porosity of layers + bphin , & ! porosity of layers + iSin ! Bulk salinity on interface real (kind=dbl_kind), intent(in) :: & sss ! sea surface salinity (ppt) @@ -327,9 +305,6 @@ subroutine prepare_hbrine (nblyr, & kperm , & ! harmonic average permeability (m^2) bphi_min ! minimum porosity - real (kind=dbl_kind), intent(inout) :: & - sice_rho ! avg sea ice density - ! local variables real (kind=dbl_kind), dimension(nblyr+1) :: & @@ -348,14 +323,12 @@ subroutine prepare_hbrine (nblyr, & ! calculate equilibrium brine density and gradients !----------------------------------------------------------------- - sice_rho = c0 - do k = 1, nblyr+1 if (k == 1) then igrm = 0 else - igrm = i_grid(k) - i_grid(k-1) + igrm = igrid(k) - igrid(k-1) endif brine_sal(k) = a1*bTin(k) & @@ -366,8 +339,6 @@ subroutine prepare_hbrine (nblyr, & / (brine_sal(k)*brine_rho(k))) bphin (k) = min(c1, bphin(k)) kin (k) = k_o*bphin(k)**exp_h - sice_rho = sice_rho + (rhoi*(c1-bphin(k)) & - + brine_rho(k)*bphin(k))*igrm enddo ! k brine_sal (nblyr+2) = sss @@ -379,6 +350,8 @@ subroutine prepare_hbrine (nblyr, & ibrine_rho(nblyr+1) = brine_rho (nblyr+2) iTin (1) = bTin(2) iTin (nblyr+1) = bTin(nblyr+1) + iSin (1) = bSin(2) + iSin (nblyr+1) = bSin(nblyr+1) iphin (1) = bphin (2) iphin (nblyr+1) = bphin (nblyr+1) k_min = MINVAL(kin(2:nblyr+1)) @@ -394,13 +367,14 @@ subroutine prepare_hbrine (nblyr, & kperm = k_min endif - igrp = i_grid(k+1) - i_grid(k ) - igrm = i_grid(k ) - i_grid(k-1) - rigr = c1 / (i_grid(k+1)-i_grid(k-1)) + igrp = igrid(k+1) - igrid(k ) + igrm = igrid(k ) - igrid(k-1) + rigr = c1 / (igrid(k+1)-igrid(k-1)) ibrine_sal(k) = (brine_sal(k+1)*igrp + brine_sal(k)*igrm) * rigr ibrine_rho(k) = (brine_rho(k+1)*igrp + brine_rho(k)*igrm) * rigr iTin (k) = (bTin (k+1)*igrp + bTin (k)*igrm) * rigr + iSin (k) = (bSin (k+1)*igrp + bSin (k)*igrm) * rigr iphin (k) = max(puny, & (bphin (k+1)*igrp + bphin (k)*igrm) * rigr) iphin (k) = min(c1, iphin (k)) @@ -426,12 +400,12 @@ end subroutine prepare_hbrine ! ice. This volume fraction may be > 1 in which case there is brine ! above the ice surface (ponds). - subroutine update_hbrine (meltt, & + subroutine update_hbrine (meltt, & melts, dt, & hin, hsn, & hin_old, hbr, & - hbr_old, & - fbri, & + hbr_old, & + fbri, & dhS_top, dhS_bottom, & dh_top_chl, dh_bot_chl, & kperm, bphi_min, & @@ -561,17 +535,7 @@ end subroutine update_hbrine ! Find density difference about interface grid points ! for gravity drainage parameterization - subroutine calculate_drho (nblyr, i_grid, b_grid, & - brine_rho, ibrine_rho, drho) - - integer (kind=int_kind), intent(in) :: & - nblyr ! number of bio layers - - real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: & - b_grid ! biology nondimensional grid layer points - - real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: & - i_grid ! biology grid interface points + subroutine calculate_drho (brine_rho, ibrine_rho, drho) real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: & brine_rho ! Internal brine density (kg/m^3) @@ -606,29 +570,29 @@ subroutine calculate_drho (nblyr, i_grid, b_grid, & rho_2b(:) = c0 drho (:) = c0 ! surface is snow or atmosphere - do k = 1, nblyr+1 ! i_grid values + do k = 1, nblyr+1 ! igrid values !---------------------------------------------- - ! h_avg(k) = i_grid(k) - ! Calculate rho_a(k), ie average rho above i_grid(k) + ! h_avg(k) = igrid(k) + ! Calculate rho_a(k), ie average rho above igrid(k) ! first part is good !---------------------------------------------- if (k == 2) then - rho_a(2) = (brine_rho(2)*b_grid(2) & + rho_a(2) = (brine_rho(2)*bgrid(2) & + (ibrine_rho(2) + brine_rho(2)) & - * p5*(i_grid(2)-b_grid(2)) )/i_grid(2) + * p5*(igrid(2)-bgrid(2)) )/igrid(2) rho_b(2) = brine_rho(2) elseif (k > 2 .AND. k < nblyr+1) then - rho_a(k) = (rho_a(k-1)*i_grid(k-1) + (ibrine_rho(k-1) + brine_rho(k)) & - * p5*(b_grid(k)-i_grid(k-1)) + (ibrine_rho(k ) + brine_rho(k)) & - * p5*(i_grid(k)-b_grid(k)))/i_grid(k) + rho_a(k) = (rho_a(k-1)*igrid(k-1) + (ibrine_rho(k-1) + brine_rho(k)) & + * p5*(bgrid(k)-igrid(k-1)) + (ibrine_rho(k ) + brine_rho(k)) & + * p5*(igrid(k)-bgrid(k)))/igrid(k) rho_b(k) = brine_rho(k) else - rho_a(nblyr+1) = (rho_a(nblyr)*i_grid(nblyr) + (ibrine_rho(nblyr) + & - brine_rho(nblyr+1))*p5*(b_grid(nblyr+1)-i_grid(nblyr)) + & - brine_rho(nblyr+1)*(i_grid(nblyr+1)-b_grid(nblyr+1)))/i_grid(nblyr+1) + rho_a(nblyr+1) = (rho_a(nblyr)*igrid(nblyr) + (ibrine_rho(nblyr) + & + brine_rho(nblyr+1))*p5*(bgrid(nblyr+1)-igrid(nblyr)) + & + brine_rho(nblyr+1)*(igrid(nblyr+1)-bgrid(nblyr+1)))/igrid(nblyr+1) rho_a(1) = brine_rho(2) !for k == 1 use grid point value rho_b(nblyr+1) = brine_rho(nblyr+1) rho_b(1) = brine_rho(2) @@ -640,10 +604,10 @@ subroutine calculate_drho (nblyr, i_grid, b_grid, & ! Calculate average above and below k rho_2a !---------------------------------------------- - do k = 1, nblyr+1 !i_grid values + do k = 1, nblyr+1 !igrid values if (k == 1) then - rho_2a(1) = (rho_a(1)*b_grid(2) + p5*(brine_rho(2) + ibrine_rho(2)) & - * (i_grid(2)-b_grid(2)))/i_grid(2) + rho_2a(1) = (rho_a(1)*bgrid(2) + p5*(brine_rho(2) + ibrine_rho(2)) & + * (igrid(2)-bgrid(2)))/igrid(2) rho_2b(1) = brine_rho(2) else mstop = 2*(k-1) + 1 @@ -657,7 +621,7 @@ subroutine calculate_drho (nblyr, i_grid, b_grid, & endif do mm = mstart,mstop - rho_2a(k) =(rho_a(nblyr+1) + rhow*(c2*i_grid(k)-c1))*p5/i_grid(k) + rho_2a(k) =(rho_a(nblyr+1) + rhow*(c2*igrid(k)-c1))*p5/igrid(k) enddo rho_2b(k) = brine_rho(k+1) endif @@ -671,26 +635,22 @@ end subroutine calculate_drho !autodocument_start icepack_init_hbrine ! Initialize brine height tracer - subroutine icepack_init_hbrine(bgrid, igrid, cgrid, & - icgrid, swgrid, nblyr, nilyr, phi_snow) - - integer (kind=int_kind), intent(in) :: & - nilyr, & ! number of ice layers - nblyr ! number of bio layers + subroutine icepack_init_hbrine(bgrid_out, igrid_out, cgrid_out, & + icgrid_out, swgrid_out, phi_snow) - real (kind=dbl_kind), intent(inout) :: & + real (kind=dbl_kind), optional, intent(inout) :: & phi_snow ! porosity at the ice-snow interface - real (kind=dbl_kind), dimension (nblyr+2), intent(out) :: & - bgrid ! biology nondimensional vertical grid points + real (kind=dbl_kind), optional, dimension (:), intent(out) :: & + bgrid_out ! biology nondimensional vertical grid points - real (kind=dbl_kind), dimension (nblyr+1), intent(out) :: & - igrid ! biology vertical interface points + real (kind=dbl_kind), optional, dimension (:), intent(out) :: & + igrid_out ! biology vertical interface points - real (kind=dbl_kind), dimension (nilyr+1), intent(out) :: & - cgrid , & ! CICE vertical coordinate - icgrid , & ! interface grid for CICE (shortwave variable) - swgrid ! grid for ice tracers used in dEdd scheme + real (kind=dbl_kind), optional, dimension (:), intent(out) :: & + cgrid_out , & ! CICE vertical coordinate + icgrid_out , & ! interface grid for CICE (shortwave variable) + swgrid_out ! grid for ice tracers used in dEdd scheme !autodocument_end @@ -704,8 +664,17 @@ subroutine icepack_init_hbrine(bgrid, igrid, cgrid, & character(len=*),parameter :: subname='(icepack_init_hbrine)' + !----------------------------------------------------------------- - if (phi_snow .le. c0) phi_snow = c1-rhos/rhoi + if (present(phi_snow)) then + if (phi_snow .le. c0) phi_snow = c1-rhos/rhoi + endif + + allocate(bgrid (nblyr+2)) + allocate(igrid (nblyr+1)) + allocate(cgrid (nilyr+1)) + allocate(icgrid(nilyr+1)) + allocate(swgrid(nilyr+1)) !----------------------------------------------------------------- ! Calculate bio gridn: 0 to 1 corresponds to ice top to bottom @@ -755,12 +724,18 @@ subroutine icepack_init_hbrine(bgrid, igrid, cgrid, & ! swgrid represents the layer index of the delta-eddington ice layer index !------------------------------------------------------------------------ zspace = c1/(real(nilyr,kind=dbl_kind)) ! CICE grid spacing - swgrid(1) = min(c1/60.0_dbl_kind, zspace/c2) + swgrid(1) = min(c1/60.0_dbl_kind, zspace*p25) !p5 to p25. NJ: allows thinner surface layers swgrid(2) = zspace/c2 !+ swgrid(1) do k = 3, nilyr+1 swgrid(k) = zspace * (real(k,kind=dbl_kind)-c1p5) enddo + if (present( bgrid_out)) bgrid_out=bgrid + if (present( cgrid_out)) cgrid_out=cgrid + if (present( igrid_out)) igrid_out=igrid + if (present(icgrid_out)) icgrid_out=icgrid + if (present(swgrid_out)) swgrid_out=swgrid + end subroutine icepack_init_hbrine !======================================================================= @@ -768,14 +743,8 @@ end subroutine icepack_init_hbrine ! **DEPRECATED**, all code removed ! Interface provided for backwards compatibility - subroutine icepack_init_zsalinity(nblyr,ntrcr_o, Rayleigh_criteria, & - Rayleigh_real, trcrn_bgc, nt_bgc_S, ncat, sss) - - integer (kind=int_kind), intent(in) :: & - nblyr , & ! number of biolayers - ntrcr_o, & ! number of non bio tracers - ncat , & ! number of categories - nt_bgc_S ! zsalinity index + subroutine icepack_init_zsalinity(Rayleigh_criteria, & + Rayleigh_real, trcrn_bgc, sss) logical (kind=log_kind), intent(inout) :: & Rayleigh_criteria diff --git a/columnphysics/icepack_flux.F90 b/columnphysics/icepack_flux.F90 index ce0b4b72c..27a9f0f80 100644 --- a/columnphysics/icepack_flux.F90 +++ b/columnphysics/icepack_flux.F90 @@ -68,7 +68,9 @@ subroutine merge_fluxes (aicen, & ! single category fluxes real (kind=dbl_kind), intent(in) :: & - aicen , & ! concentration of ice + aicen ! concentration of ice + + real (kind=dbl_kind), optional, intent(in) :: & flw , & ! downward longwave flux (W/m**2) strairxn, & ! air/ice zonal strss, (N/m**2) strairyn, & ! air/ice merdnl strss, (N/m**2) @@ -95,9 +97,7 @@ subroutine merge_fluxes (aicen, & meltsliqn,& ! mass of snow melt (kg/m^2) dsnown , & ! change in snow depth (m) congeln , & ! congelation ice growth (m) - snoicen ! snow-ice growth (m) - - real (kind=dbl_kind), optional, intent(in):: & + snoicen , & ! snow-ice growth (m) fswthrun_vdr, & ! vis dir sw radiation through ice bot (W/m**2) fswthrun_vdf, & ! vis dif sw radiation through ice bot (W/m**2) fswthrun_idr, & ! nir dir sw radiation through ice bot (W/m**2) @@ -105,7 +105,7 @@ subroutine merge_fluxes (aicen, & Urefn ! air speed reference level (m/s) ! cumulative fluxes - real (kind=dbl_kind), intent(inout) :: & + real (kind=dbl_kind), optional, intent(inout) :: & strairxT, & ! air/ice zonal strss, (N/m**2) strairyT, & ! air/ice merdnl strss, (N/m**2) Cdn_atm_ratio, & ! ratio of total drag over neutral drag @@ -130,28 +130,24 @@ subroutine merge_fluxes (aicen, & melts , & ! snow melt (m) meltsliq, & ! mass of snow melt (kg/m^2) congel , & ! congelation ice growth (m) - snoice ! snow-ice growth (m) - - real (kind=dbl_kind), intent(inout), optional :: & - fswthru_vdr , & ! vis dir sw radiation through ice bot (W/m**2) - fswthru_vdf , & ! vis dif sw radiation through ice bot (W/m**2) - fswthru_idr , & ! nir dir sw radiation through ice bot (W/m**2) - fswthru_idf ! nir dif sw radiation through ice bot (W/m**2) - - real (kind=dbl_kind), intent(inout), optional :: & + snoice , & ! snow-ice growth (m) + fswthru_vdr, & ! vis dir sw radiation through ice bot (W/m**2) + fswthru_vdf, & ! vis dif sw radiation through ice bot (W/m**2) + fswthru_idr, & ! nir dir sw radiation through ice bot (W/m**2) + fswthru_idf, & ! nir dif sw radiation through ice bot (W/m**2) dsnow, & ! change in snow depth (m) Uref ! air speed reference level (m/s) - real (kind=dbl_kind), dimension(:), intent(inout), optional :: & - Qref_iso, & ! isotope air sp hum ref level (kg/kg) - fiso_ocn, & ! isotope fluxes to ocean (kg/m2/s) - fiso_evap ! isotope evaporation (kg/m2/s) - real (kind=dbl_kind), dimension(:), intent(in), optional :: & Qrefn_iso, & ! isotope air sp hum ref level (kg/kg) fiso_ocnn, & ! isotope fluxes to ocean (kg/m2/s) fiso_evapn ! isotope evaporation (kg/m2/s) + real (kind=dbl_kind), dimension(:), intent(inout), optional :: & + Qref_iso, & ! isotope air sp hum ref level (kg/kg) + fiso_ocn, & ! isotope fluxes to ocean (kg/m2/s) + fiso_evap ! isotope evaporation (kg/m2/s) + character(len=*),parameter :: subname='(merge_fluxes)' !----------------------------------------------------------------- @@ -163,23 +159,38 @@ subroutine merge_fluxes (aicen, & ! atmo fluxes - strairxT = strairxT + strairxn * aicen - strairyT = strairyT + strairyn * aicen - Cdn_atm_ratio = Cdn_atm_ratio + & - Cdn_atm_ratio_n * aicen - fsurf = fsurf + fsurfn * aicen - fcondtop = fcondtop + fcondtopn * aicen - fcondbot = fcondbot + fcondbotn * aicen - fsens = fsens + fsensn * aicen - flat = flat + flatn * aicen - fswabs = fswabs + fswabsn * aicen - flwout = flwout & - + (flwoutn - (c1-emissivity)*flw) * aicen - evap = evap + evapn * aicen - evaps = evaps + evapsn * aicen - evapi = evapi + evapin * aicen - Tref = Tref + Trefn * aicen - Qref = Qref + Qrefn * aicen + if (present(strairxn) .and. present(strairxT)) & + strairxT = strairxT + strairxn * aicen + if (present(strairyn) .and. present(strairyT)) & + strairyT = strairyT + strairyn * aicen + if (present(Cdn_atm_ratio_n) .and. present(Cdn_atm_ratio)) & + Cdn_atm_ratio = Cdn_atm_ratio + & + Cdn_atm_ratio_n * aicen + if (present(fsurfn) .and. present(fsurf)) & + fsurf = fsurf + fsurfn * aicen + if (present(fcondtopn) .and. present(fcondtop)) & + fcondtop = fcondtop + fcondtopn * aicen + if (present(fcondbotn) .and. present(fcondbot)) & + fcondbot = fcondbot + fcondbotn * aicen + if (present(fsensn) .and. present(fsens)) & + fsens = fsens + fsensn * aicen + if (present(flatn) .and. present(flat)) & + flat = flat + flatn * aicen + if (present(fswabsn) .and. present(fswabs)) & + fswabs = fswabs + fswabsn * aicen + if (present(flwoutn) .and. present(flwout) .and. present(flw)) & + flwout = flwout & + + (flwoutn - (c1-emissivity)*flw) * aicen + if (present(evapn) .and. present(evap)) & + evap = evap + evapn * aicen + if (present(evapsn) .and. present(evaps)) & + evaps = evaps + evapsn * aicen + if (present(evapin) .and. present(evapi)) & + evapi = evapi + evapin * aicen + if (present(Trefn) .and. present(Tref)) & + Tref = Tref + Trefn * aicen + if (present(Qrefn) .and. present(Qref)) & + Qref = Qref + Qrefn * aicen ! Isotopes if (tr_iso) then @@ -196,35 +207,46 @@ subroutine merge_fluxes (aicen, & ! ocean fluxes if (present(Urefn) .and. present(Uref)) then - Uref = Uref + Urefn * aicen + Uref = Uref + Urefn * aicen endif - fresh = fresh + freshn * aicen - fsalt = fsalt + fsaltn * aicen - fhocn = fhocn + fhocnn * aicen - fswthru = fswthru + fswthrun * aicen - if (present(fswthru_vdr)) & - fswthru_vdr = fswthru_vdr + fswthrun_vdr * aicen - if (present(fswthru_vdf)) & - fswthru_vdf = fswthru_vdf + fswthrun_vdf * aicen - if (present(fswthru_idr)) & - fswthru_idr = fswthru_idr + fswthrun_idr * aicen - if (present(fswthru_idf)) & - fswthru_idf = fswthru_idf + fswthrun_idf * aicen + if (present(freshn) .and. present(fresh)) & + fresh = fresh + freshn * aicen + if (present(fsaltn) .and. present(fsalt)) & + fsalt = fsalt + fsaltn * aicen + if (present(fhocnn) .and. present(fhocn)) & + fhocn = fhocn + fhocnn * aicen + if (present(fswthrun) .and. present(fswthru)) & + fswthru = fswthru + fswthrun * aicen + + if (present(fswthrun_vdr) .and. present(fswthru_vdr)) & + fswthru_vdr = fswthru_vdr + fswthrun_vdr * aicen + if (present(fswthrun_vdf) .and. present(fswthru_vdf)) & + fswthru_vdf = fswthru_vdf + fswthrun_vdf * aicen + if (present(fswthrun_idr) .and. present(fswthru_idr)) & + fswthru_idr = fswthru_idr + fswthrun_idr * aicen + if (present(fswthrun_idf) .and. present(fswthru_idf)) & + fswthru_idf = fswthru_idf + fswthrun_idf * aicen ! ice/snow thickness - meltt = meltt + melttn * aicen - meltb = meltb + meltbn * aicen - melts = melts + meltsn * aicen + if (present(melttn) .and. present(meltt)) & + meltt = meltt + melttn * aicen + if (present(meltbn) .and. present(meltb)) & + meltb = meltb + meltbn * aicen + if (present(meltsn) .and. present(melts)) & + melts = melts + meltsn * aicen if (snwgrain) then - meltsliq = meltsliq + meltsliqn * aicen + if (present(meltsliqn) .and. present(meltsliq)) & + meltsliq = meltsliq + meltsliqn * aicen endif - if (present(dsnow)) then + if (present(dsnown) .and. present(dsnow)) then dsnow = dsnow + dsnown * aicen endif - congel = congel + congeln * aicen - snoice = snoice + snoicen * aicen + if (present(congeln) .and. present(congel)) & + congel = congel + congeln * aicen + if (present(snoicen) .and. present(snoice)) & + snoice = snoice + snoicen * aicen end subroutine merge_fluxes diff --git a/columnphysics/icepack_fsd.F90 b/columnphysics/icepack_fsd.F90 index 1454fdefc..28f12d922 100644 --- a/columnphysics/icepack_fsd.F90 +++ b/columnphysics/icepack_fsd.F90 @@ -45,7 +45,7 @@ module icepack_fsd use icepack_kinds use icepack_parameters, only: c0, c1, c2, c4, p01, p1, p5, puny use icepack_parameters, only: pi, floeshape, wave_spec, bignum, gravit, rhoi - use icepack_tracers, only: nt_fsd, tr_fsd + use icepack_tracers, only: nt_fsd, tr_fsd, nfsd, ncat use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted @@ -84,16 +84,13 @@ module icepack_fsd ! ! authors: Lettie Roach, NIWA/VUW and C. M. Bitz, UW - subroutine icepack_init_fsd_bounds(nfsd, & + subroutine icepack_init_fsd_bounds( & floe_rad_l, & ! fsd size lower bound in m (radius) floe_rad_c, & ! fsd size bin centre in m (radius) floe_binwidth, & ! fsd size bin width in m (radius) c_fsd_range, & ! string for history output write_diags ) ! flag for writing diagnostics - integer (kind=int_kind), intent(in) :: & - nfsd ! number of floe size categories - real(kind=dbl_kind), dimension(:), intent(inout) :: & floe_rad_l, & ! fsd size lower bound in m (radius) floe_rad_c, & ! fsd size bin centre in m (radius) @@ -259,14 +256,11 @@ end subroutine icepack_init_fsd_bounds ! ! authors: Lettie Roach, NIWA/VUW - subroutine icepack_init_fsd(nfsd, ice_ic, & + subroutine icepack_init_fsd(ice_ic, & floe_rad_c, & ! fsd size bin centre in m (radius) floe_binwidth, & ! fsd size bin width in m (radius) afsd) ! floe size distribution tracer - integer(kind=int_kind), intent(in) :: & - nfsd - character(len=char_len_long), intent(in) :: & ice_ic ! method of ice cover initialization @@ -316,11 +310,7 @@ end subroutine icepack_init_fsd ! ! authors: Elizabeth Hunke, LANL ! - subroutine icepack_cleanup_fsd (ncat, nfsd, afsdn) - - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nfsd ! number of floe size categories + subroutine icepack_cleanup_fsd (afsdn) real (kind=dbl_kind), dimension(:,:), intent(inout) :: & afsdn ! floe size distribution tracer @@ -337,7 +327,7 @@ subroutine icepack_cleanup_fsd (ncat, nfsd, afsdn) if (tr_fsd) then do n = 1, ncat - call icepack_cleanup_fsdn(nfsd, afsdn(:,n)) + call icepack_cleanup_fsdn(afsdn(:,n)) if (icepack_warnings_aborted(subname)) return enddo @@ -352,10 +342,7 @@ end subroutine icepack_cleanup_fsd ! authors: Elizabeth Hunke, LANL ! - subroutine icepack_cleanup_fsdn (nfsd, afsd) - - integer (kind=int_kind), intent(in) :: & - nfsd ! number of floe size categories + subroutine icepack_cleanup_fsdn (afsd) real (kind=dbl_kind), dimension(:), intent(inout) :: & afsd ! floe size distribution tracer @@ -391,16 +378,11 @@ end subroutine icepack_cleanup_fsdn ! ! authors: Lettie Roach, NIWA/VUW - subroutine partition_area (ncat, nfsd, & - floe_rad_c, aice, & + subroutine partition_area (floe_rad_c, aice, & aicen, vicen, & afsdn, lead_area, & latsurf_area) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nfsd ! number of floe size categories - real (kind=dbl_kind), dimension(:), intent(in) :: & floe_rad_c ! fsd size bin centre in m (radius) @@ -491,8 +473,7 @@ end subroutine partition_area ! ! authors: Lettie Roach, NIWA/VUW ! - subroutine fsd_lateral_growth (ncat, nfsd, & - dt, aice, & + subroutine fsd_lateral_growth (dt, aice, & aicen, vicen, & vi0new, & frazil, floe_rad_c, & @@ -501,10 +482,6 @@ subroutine fsd_lateral_growth (ncat, nfsd, & G_radial, d_an_latg, & tot_latg) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nfsd ! number of floe size categories - real (kind=dbl_kind), intent(in) :: & dt , & ! time step (s) aice ! total concentration of ice @@ -552,8 +529,7 @@ subroutine fsd_lateral_growth (ncat, nfsd, & d_an_latg = c0 ! partition volume into lateral growth and frazil - call partition_area (ncat, nfsd, & - floe_rad_c, aice, & + call partition_area (floe_rad_c, aice, & aicen, vicen, & afsdn, lead_area, & latsurf_area) @@ -610,7 +586,7 @@ end subroutine fsd_lateral_growth ! ! authors: Lettie Roach, NIWA/VUW ! - subroutine fsd_add_new_ice (ncat, n, nfsd, & + subroutine fsd_add_new_ice (n, & dt, ai0new, & d_an_latg, d_an_newi, & floe_rad_c, floe_binwidth, & @@ -625,9 +601,7 @@ subroutine fsd_add_new_ice (ncat, n, nfsd, & aicen, trcrn) integer (kind=int_kind), intent(in) :: & - n , & ! thickness category number - ncat , & ! number of thickness categories - nfsd ! number of floe size categories + n ! thickness category number real (kind=dbl_kind), intent(in) :: & dt , & ! time step (s) @@ -722,7 +696,7 @@ subroutine fsd_add_new_ice (ncat, n, nfsd, & end do ! timestep required for this - subdt = get_subdt_fsd(nfsd, afsdn_latg(:,n), dafsd_tmp(:)) + subdt = get_subdt_fsd(afsdn_latg(:,n), dafsd_tmp(:)) subdt = MIN(subdt, dt) ! update fsd and elapsed time @@ -731,7 +705,7 @@ subroutine fsd_add_new_ice (ncat, n, nfsd, & END DO - call icepack_cleanup_fsdn (nfsd, afsdn_latg(:,n)) + call icepack_cleanup_fsdn (afsdn_latg(:,n)) if (icepack_warnings_aborted(subname)) return trcrn(nt_fsd:nt_fsd+nfsd-1,n) = afsdn_latg(:,n) @@ -748,7 +722,7 @@ subroutine fsd_add_new_ice (ncat, n, nfsd, & if (wave_spec) then if (wave_sig_ht > puny) then - call wave_dep_growth (nfsd, wave_spectrum, & + call wave_dep_growth (wave_spectrum, & wavefreq, dwavefreq, & new_size) if (icepack_warnings_aborted(subname)) return @@ -776,7 +750,7 @@ subroutine fsd_add_new_ice (ncat, n, nfsd, & if (wave_spec) then if (wave_sig_ht > puny) then - call wave_dep_growth (nfsd, wave_spectrum, & + call wave_dep_growth (wave_spectrum, & wavefreq, dwavefreq, & new_size) if (icepack_warnings_aborted(subname)) return @@ -790,7 +764,7 @@ subroutine fsd_add_new_ice (ncat, n, nfsd, & endif ! entirely new ice or not trcrn(nt_fsd:nt_fsd+nfsd-1,n) = afsd_ni(:) - call icepack_cleanup_fsdn (nfsd, trcrn(nt_fsd:nt_fsd+nfsd-1,n)) + call icepack_cleanup_fsdn (trcrn(nt_fsd:nt_fsd+nfsd-1,n)) if (icepack_warnings_aborted(subname)) return endif ! d_an_newi > puny endif ! n = 1 @@ -818,13 +792,10 @@ end subroutine fsd_add_new_ice ! ! authors: Lettie Roach, NIWA/VUW ! - subroutine wave_dep_growth (nfsd, local_wave_spec, & + subroutine wave_dep_growth (local_wave_spec, & wavefreq, dwavefreq, & new_size) - integer (kind=int_kind), intent(in) :: & - nfsd ! number of floe size categories - real (kind=dbl_kind), dimension(:), intent(in) :: & local_wave_spec ! ocean surface wave spectrum as a function of frequency ! power spectral density of surface elevation, E(f) (units m^2 s) @@ -879,15 +850,10 @@ end subroutine wave_dep_growth ! authors: Lettie Roach, NIWA/VUW ! - subroutine fsd_weld_thermo (ncat, nfsd, & - dt, frzmlt, & + subroutine fsd_weld_thermo (dt, frzmlt, & aicen, trcrn, & d_afsd_weld) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nfsd ! number of floe size categories - real (kind=dbl_kind), intent(in) :: & dt ! time step (s) @@ -948,7 +914,7 @@ subroutine fsd_weld_thermo (ncat, nfsd, & d_afsd_weld (:) = c0 d_afsdn_weld(:,n) = c0 afsdn(:,n) = trcrn(nt_fsd:nt_fsd+nfsd-1,n) - call icepack_cleanup_fsdn (nfsd, afsdn(:,n)) + call icepack_cleanup_fsdn (afsdn(:,n)) if (icepack_warnings_aborted(subname)) return ! If there is some ice in the lower (nfsd-1) categories @@ -1010,7 +976,7 @@ subroutine fsd_weld_thermo (ncat, nfsd, & END DO ! time afsdn(:,n) = afsd_tmp(:) - call icepack_cleanup_fsdn (nfsd, afsdn(:,n)) + call icepack_cleanup_fsdn (afsdn(:,n)) if (icepack_warnings_aborted(subname)) return do k = 1, nfsd @@ -1039,12 +1005,9 @@ end subroutine fsd_weld_thermo ! authors: 2018 Lettie Roach, NIWA/VUW ! ! - function get_subdt_fsd(nfsd, afsd_init, d_afsd) & + function get_subdt_fsd(afsd_init, d_afsd) & result(subdt) - integer (kind=int_kind), intent(in) :: & - nfsd ! number of floe size categories - real (kind=dbl_kind), dimension (nfsd), intent(in) :: & afsd_init, d_afsd ! floe size distribution tracer diff --git a/columnphysics/icepack_isotope.F90 b/columnphysics/icepack_isotope.F90 index 1db640556..616a28700 100644 --- a/columnphysics/icepack_isotope.F90 +++ b/columnphysics/icepack_isotope.F90 @@ -45,8 +45,7 @@ module icepack_isotope ! ! Increase isotope in ice or snow surface due to deposition and loss ! - subroutine update_isotope (dt, & - nilyr, nslyr, & + subroutine update_isotope(dt, & meltt, melts, & meltb, congel, & snoice, evap, & @@ -63,9 +62,6 @@ subroutine update_isotope (dt, & ! use water_isotopes, only: wiso_alpi use icepack_parameters, only: ktherm, rhoi, rhos, Tffresh - integer (kind=int_kind), intent(in) :: & - nilyr, nslyr - real (kind=dbl_kind), intent(in) :: & dt ! time step diff --git a/columnphysics/icepack_itd.F90 b/columnphysics/icepack_itd.F90 index 0da1f1590..1870ec4ad 100644 --- a/columnphysics/icepack_itd.F90 +++ b/columnphysics/icepack_itd.F90 @@ -29,6 +29,7 @@ module icepack_itd use icepack_parameters, only: c0, c1, c2, c3, c15, c25, c100, p1, p01, p001, p5, puny use icepack_parameters, only: Lfresh, rhos, ice_ref_salinity, hs_min, cp_ice, rhoi use icepack_parameters, only: rhosi, sk_l, hs_ssl, min_salin, rsnw_fall, rhosnew + use icepack_tracers, only: ncat, nilyr, nslyr, nblyr, ntrcr, nbtrcr, n_aero use icepack_tracers, only: nt_Tsfc, nt_qice, nt_qsno, nt_aero, nt_isosno, nt_isoice use icepack_tracers, only: nt_apnd, nt_hpnd, nt_fbri, tr_brine, bio_index use icepack_tracers, only: n_iso, tr_iso, nt_smice, nt_rsnw, nt_rhos, nt_sice @@ -64,10 +65,7 @@ module icepack_itd ! ! authors: William H. Lipscomb, LANL - subroutine aggregate_area (ncat, aicen, aice, aice0) - - integer (kind=int_kind), intent(in) :: & - ncat ! number of thickness categories + subroutine aggregate_area (aicen, aice, aice0) real (kind=dbl_kind), dimension(:), intent(in) :: & aicen ! concentration of ice @@ -102,17 +100,13 @@ end subroutine aggregate_area ! ! authors: William H. Lipscomb and Elizabeth C. Hunke, LANL - subroutine rebin (ntrcr, trcr_depend, & + subroutine rebin (trcr_depend, & trcr_base, & n_trcr_strata, & nt_strata, & aicen, trcrn, & vicen, vsnon, & - ncat, hin_max, Tf ) - - integer (kind=int_kind), intent(in) :: & - ntrcr , & ! number of tracers in use - ncat ! number of thickness categories + hin_max, Tf ) integer (kind=int_kind), dimension (:), intent(in) :: & trcr_depend, & ! = 0 for aicen tracers, 1 for vicen, 2 for vsnon @@ -216,8 +210,7 @@ subroutine rebin (ntrcr, trcr_depend, & ! shift ice between categories !----------------------------------------------------------------- - call shift_ice (ntrcr, ncat, & - trcr_depend, & + call shift_ice (trcr_depend, & trcr_base, & n_trcr_strata, & nt_strata, & @@ -264,8 +257,7 @@ subroutine rebin (ntrcr, trcr_depend, & ! shift ice between categories !----------------------------------------------------------------- - call shift_ice (ntrcr, ncat, & - trcr_depend, & + call shift_ice (trcr_depend, & trcr_base, & n_trcr_strata, & nt_strata, & @@ -356,8 +348,7 @@ end subroutine reduce_area ! ! authors: William H. Lipscomb and Elizabeth C. Hunke, LANL - subroutine shift_ice (ntrcr, ncat, & - trcr_depend, & + subroutine shift_ice (trcr_depend, & trcr_base, & n_trcr_strata, & nt_strata, & @@ -366,10 +357,6 @@ subroutine shift_ice (ntrcr, ncat, & hicen, donor, & daice, dvice, Tf ) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - ntrcr ! number of tracers in use - integer (kind=int_kind), dimension (:), intent(in) :: & trcr_depend, & ! = 0 for aicen tracers, 1 for vicen, 2 for vsnon n_trcr_strata ! number of underlying tracer layers @@ -665,7 +652,7 @@ subroutine shift_ice (ntrcr, ncat, & ! Compute new tracers !----------------------------------------------------------------- - call icepack_compute_tracers (ntrcr, trcr_depend, & + call icepack_compute_tracers(trcr_depend, & atrcrn(:,n), aicen(n), & vicen(n), vsnon(n), & trcr_base, n_trcr_strata, & @@ -759,14 +746,10 @@ end subroutine column_conservation_check ! ! author: William H. Lipscomb, LANL - subroutine cleanup_itd (dt, ntrcr, & - nilyr, nslyr, & - ncat, hin_max, & + subroutine cleanup_itd (dt, hin_max, & aicen, trcrn, & vicen, vsnon, & aice0, aice, & - n_aero, & - nbtrcr, nblyr, & tr_aero, & tr_pond_topo, & first_ice, & @@ -777,15 +760,6 @@ subroutine cleanup_itd (dt, ntrcr, & faero_ocn, fiso_ocn, & flux_bio, Tf, limit_aice_in) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nilyr , & ! number of ice layers - nblyr , & ! number of bio layers - nslyr , & ! number of snow layers - ntrcr , & ! number of tracers in use - nbtrcr, & ! number of bio tracers in use - n_aero ! number of aerosol tracers - real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -894,7 +868,7 @@ subroutine cleanup_itd (dt, ntrcr, & ! Compute total ice area. !----------------------------------------------------------------- - call aggregate_area (ncat, aicen, aice, aice0) + call aggregate_area (aicen, aice, aice0) if (icepack_warnings_aborted(subname)) return if (limit_aice) then ! check for aice out of bounds @@ -924,13 +898,13 @@ subroutine cleanup_itd (dt, ntrcr, & ! correctly (e.g., very fast ice growth). !----------------------------------------------------------------- - call rebin (ntrcr, trcr_depend, & + call rebin (trcr_depend, & trcr_base, & n_trcr_strata, & nt_strata, & aicen, trcrn, & vicen, vsnon, & - ncat, hin_max, Tf ) + hin_max, Tf ) if (icepack_warnings_aborted(subname)) return endif ! aice > puny @@ -940,21 +914,17 @@ subroutine cleanup_itd (dt, ntrcr, & !----------------------------------------------------------------- if (limit_aice) then - call zap_small_areas (dt, ntrcr, & - ncat, & - n_aero, & - nblyr, & - nilyr, nslyr, & + call zap_small_areas (dt, & aice, aice0, & aicen, trcrn, & vicen, vsnon, & dfpond, & dfresh, dfsalt, & - dfhocn, & + dfhocn, & dfaero_ocn, dfiso_ocn, & tr_aero, & tr_pond_topo, & - first_ice, nbtrcr, & + first_ice, & dflux_bio, Tf ) if (icepack_warnings_aborted(subname)) then @@ -973,15 +943,12 @@ subroutine cleanup_itd (dt, ntrcr, & ! Zap snow that has out of bounds temperatures !------------------------------------------------------------------- - call zap_snow_temperature(dt, ncat, & - nblyr, & - nslyr, aicen, & + call zap_snow_temperature(dt, aicen, & trcrn, vsnon, & dfresh, dfhocn, & dfaero_ocn, tr_aero, & dfiso_ocn, & - dflux_bio, nbtrcr, & - n_aero) + dflux_bio) if (icepack_warnings_aborted(subname)) return !------------------------------------------------------------------- @@ -1023,11 +990,7 @@ end subroutine cleanup_itd ! ! author: William H. Lipscomb, LANL - subroutine zap_small_areas (dt, ntrcr, & - ncat, & - n_aero, & - nblyr, & - nilyr, nslyr, & + subroutine zap_small_areas (dt, & aice, aice0, & aicen, trcrn, & vicen, vsnon, & @@ -1037,18 +1000,9 @@ subroutine zap_small_areas (dt, ntrcr, & dfaero_ocn, dfiso_ocn, & tr_aero, & tr_pond_topo, & - first_ice, nbtrcr, & + first_ice, & dflux_bio, Tf ) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nilyr , & ! number of ice layers - nblyr , & ! number of bio layers - nslyr , & ! number of snow layers - ntrcr , & ! number of tracers in use - n_aero , & ! number of aerosol tracers - nbtrcr ! number of biology tracers - real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -1096,6 +1050,7 @@ subroutine zap_small_areas (dt, ntrcr, & blevels real (kind=dbl_kind) :: xtmp, sicen ! temporary variables + real (kind=dbl_kind) :: dvssl, dvint ! temporary variables real (kind=dbl_kind) , dimension (1):: trcr_skl real (kind=dbl_kind) , dimension (nblyr+1):: bvol @@ -1146,7 +1101,6 @@ subroutine zap_small_areas (dt, ntrcr, & if (skl_bgc .and. nbtrcr > 0) then blevels = 1 bvol(1) = aicen(n)*sk_l - it = 1 do it = 1, nbtrcr trcr_skl(1) = trcrn(bio_index(it),n) call zap_small_bgc(blevels, dflux_bio(it), & @@ -1202,14 +1156,13 @@ subroutine zap_small_areas (dt, ntrcr, & !----------------------------------------------------------------- ! Zap snow !----------------------------------------------------------------- - call zap_snow(dt, nslyr, & + call zap_snow(dt, & trcrn(:,n), vsnon(n), & dfresh, dfhocn, & dfaero_ocn, tr_aero, & dfiso_ocn, & - dflux_bio, nbtrcr, & - n_aero, & - aicen(n), nblyr) + dflux_bio, & + aicen(n)) if (icepack_warnings_aborted(subname)) return !----------------------------------------------------------------- @@ -1273,6 +1226,36 @@ subroutine zap_small_areas (dt, ntrcr, & enddo ! it endif + if (skl_bgc .and. nbtrcr > 0) then + blevels = 1 + bvol(1) = (aice-c1)/aice * sk_l + do it = 1, nbtrcr + trcr_skl(1) = trcrn(bio_index(it),n) + call zap_small_bgc(blevels, dflux_bio(it), & + dt, bvol(1:blevels), trcr_skl(blevels)) + enddo + elseif (z_tracers .and. nbtrcr > 0) then + blevels = nblyr + 1 + bvol(:) = (aice-c1)/aice*vicen(n)/real(nblyr,kind=dbl_kind)*trcrn(nt_fbri,n) + bvol(1) = p5*bvol(1) + bvol(blevels) = p5*bvol(blevels) + do it = 1, nbtrcr + call zap_small_bgc(blevels, dflux_bio(it), & + dt, bvol(1:blevels),trcrn(bio_index(it):bio_index(it)+blevels-1,n)) + if (icepack_warnings_aborted(subname)) return + enddo + ! zap snow zaerosols + dvssl = p5*vsnon(n)/real(nslyr,kind=dbl_kind) ! snow surface layer + dvint = vsnon(n) - dvssl ! snow interior + + do it = 1, nbtrcr + xtmp = (trcrn(bio_index(it)+nblyr+1,n)*dvssl + & + trcrn(bio_index(it)+nblyr+2,n)*dvint)*(aice-c1)/aice/dt + dflux_bio(it) = dflux_bio(it) + xtmp + enddo ! it + + endif + if (tr_iso) then do it = 1, n_iso xtmp = (vsnon(n)*trcrn(nt_isosno+it-1,n) & @@ -1346,20 +1329,12 @@ end subroutine zap_small_areas !======================================================================= - subroutine zap_snow(dt, nslyr, & + subroutine zap_snow(dt, & trcrn, vsnon, & dfresh, dfhocn, & dfaero_ocn, tr_aero, & dfiso_ocn, & - dflux_bio, nbtrcr, & - n_aero, & - aicen, nblyr) - - integer (kind=int_kind), intent(in) :: & - nslyr , & ! number of snow layers - n_aero , & ! number of aerosol tracers - nblyr , & ! number of bio layers - nbtrcr + dflux_bio, aicen) real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -1414,8 +1389,8 @@ subroutine zap_snow(dt, nslyr, & endif ! tr_iso if (z_tracers) then - dvssl = min(p5*vsnon/real(nslyr,kind=dbl_kind), hs_ssl*aicen) ! snow surface layer - dvint = vsnon - dvssl ! snow interior + dvssl = p5*vsnon/real(nslyr,kind=dbl_kind) ! snow surface layer + dvint = vsnon - dvssl ! snow interior do it = 1, nbtrcr xtmp = (trcrn(bio_index(it)+nblyr+1)*dvssl + & @@ -1442,22 +1417,12 @@ end subroutine zap_snow !======================================================================= - subroutine zap_snow_temperature(dt, ncat, & - nblyr, & - nslyr, aicen, & + subroutine zap_snow_temperature(dt, aicen, & trcrn, vsnon, & dfresh, dfhocn, & dfaero_ocn, tr_aero, & dfiso_ocn, & - dflux_bio, nbtrcr, & - n_aero ) - - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nslyr , & ! number of snow layers - n_aero, & ! number of aerosol tracers - nbtrcr, & ! number of z-tracers in use - nblyr ! number of bio layers in ice + dflux_bio) real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -1560,14 +1525,13 @@ subroutine zap_snow_temperature(dt, ncat, & ! Zap the cells !----------------------------------------------------------------- if (l_zap) & - call zap_snow(dt, nslyr, & + call zap_snow(dt, & trcrn(:,n), vsnon(n), & dfresh, dfhocn, & dfaero_ocn, tr_aero, & dfiso_ocn, & - dflux_bio, nbtrcr, & - n_aero, & - aicen(n), nblyr) + dflux_bio, & + aicen(n)) if (icepack_warnings_aborted(subname)) return enddo ! n @@ -1581,10 +1545,7 @@ end subroutine zap_snow_temperature ! authors: William H. Lipscomb and Elizabeth C. Hunke, LANL ! C. M. Bitz, UW - subroutine icepack_init_itd(ncat, hin_max) - - integer (kind=int_kind), intent(in) :: & - ncat ! number of thickness categories + subroutine icepack_init_itd(hin_max) real (kind=dbl_kind), intent(out) :: & hin_max(0:ncat) ! category limits (m) @@ -1760,10 +1721,7 @@ end subroutine icepack_init_itd ! authors: William H. Lipscomb and Elizabeth C. Hunke, LANL ! C. M. Bitz, UW - subroutine icepack_init_itd_hist (ncat, hin_max, c_hi_range) - - integer (kind=int_kind), intent(in) :: & - ncat ! number of thickness categories + subroutine icepack_init_itd_hist (hin_max, c_hi_range) real (kind=dbl_kind), intent(in) :: & hin_max(0:ncat) ! category limits (m) @@ -1815,22 +1773,16 @@ end subroutine icepack_init_itd_hist ! authors: C. M. Bitz, UW ! W. H. Lipscomb, LANL - subroutine icepack_aggregate (ncat, & - aicen, trcrn, & + subroutine icepack_aggregate(aicen, trcrn, & vicen, vsnon, & aice, trcr, & vice, vsno, & aice0, & - ntrcr, & trcr_depend, & trcr_base, & n_trcr_strata, & nt_strata, Tf) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - ntrcr ! number of tracers in use - real (kind=dbl_kind), dimension (:), intent(in) :: & aicen , & ! concentration of ice vicen , & ! volume per unit area of ice (m) @@ -1919,7 +1871,7 @@ subroutine icepack_aggregate (ncat, & aice0 = max (c1 - aice, c0) ! Tracers - call icepack_compute_tracers (ntrcr, trcr_depend, & + call icepack_compute_tracers(trcr_depend, & atrcr, aice, & vice , vsno, & trcr_base, n_trcr_strata, & diff --git a/columnphysics/icepack_mechred.F90 b/columnphysics/icepack_mechred.F90 index d897dba49..6205b581a 100644 --- a/columnphysics/icepack_mechred.F90 +++ b/columnphysics/icepack_mechred.F90 @@ -40,12 +40,13 @@ module icepack_mechred use icepack_parameters, only: icepack_chkoptargflag use icepack_parameters, only: kstrength, krdg_partic, krdg_redist, mu_rdg - use icepack_parameters, only: conserv_check + use icepack_parameters, only: conserv_check, z_tracers + use icepack_tracers, only: ncat, nilyr, nslyr, nblyr, n_aero use icepack_tracers, only: tr_pond_topo, tr_aero, tr_iso, tr_brine, ntrcr, nbtrcr use icepack_tracers, only: nt_qice, nt_qsno, nt_fbri, nt_sice use icepack_tracers, only: nt_alvl, nt_vlvl, nt_aero, nt_isosno, nt_isoice use icepack_tracers, only: nt_apnd, nt_hpnd - use icepack_tracers, only: n_iso + use icepack_tracers, only: n_iso, bio_index use icepack_tracers, only: icepack_compute_tracers use icepack_warnings, only: warnstr, icepack_warnings_add @@ -87,9 +88,7 @@ module icepack_mechred ! author: William H. Lipscomb, LANL subroutine ridge_ice (dt, ndtd, & - ncat, n_aero, & - nilyr, nslyr, & - ntrcr, hin_max, & + hin_max, & rdg_conv, rdg_shear, & aicen, trcrn, & vicen, vsnon, & @@ -101,7 +100,7 @@ subroutine ridge_ice (dt, ndtd, & mu_rdg, tr_brine, & dardg1dt, dardg2dt, & dvirdgdt, opening, & - fpond, & + fpond, flux_bio, & fresh, fhocn, & faero_ocn, fiso_ocn, & aparticn, krdgn, & @@ -112,12 +111,7 @@ subroutine ridge_ice (dt, ndtd, & closing ) integer (kind=int_kind), intent(in) :: & - ndtd , & ! number of dynamics subcycles - ncat , & ! number of thickness categories - nilyr , & ! number of ice layers - nslyr , & ! number of snow layers - n_aero, & ! number of aerosol tracers - ntrcr ! number of tracers in use + ndtd ! number of dynamics subcycles real (kind=dbl_kind), intent(in) :: & mu_rdg , & ! gives e-folding scale of ridged ice (m^.5) @@ -187,6 +181,9 @@ subroutine ridge_ice (dt, ndtd, & real (kind=dbl_kind), dimension(:), intent(inout), optional :: & faero_ocn ! aerosol flux to ocean (kg/m^2/s) + real (kind=dbl_kind), dimension(:), intent(inout), optional :: & + flux_bio ! biological and zaerosol flux to ocean (kg/m^2/s) + real (kind=dbl_kind), dimension(:), intent(inout), optional :: & fiso_ocn ! isotope flux to ocean (kg/m^2/s) @@ -220,6 +217,9 @@ subroutine ridge_ice (dt, ndtd, & real (kind=dbl_kind), dimension (n_aero) :: & maero ! aerosol mass added to ocean (kg m-2) + real (kind=dbl_kind), dimension (nbtrcr) :: & + mbio ! bio mass added to ocean (mmol or kg m-2) + real (kind=dbl_kind), dimension (n_iso) :: & miso ! isotope mass added to ocean (kg m-2) @@ -272,6 +272,7 @@ subroutine ridge_ice (dt, ndtd, & msnow_mlt = c0 esnow_mlt = c0 maero (:) = c0 + mbio (:) = c0 miso (:) = c0 mpond = c0 ardg1 = c0 @@ -287,7 +288,7 @@ subroutine ridge_ice (dt, ndtd, & ! Compute area of ice plus open water before ridging. !----------------------------------------------------------------- - call asum_ridging (ncat, aicen, aice0, asum) + call asum_ridging (aicen, aice0, asum) if (icepack_warnings_aborted(subname)) return !----------------------------------------------------------------- @@ -302,8 +303,7 @@ subroutine ridge_ice (dt, ndtd, & else - call ridge_prep (dt, & - ncat, hin_max, & + call ridge_prep (dt, hin_max, & rdg_conv, rdg_shear, & asum, closing_net, & divu_adv, opning) @@ -366,10 +366,10 @@ subroutine ridge_ice (dt, ndtd, & ! and various quantities associated with the new ridged ice. !----------------------------------------------------------------- - call ridge_itd (ncat, aice0, & + call ridge_itd (aice0, & aicen, vicen, & - krdg_partic, krdg_redist, & - mu_rdg, & + krdg_partic, krdg_redist,& + mu_rdg, & aksum, apartic, & hrmin, hrmax, & hrexp, krdg, & @@ -381,8 +381,7 @@ subroutine ridge_ice (dt, ndtd, & ! Redistribute area, volume, and energy. !----------------------------------------------------------------- - call ridge_shift (ntrcr, dt, & - ncat, hin_max, & + call ridge_shift (dt, hin_max, & aicen, trcrn, & vicen, vsnon, & aice0, trcr_depend, & @@ -396,11 +395,11 @@ subroutine ridge_ice (dt, ndtd, & virdg, aopen, & ardg1n, ardg2n, & virdgn, & - nslyr, n_aero, & msnow_mlt, esnow_mlt, & maero, miso, & mpond, Tf, & - aredistn, vredistn) + aredistn, vredistn, & + mbio) if (icepack_warnings_aborted(subname)) return !----------------------------------------------------------------- @@ -409,7 +408,7 @@ subroutine ridge_ice (dt, ndtd, & ! with new rates. !----------------------------------------------------------------- - call asum_ridging (ncat, aicen, aice0, asum) + call asum_ridging (aicen, aice0, asum) if (icepack_warnings_aborted(subname)) return if (abs(asum - c1) < puny) then @@ -590,6 +589,11 @@ subroutine ridge_ice (dt, ndtd, & faero_ocn(it) = faero_ocn(it) + maero(it)*dti enddo endif + if (present(flux_bio)) then + do it = 1, nbtrcr + flux_bio(it) = flux_bio(it) + mbio(it)*dti + enddo + endif if (present(fiso_ocn)) then if (tr_iso) then ! check size fiso_ocn vs n_iso ??? @@ -639,10 +643,7 @@ end subroutine ridge_ice ! ! author: William H. Lipscomb, LANL - subroutine asum_ridging (ncat, aicen, aice0, asum) - - integer (kind=int_kind), intent(in) :: & - ncat ! number of thickness categories + subroutine asum_ridging (aicen, aice0, asum) real (kind=dbl_kind), dimension (:), intent(in) :: & aicen ! concentration of ice in each category @@ -672,15 +673,11 @@ end subroutine asum_ridging ! ! author: William H. Lipscomb, LANL - subroutine ridge_prep (dt, & - ncat, hin_max, & + subroutine ridge_prep (dt, hin_max, & rdg_conv, rdg_shear, & asum, closing_net, & divu_adv, opning) - integer (kind=int_kind), intent(in) :: & - ncat ! number of thickness categories - real (kind=dbl_kind), intent(in) :: & dt ! time step (s) @@ -774,7 +771,7 @@ end subroutine ridge_prep ! 2006: Changed subroutine name to ridge_itd ! Added new options for ridging participation and redistribution. - subroutine ridge_itd (ncat, aice0, & + subroutine ridge_itd (aice0, & aicen, vicen, & krdg_partic, krdg_redist, & mu_rdg, & @@ -784,9 +781,6 @@ subroutine ridge_itd (ncat, aice0, & aparticn, krdgn, & mraft) - integer (kind=int_kind), intent(in) :: & - ncat ! number of thickness categories - real (kind=dbl_kind), intent(in) :: & mu_rdg , & ! gives e-folding scale of ridged ice (m^.5) aice0 ! concentration of open water @@ -1066,8 +1060,7 @@ end subroutine ridge_itd ! ! author: William H. Lipscomb, LANL - subroutine ridge_shift (ntrcr, dt, & - ncat, hin_max, & + subroutine ridge_shift (dt, hin_max, & aicen, trcrn, & vicen, vsnon, & aice0, trcr_depend, & @@ -1081,17 +1074,13 @@ subroutine ridge_shift (ntrcr, dt, & virdg, aopen, & ardg1nn, ardg2nn, & virdgnn, & - nslyr, n_aero, & msnow_mlt, esnow_mlt, & maero, miso, & mpond, Tf, & - aredistn, vredistn) + aredistn, vredistn, & + mbio) integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nslyr , & ! number of snow layers - ntrcr , & ! number of tracers in use - n_aero, & ! number of aerosol tracers krdg_redist ! selects redistribution function real (kind=dbl_kind), intent(in) :: & @@ -1162,6 +1151,9 @@ subroutine ridge_shift (ntrcr, dt, & real (kind=dbl_kind), dimension(:), intent(inout) :: & miso ! isotope mass added to ocean (kg m-2) + real (kind=dbl_kind), dimension(:), intent(inout) :: & + mbio ! biology and zaerosol mass added to ocean (kg m-2) + real (kind=dbl_kind), dimension (:), intent(inout), optional :: & aredistn , & ! redistribution function: fraction of new ridge area vredistn ! redistribution function: fraction of new ridge volume @@ -1214,7 +1206,9 @@ subroutine ridge_shift (ntrcr, dt, & hL, hR , & ! left and right limits of integration expL, expR , & ! exponentials involving hL, hR tmpfac , & ! factor by which opening/closing rates are cut - wk1 ! work variable + wk1 , & ! work variable + dzssl , & ! fraction of snow surface biotracers + dzint ! fraction of interior snow biotracers character(len=*),parameter :: subname='(ridge_shift)' @@ -1385,6 +1379,16 @@ subroutine ridge_shift (ntrcr, dt, & enddo endif + if (z_tracers .and. nbtrcr > 0) then + dzssl = p5/real(nslyr,kind=dbl_kind) + dzint = c1-dzssl + do it = 1, nbtrcr + mbio(it) = mbio(it) + vsrdgn*(c1-fsnowrdg) & + * (trcrn(bio_index(it) + nblyr + 1,n) * dzssl & + + trcrn(bio_index(it) + nblyr + 2,n) * dzint) + enddo + endif + if (tr_pond_topo) then mpond = mpond + ardg1n * trcrn(nt_apnd,n) & * trcrn(nt_hpnd,n) @@ -1570,7 +1574,7 @@ subroutine ridge_shift (ntrcr, dt, & !----------------------------------------------------------------- do n = 1, ncat - call icepack_compute_tracers (ntrcr, trcr_depend, & + call icepack_compute_tracers (trcr_depend, & atrcrn(:,n), aicen(n), & vicen(n), vsnon(n), & trcr_base, n_trcr_strata, & @@ -1596,15 +1600,11 @@ end subroutine ridge_shift ! authors: William H. Lipscomb, LANL ! Elizabeth C. Hunke, LANL - subroutine icepack_ice_strength (ncat, & - aice, vice, & + subroutine icepack_ice_strength(aice, vice, & aice0, aicen, & vicen, & strength) - integer (kind=int_kind), intent(in) :: & - ncat ! number of thickness categories - real (kind=dbl_kind), intent(in) :: & aice , & ! concentration of ice vice , & ! volume per unit area of ice (m) @@ -1652,13 +1652,13 @@ subroutine icepack_ice_strength (ncat, & ! Compute thickness distribution of ridging and ridged ice. !----------------------------------------------------------------- - call asum_ridging (ncat, aicen, aice0, asum) + call asum_ridging (aicen, aice0, asum) if (icepack_warnings_aborted(subname)) return - call ridge_itd (ncat, aice0, & + call ridge_itd (aice0, & aicen, vicen, & krdg_partic, krdg_redist, & - mu_rdg, & + mu_rdg, & aksum, apartic, & hrmin, hrmax, & hrexp, krdg) @@ -1719,10 +1719,8 @@ end subroutine icepack_ice_strength ! authors: William H. Lipscomb, LANL ! Elizabeth C. Hunke, LANL - subroutine icepack_step_ridge (dt, ndtd, & - nilyr, nslyr, & - nblyr, & - ncat, hin_max, & + subroutine icepack_step_ridge(dt, ndtd, & + hin_max, & rdg_conv, rdg_shear, & aicen, & trcrn, & @@ -1734,7 +1732,6 @@ subroutine icepack_step_ridge (dt, ndtd, & dvirdgdt, opening, & fpond, & fresh, fhocn, & - n_aero, & faero_ocn, fiso_ocn, & aparticn, krdgn, & aredistn, vredistn, & @@ -1752,12 +1749,7 @@ subroutine icepack_step_ridge (dt, ndtd, & Tf ! freezing temperature integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - ndtd , & ! number of dynamics supercycles - nblyr , & ! number of bio layers - nilyr , & ! number of ice layers - nslyr , & ! number of snow layers - n_aero ! number of aerosol tracers + ndtd ! number of dynamics supercycles real (kind=dbl_kind), dimension(0:ncat), intent(inout) :: & hin_max ! category limits (m) @@ -1858,9 +1850,7 @@ subroutine icepack_step_ridge (dt, ndtd, & !----------------------------------------------------------------- call ridge_ice (dt, ndtd, & - ncat, n_aero, & - nilyr, nslyr, & - ntrcr, hin_max, & + hin_max, & rdg_conv, rdg_shear, & aicen, & trcrn, & @@ -1874,7 +1864,7 @@ subroutine icepack_step_ridge (dt, ndtd, & mu_rdg, tr_brine, & dardg1dt, dardg2dt, & dvirdgdt, opening, & - fpond, & + fpond, flux_bio, & fresh, fhocn, & faero_ocn, fiso_ocn, & aparticn, krdgn, & @@ -1891,14 +1881,10 @@ subroutine icepack_step_ridge (dt, ndtd, & !----------------------------------------------------------------- dtt = dt * ndtd ! for proper averaging over thermo timestep - call cleanup_itd (dtt, ntrcr, & - nilyr, nslyr, & - ncat, hin_max, & + call cleanup_itd (dtt, hin_max, & aicen, trcrn, & vicen, vsnon, & aice0, aice, & - n_aero, & - nbtrcr, nblyr, & tr_aero, & tr_pond_topo, & first_ice, & diff --git a/columnphysics/icepack_meltpond_topo.F90 b/columnphysics/icepack_meltpond_topo.F90 index 830c7a0b0..23928fef3 100644 --- a/columnphysics/icepack_meltpond_topo.F90 +++ b/columnphysics/icepack_meltpond_topo.F90 @@ -23,6 +23,7 @@ module icepack_meltpond_topo use icepack_parameters, only: c0, c1, c2, p01, p1, p15, p4, p6 use icepack_parameters, only: puny, viscosity_dyn, rhoi, rhos, rhow, Timelt, Lfresh use icepack_parameters, only: gravit, depressT, kice, ice_ref_salinity + use icepack_tracers, only: ncat, nilyr use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted use icepack_therm_shared, only: calculate_Tin_from_qin @@ -38,7 +39,7 @@ module icepack_meltpond_topo !======================================================================= - subroutine compute_ponds_topo(dt, ncat, nilyr, & + subroutine compute_ponds_topo(dt, & ktherm, & aice, aicen, & vice, vicen, & @@ -50,8 +51,6 @@ subroutine compute_ponds_topo(dt, ncat, nilyr, & apnd, hpnd, ipnd ) integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nilyr, & ! number of ice layers ktherm ! type of thermodynamics (0 0-layer, 1 BL99, 2 mushy) real (kind=dbl_kind), intent(in) :: & @@ -159,7 +158,7 @@ subroutine compute_ponds_topo(dt, ncat, nilyr, & !-------------------------------------------------------------- ! calculate pond area and depth !-------------------------------------------------------------- - call pond_area(dt, ncat, nilyr, & + call pond_area(dt, & ktherm, & aice, vice, vsno, & aicen, vicen, vsnon, & @@ -291,7 +290,7 @@ end subroutine compute_ponds_topo ! Computes melt pond area, pond depth and melting rates - subroutine pond_area(dt, ncat, nilyr,& + subroutine pond_area(dt, & ktherm, & aice, vice, vsno, & aicen, vicen, vsnon,& @@ -300,8 +299,6 @@ subroutine pond_area(dt, ncat, nilyr,& apondn,hpondn,dvolp ) integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nilyr, & ! number of ice layers ktherm ! type of thermodynamics (-1 none, 1 BL99, 2 mushy) real (kind=dbl_kind), intent(in) :: & @@ -469,7 +466,7 @@ subroutine pond_area(dt, ncat, nilyr,& ! height and area corresponding to the remaining volume - call calc_hpond(ncat, reduced_aicen, asnon, hsnon, & + call calc_hpond(reduced_aicen, asnon, hsnon, & alfan, volp, cum_max_vol, hpond, m_index) if (icepack_warnings_aborted(subname)) return @@ -495,7 +492,7 @@ subroutine pond_area(dt, ncat, nilyr,& if (ktherm /= 2 .and. pressure_head > c0) then do n = 1, ncat-1 if (hicen(n) > c0) then - call permeability_phi(nilyr, qicen(:,n), sicen(:,n), perm) + call permeability_phi(qicen(:,n), sicen(:,n), perm) if (icepack_warnings_aborted(subname)) return if (perm > c0) permflag = 1 drain = perm*apondn(n)*pressure_head*dt / (viscosity_dyn*hicen(n)) @@ -511,7 +508,7 @@ subroutine pond_area(dt, ncat, nilyr,& ! adjust melt pond dimensions if (permflag > 0) then ! recompute pond depth - call calc_hpond(ncat, reduced_aicen, asnon, hsnon, & + call calc_hpond(reduced_aicen, asnon, hsnon, & alfan, volp, cum_max_vol, hpond, m_index) if (icepack_warnings_aborted(subname)) return do n=1, m_index @@ -569,12 +566,9 @@ end subroutine pond_area !======================================================================= - subroutine calc_hpond(ncat, aicen, asnon, hsnon, & + subroutine calc_hpond(aicen, asnon, hsnon, & alfan, volp, cum_max_vol, hpond, m_index) - integer (kind=int_kind), intent(in) :: & - ncat ! number of thickness categories - real (kind=dbl_kind), dimension(:), intent(in) :: & aicen, & asnon, & @@ -734,10 +728,7 @@ end subroutine calc_hpond ! determine the liquid fraction of brine in the ice and the permeability - subroutine permeability_phi(nilyr, qicen, sicen, perm) - - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers + subroutine permeability_phi(qicen, sicen, perm) real (kind=dbl_kind), dimension(:), intent(in) :: & qicen, & ! energy of melting for each ice layer (J/m2) diff --git a/columnphysics/icepack_mushy_physics.F90 b/columnphysics/icepack_mushy_physics.F90 index 8ab819768..244faa725 100644 --- a/columnphysics/icepack_mushy_physics.F90 +++ b/columnphysics/icepack_mushy_physics.F90 @@ -5,6 +5,7 @@ module icepack_mushy_physics use icepack_parameters, only: puny use icepack_parameters, only: rhow, rhoi, rhos, cp_ocn, cp_ice, Lfresh use icepack_parameters, only: ksno + use icepack_tracers, only: nilyr use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted @@ -70,10 +71,7 @@ module icepack_mushy_physics !======================================================================= ! Detemine the conductivity of the mush from enthalpy and salinity - subroutine conductivity_mush_array(nilyr, zqin, zSin, km) - - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers + subroutine conductivity_mush_array(zqin, zSin, km) real(kind=dbl_kind), dimension(:), intent(in) :: & zqin, & ! ice layer enthalpy (J m-3) diff --git a/columnphysics/icepack_parameters.F90 b/columnphysics/icepack_parameters.F90 index e76b23b09..ef82b0695 100644 --- a/columnphysics/icepack_parameters.F90 +++ b/columnphysics/icepack_parameters.F90 @@ -192,6 +192,7 @@ module icepack_parameters kappav = 1.4_dbl_kind ,&! vis extnctn coef in ice, wvlngth<700nm (1/m) hi_ssl = 0.050_dbl_kind,&! ice surface scattering layer thickness (m) hs_ssl = 0.040_dbl_kind,&! snow surface scattering layer thickness (m) + hs_ssl_min = 5.e-4_dbl_kind,&! minimum snow surface scattering layer thickness for aerosol (m) ! baseline albedos for ccsm3 shortwave, set in namelist albicev = 0.78_dbl_kind ,&! visible ice albedo for h > ahmax albicei = 0.36_dbl_kind ,&! near-ir ice albedo for h > ahmax @@ -205,8 +206,9 @@ module icepack_parameters dT_mlt = c1p5 ,&! change in temp for non-melt to melt snow grain ! radius change (C) rsnw_mlt = 1500._dbl_kind,&! maximum melting snow grain radius (10^-6 m) - kalg = 0.60_dbl_kind ! algae absorption coefficient for 0.5 m thick layer + kalg = 0.60_dbl_kind, &! algae absorption coefficient for 0.5 m thick layer ! 0.5 m path of 75 mg Chl a / m2 + R_gC2molC = 12.0107_dbl_kind! g carbon per mol carbon ! weights for albedos ! 4 Jan 2007 BPB Following are appropriate for complete cloud ! in a summer polar atmosphere with 1.5m bare sea ice surface: @@ -398,19 +400,23 @@ module icepack_parameters scale_bgc = .false., & ! if .true., initialize bgc tracers proportionally with salinity solve_zbgc = .false., & ! if .true., solve vertical biochemistry portion of code dEdd_algae = .false., & ! if .true., algal absorption of shortwave is computed in the - skl_bgc = .false. ! if true, solve skeletal biochemistry + skl_bgc = .false., & ! if true, solve skeletal biochemistry + use_macromolecules = .false., & ! if true, ocean DOC already split into + ! polysaccharids, lipid and protein fractions + use_atm_dust_iron = .false., & ! if .true., compute iron contribution from dust + restartbgc = .false. real (kind=dbl_kind), public :: & - phi_snow = p5 , & ! snow porosity - grid_o = c5 , & ! for bottom flux + phi_snow = -1.0_dbl_kind , & ! snow porosity (compute from snow density if negative) + grid_o = 0.006_dbl_kind , & ! for bottom flux initbio_frac = c1 , & ! fraction of ocean trcr concentration in bio trcrs - l_sk = 7.0_dbl_kind , & ! characteristic diffusive scale (m) - grid_oS = c5 , & ! for bottom flux - l_skS = 7.0_dbl_kind , & ! characteristic skeletal layer thickness (m) (zsalinity) - algal_vel = 1.11e-8_dbl_kind, & ! 0.5 cm/d(m/s) Lavoie 2005 1.5 cm/day + l_sk = 2.0_dbl_kind , & ! characteristic diffusive scale (m) + grid_oS = c0 , & ! for bottom flux + l_skS = 0.028_dbl_kind , & ! characteristic skeletal layer thickness (m) (zsalinity) + algal_vel = 1.0e-7_dbl_kind , & ! 0.5 cm/d(m/s) Lavoie 2005 1.5 cm/day R_dFe2dust = 0.035_dbl_kind , & ! g/g (3.5% content) Tagliabue 2009 dustFe_sol = 0.005_dbl_kind , & ! solubility fraction - frazil_scav = c1 , & ! fraction or multiple of bgc concentrated in frazil ice + frazil_scav = 0.8_dbl_kind , & ! fraction or multiple of bgc concentrated in frazil ice sk_l = 0.03_dbl_kind , & ! skeletal layer thickness (m) min_bgc = 0.01_dbl_kind , & ! fraction of ocean bgc concentration in surface melt T_max = c0 , & ! maximum temperature (C) @@ -418,20 +424,116 @@ module icepack_parameters op_dep_min = p1 , & ! light attenuates for optical depths exceeding min fr_graze_s = p5 , & ! fraction of grazing spilled or slopped fr_graze_e = p5 , & ! fraction of assimilation excreted - fr_mort2min = p5 , & ! fractionation of mortality to Am - fr_dFe = 0.3_dbl_kind , & ! fraction of remineralized nitrogen + fr_mort2min = 0.9_dbl_kind , & ! fractionation of mortality to Am + fr_dFe = 1.0_dbl_kind , & ! fraction of remineralized nitrogen ! (in units of algal iron) - k_nitrif = c0 , & ! nitrification rate (1/day) + k_nitrif = 0.046_dbl_kind , & ! nitrification rate (1/day) t_iron_conv = 3065.0_dbl_kind , & ! desorption loss pFe to dFe (day) max_loss = 0.9_dbl_kind , & ! restrict uptake to % of remaining value max_dfe_doc1 = 0.2_dbl_kind , & ! max ratio of dFe to saccharides in the ice ! (nM Fe/muM C) fr_resp = 0.05_dbl_kind , & ! fraction of algal growth lost due to respiration - fr_resp_s = 0.75_dbl_kind , & ! DMSPd fraction of respiration loss as DMSPd - y_sk_DMS = p5 , & ! fraction conversion given high yield - t_sk_conv = 3.0_dbl_kind , & ! Stefels conversion time (d) - t_sk_ox = 10.0_dbl_kind ! DMS oxidation time (d) - + fr_resp_s = 0.90_dbl_kind , & ! DMSPd fraction of respiration loss as DMSPd + y_sk_DMS = 0.7_dbl_kind , & ! fraction conversion given high yield + t_sk_conv = 5.0_dbl_kind , & ! Stefels conversion time (d) + t_sk_ox = 12.0_dbl_kind , & ! DMS oxidation time (d) + grid_o_t = 0.006_dbl_kind , & ! ice surface molecular sublayer thickness (m) + ratio_Si2N_diatoms = 1.8_dbl_kind , & ! algal Si to N (mol/mol) + ratio_Si2N_sp = c0 , & + ratio_Si2N_phaeo = c0 , & + ratio_S2N_diatoms = 0.03_dbl_kind , & ! algal S to N (mol/mol) + ratio_S2N_sp = 0.03_dbl_kind , & + ratio_S2N_phaeo = 0.03_dbl_kind , & + ratio_Fe2C_diatoms = 0.0033_dbl_kind, & ! algal Fe to C (umol/mol) + ratio_Fe2C_sp = 0.0033_dbl_kind, & + ratio_Fe2C_phaeo = 0.1_dbl_kind , & + ratio_Fe2N_diatoms = 0.023_dbl_kind , & ! algal Fe to N (umol/mol) + ratio_Fe2N_sp = 0.023_dbl_kind , & + ratio_Fe2N_phaeo = 0.7_dbl_kind , & + ratio_Fe2DON = 0.023_dbl_kind , & ! Fe to N of DON (nmol/umol) + ratio_Fe2DOC_s = 0.1_dbl_kind , & ! Fe to C of DOC (nmol/umol) saccharids + ratio_Fe2DOC_l = 0.033_dbl_kind , & ! Fe to C of DOC (nmol/umol) lipids + tau_min = 3600.0_dbl_kind, & ! rapid timescale for mobile to stationary exchanges (s) + tau_max = 604800.0_dbl_kind, & ! short timescale for mobile to stationary exchanges (s) + chlabs_diatoms = 0.03_dbl_kind , & ! absorptivity for diatoms (1/m/(mg/m3)) + chlabs_sp = 0.01_dbl_kind , & ! absorptivity for small plankton (1/m/(mg/m3)) + chlabs_phaeo = 0.05_dbl_kind , & ! absorptivity for phaeocystis (1/m/(mg/m3)) + alpha2max_low_diatoms = 0.3_dbl_kind, & ! light limitation for diatoms (1/(W/m2)) + alpha2max_low_sp = 0.2_dbl_kind , & ! light limitation for small plankton (1/(W/m2)) + alpha2max_low_phaeo = 0.17_dbl_kind , & ! light limitation for phaeocystis(1/(W/m2)) + beta2max_diatoms = 0.001_dbl_kind , & ! light inhibition (1/(W/m^2)) + beta2max_sp = 0.001_dbl_kind , & + beta2max_phaeo = 0.04_dbl_kind , & + mu_max_diatoms = 1.44_dbl_kind , & ! maximum growth rate (1/day) + mu_max_sp = 0.41_dbl_kind , & + mu_max_phaeo = 0.63_dbl_kind , & + grow_Tdep_diatoms = 0.063_dbl_kind , & ! Temperature dependence of growth (1/C) + grow_Tdep_sp = 0.063_dbl_kind , & + grow_Tdep_phaeo = 0.063_dbl_kind , & + fr_graze_diatoms = 0.19_dbl_kind , & ! Fraction grazed + fr_graze_sp = 0.19_dbl_kind , & + fr_graze_phaeo = 0.19_dbl_kind , & + mort_pre_diatoms = 0.007_dbl_kind , & ! Mortality (1/day) + mort_pre_sp = 0.007_dbl_kind , & + mort_pre_phaeo = 0.007_dbl_kind , & + mort_Tdep_diatoms = 0.03_dbl_kind , & ! T dependence of mortality (1/C) + mort_Tdep_sp = 0.03_dbl_kind , & + mort_Tdep_phaeo = 0.03_dbl_kind , & + k_exude_diatoms = c0 , & ! algal exudation (1/d) + k_exude_sp = c0 , & + k_exude_phaeo = c0 , & + K_Nit_diatoms = c1 , & ! nitrate half saturation (mmol/m^3) + K_Nit_sp = c1 , & + K_Nit_phaeo = c1 , & + K_Am_diatoms = 0.3_dbl_kind , & ! ammonium half saturation (mmol/m^3) + K_Am_sp = 0.3_dbl_kind , & + K_Am_phaeo = 0.3_dbl_kind , & + K_Sil_diatoms = 4.0_dbl_kind , & ! silicate half saturation (mmol/m^3) + K_Sil_sp = c0 , & + K_Sil_phaeo = c0 , & + K_Fe_diatoms = c1 , & ! iron half saturation (nM) + K_Fe_sp = 0.2_dbl_kind , & + K_Fe_phaeo = 0.1_dbl_kind , & + f_don_protein = 0.6_dbl_kind , & ! fraction of spilled grazing to proteins + kn_bac_protein = 0.2_dbl_kind , & ! Bacterial degredation of DON (1/d) + f_don_Am_protein = c1 , & ! fraction of remineralized DON to ammonium + f_doc_s = 0.5_dbl_kind , & ! fraction of mortality to DOC + f_doc_l = 0.5_dbl_kind , & + f_exude_s = c1 , & ! fraction of exudation to DOC + f_exude_l = c1 , & + k_bac_s = 0.03_dbl_kind , & ! Bacterial degredation of DOC (1/d) + k_bac_l = 0.03_dbl_kind , & + algaltype_diatoms = c0 , & ! mobility type + algaltype_sp = c0 , & ! algal groups + algaltype_phaeo = c0 , & ! + nitratetype = -1.0_dbl_kind , & ! nitrate + ammoniumtype = c0 , & ! ammonium + silicatetype = -1.0_dbl_kind , & ! silicate + dmspptype = 0.5_dbl_kind , & ! DMS + dmspdtype = c0 , & ! + humtype = c0 , & ! humics + doctype_s = c0 , & ! DOC + doctype_l = c0 , & ! + dictype_1 = -1.0_dbl_kind , & ! DIC + dontype_protein = c0 , & ! DON + fedtype_1 = c0 , & ! Iron + feptype_1 = 0.5_dbl_kind , & ! + zaerotype_bc1 = -1.0_dbl_kind , & ! Aerosols + zaerotype_bc2 = -1.0_dbl_kind , & ! + zaerotype_dust1 = -1.0_dbl_kind , & ! + zaerotype_dust2 = -1.0_dbl_kind , & ! + zaerotype_dust3 = -1.0_dbl_kind , & ! + zaerotype_dust4 = -1.0_dbl_kind , & ! + ratio_C2N_diatoms = 7.0_dbl_kind , & ! algal carbon to nitrogen mole ratio + ratio_C2N_sp = 7.0_dbl_kind , & + ratio_C2N_phaeo = 7.0_dbl_kind , & + ratio_chl2N_diatoms = 2.1_dbl_kind , & ! algal chlorophyll to nitrogen ratio (g chla/mol) + ratio_chl2N_sp = 1.1_dbl_kind , & + ratio_chl2N_phaeo = 0.84_dbl_kind , & + ratio_C2N_proteins = 5.0_dbl_kind , &! Ratio of carbon to nitrogen in proteins + F_abs_chl_diatoms = 2.0_dbl_kind , & ! scales absorbed radiation for dEdd + F_abs_chl_sp = 4.0_dbl_kind , & ! + F_abs_chl_phaeo = 5.0_dbl_kind !======================================================================= contains @@ -455,7 +557,7 @@ subroutine icepack_init_parameters( & zref_in, hs_min_in, snowpatch_in, rhosi_in, sk_l_in, & saltmax_in, phi_init_in, min_salin_in, salt_loss_in, & Tliquidus_max_in, & - min_bgc_in, dSin0_frazil_in, hi_ssl_in, hs_ssl_in, & + min_bgc_in, dSin0_frazil_in, hi_ssl_in, hs_ssl_in, hs_ssl_min_in, & awtvdr_in, awtidr_in, awtvdf_in, awtidf_in, & qqqice_in, TTTice_in, qqqocn_in, TTTocn_in, & ktherm_in, conduct_in, fbot_xfer_type_in, calc_Tsfc_in, dts_b_in, & @@ -466,7 +568,7 @@ subroutine icepack_init_parameters( & phi_i_mushy_in, shortwave_in, albedo_type_in, albsnowi_in, & albicev_in, albicei_in, albsnowv_in, & ahmax_in, R_ice_in, R_pnd_in, R_snw_in, dT_mlt_in, rsnw_mlt_in, & - kalg_in, kstrength_in, krdg_partic_in, krdg_redist_in, mu_rdg_in, & + kalg_in, R_gC2molC_in, kstrength_in, krdg_partic_in, krdg_redist_in, mu_rdg_in, & atmbndy_in, calc_strair_in, formdrag_in, highfreq_in, natmiter_in, & atmiter_conv_in, calc_dragio_in, & tfrz_option_in, kitd_in, kcatbound_in, hs0_in, frzpnd_in, & @@ -474,9 +576,10 @@ subroutine icepack_init_parameters( & floeshape_in, wave_spec_in, wave_spec_type_in, nfreq_in, & dpscale_in, rfracmin_in, rfracmax_in, pndaspect_in, hs1_in, hp1_in, & 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, & + modal_aero_in, use_macromolecules_in, restartbgc_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, & - phi_snow_in, T_max_in, fsal_in, & + phi_snow_in, T_max_in, fsal_in, use_atm_dust_iron_in, & 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, & @@ -488,7 +591,38 @@ subroutine icepack_init_parameters( & 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, snw_ssp_table_in ) + snw_aging_table_in, snw_ssp_table_in, grid_o_t_in, tau_min_in, tau_max_in, & + f_don_protein_in, kn_bac_protein_in, f_don_Am_protein_in, & + ratio_Si2N_diatoms_in, & + ratio_Si2N_sp_in, ratio_Si2N_phaeo_in, ratio_S2N_diatoms_in, & + ratio_S2N_sp_in, ratio_S2N_phaeo_in, ratio_Fe2C_diatoms_in, & + ratio_Fe2C_sp_in, ratio_Fe2C_phaeo_in, ratio_Fe2N_diatoms_in, & + ratio_Fe2N_sp_in, ratio_Fe2N_phaeo_in, ratio_Fe2DON_in, & + ratio_Fe2DOC_s_in, ratio_Fe2DOC_l_in, & + chlabs_diatoms_in, chlabs_sp_in, chlabs_phaeo_in, alpha2max_low_diatoms_in, & + alpha2max_low_sp_in, alpha2max_low_phaeo_in, beta2max_diatoms_in, & + beta2max_sp_in, beta2max_phaeo_in, mu_max_diatoms_in, mu_max_sp_in, & + mu_max_phaeo_in, grow_Tdep_diatoms_in, grow_Tdep_sp_in, & + grow_Tdep_phaeo_in, fr_graze_diatoms_in, fr_graze_sp_in, & + fr_graze_phaeo_in, mort_pre_diatoms_in, mort_pre_sp_in, & + mort_pre_phaeo_in, mort_Tdep_diatoms_in, mort_Tdep_sp_in, & + mort_Tdep_phaeo_in, k_exude_diatoms_in, k_exude_sp_in, k_exude_phaeo_in, & + K_Nit_diatoms_in, K_Nit_sp_in, K_Nit_phaeo_in, & + K_Am_diatoms_in, K_Am_sp_in, K_Am_phaeo_in, & + K_Sil_diatoms_in, K_Sil_sp_in, K_Sil_phaeo_in, & + K_Fe_diatoms_in, K_Fe_sp_in, K_Fe_phaeo_in, & + f_doc_s_in, f_doc_l_in, f_exude_s_in, f_exude_l_in, & + k_bac_s_in, k_bac_l_in, algaltype_diatoms_in, & + algaltype_sp_in, algaltype_phaeo_in, nitratetype_in, & + ammoniumtype_in, silicatetype_in, dmspptype_in, & + dmspdtype_in, humtype_in, doctype_s_in, doctype_l_in, & + dictype_1_in, dontype_protein_in, fedtype_1_in, feptype_1_in, & + zaerotype_bc1_in, zaerotype_bc2_in, zaerotype_dust1_in, & + zaerotype_dust2_in, zaerotype_dust3_in, zaerotype_dust4_in, & + ratio_C2N_diatoms_in, ratio_C2N_sp_in, ratio_C2N_phaeo_in, & + ratio_chl2N_diatoms_in, ratio_chl2N_sp_in, ratio_chl2N_phaeo_in, & + F_abs_chl_diatoms_in, F_abs_chl_sp_in, F_abs_chl_phaeo_in, & + ratio_C2N_proteins_in ) !----------------------------------------------------------------- ! control settings @@ -606,7 +740,8 @@ subroutine icepack_init_parameters( & stefan_boltzmann_in, & ! W/m^2/K^4 kappav_in, & ! vis extnctn coef in ice, wvlngth<700nm (1/m) hi_ssl_in, & ! ice surface scattering layer thickness (m) - hs_ssl_in, & ! visible, direct + hs_ssl_in, & ! snow surface scattering layer thickness (m) + hs_ssl_min_in, & ! minimum snow surface scattering layer thickness for aerosols (m) awtvdr_in, & ! visible, direct ! for history and awtidr_in, & ! near IR, direct ! diagnostics awtvdf_in, & ! visible, diffuse @@ -633,7 +768,8 @@ subroutine icepack_init_parameters( & dT_mlt_in , & ! change in temp for non-melt to melt snow grain ! radius change (C) rsnw_mlt_in , & ! maximum melting snow grain radius (10^-6 m) - kalg_in ! algae absorption coefficient for 0.5 m thick layer + kalg_in , & ! algae absorption coefficient for 0.5 m thick layer + R_gC2molC_in ! g carbon per mol logical (kind=log_kind), intent(in), optional :: & sw_redist_in ! redistribute shortwave @@ -742,6 +878,10 @@ subroutine icepack_init_parameters( & solve_zbgc_in, & ! if .true., solve vertical biochemistry portion of code dEdd_algae_in, & ! if .true., algal absorptionof Shortwave is computed in the modal_aero_in, & ! if .true., use modal aerosol formulation in shortwave + use_macromolecules_in, & ! if .true., ocean DOC is already split into + ! polysaccharid, lipid and protein fractions + use_atm_dust_iron_in, & ! if .true., compute iron contribution from dust + restartbgc_in, & conserv_check_in ! if .true., run conservation checks and abort if checks fail logical (kind=log_kind), intent(in), optional :: & @@ -751,12 +891,112 @@ subroutine icepack_init_parameters( & real (kind=dbl_kind), intent(in), optional :: & grid_o_in , & ! for bottom flux l_sk_in , & ! characteristic diffusive scale (zsalinity) (m) + grid_o_t_in , & ! top grid point length scale initbio_frac_in, & ! fraction of ocean tracer concentration used to initialize tracer phi_snow_in ! snow porosity at the ice/snow interface real (kind=dbl_kind), intent(in), optional :: & grid_oS_in , & ! for bottom flux (zsalinity) l_skS_in ! 0.02 characteristic skeletal layer thickness (m) (zsalinity) + + real (kind=dbl_kind), intent(in), optional :: & + ratio_Si2N_diatoms_in, & ! algal Si to N (mol/mol) + ratio_Si2N_sp_in , & + ratio_Si2N_phaeo_in , & + ratio_S2N_diatoms_in , & ! algal S to N (mol/mol) + ratio_S2N_sp_in , & + ratio_S2N_phaeo_in , & + ratio_Fe2C_diatoms_in, & ! algal Fe to C (umol/mol) + ratio_Fe2C_sp_in , & + ratio_Fe2C_phaeo_in , & + ratio_Fe2N_diatoms_in, & ! algal Fe to N (umol/mol) + ratio_Fe2N_sp_in , & + ratio_Fe2N_phaeo_in , & + ratio_Fe2DON_in , & ! Fe to N of DON (nmol/umol) + ratio_Fe2DOC_s_in , & ! Fe to C of DOC (nmol/umol) saccharids + ratio_Fe2DOC_l_in , & ! Fe to C of DOC (nmol/umol) lipids + tau_min_in , & ! rapid mobile to stationary exchanges (s) = 1.5 hours + tau_max_in , & ! long time mobile to stationary exchanges (s) = 2 days + chlabs_diatoms_in , & ! chl absorption (1/m/(mg/m^3)) + chlabs_sp_in , & ! + chlabs_phaeo_in , & ! + alpha2max_low_diatoms_in , & ! light limitation (1/(W/m^2)) + alpha2max_low_sp_in , & + alpha2max_low_phaeo_in , & + beta2max_diatoms_in , & ! light inhibition (1/(W/m^2)) + beta2max_sp_in , & + beta2max_phaeo_in , & + mu_max_diatoms_in , & ! maximum growth rate (1/day) + mu_max_sp_in , & + mu_max_phaeo_in , & + grow_Tdep_diatoms_in, & ! Temperature dependence of growth (1/C) + grow_Tdep_sp_in , & + grow_Tdep_phaeo_in , & + fr_graze_diatoms_in , & ! Fraction grazed + fr_graze_sp_in , & + fr_graze_phaeo_in , & + mort_pre_diatoms_in , & ! Mortality (1/day) + mort_pre_sp_in , & + mort_pre_phaeo_in , & + mort_Tdep_diatoms_in, & ! T dependence of mortality (1/C) + mort_Tdep_sp_in , & + mort_Tdep_phaeo_in , & + k_exude_diatoms_in , & ! algal exudation (1/d) + k_exude_sp_in , & + k_exude_phaeo_in , & + K_Nit_diatoms_in , & ! nitrate half saturation (mmol/m^3) + K_Nit_sp_in , & + K_Nit_phaeo_in , & + K_Am_diatoms_in , & ! ammonium half saturation (mmol/m^3) + K_Am_sp_in , & + K_Am_phaeo_in , & + K_Sil_diatoms_in , & ! silicate half saturation (mmol/m^3) + K_Sil_sp_in , & + K_Sil_phaeo_in , & + K_Fe_diatoms_in , & ! iron half saturation (nM) + K_Fe_sp_in , & + K_Fe_phaeo_in , & + f_don_protein_in , & ! fraction of spilled grazing to proteins + kn_bac_protein_in , & ! Bacterial degredation of DON (1/d) + f_don_Am_protein_in , & ! fraction of remineralized DON to ammonium + f_doc_s_in , & ! fraction of mortality to DOC + f_doc_l_in , & + f_exude_s_in , & ! fraction of exudation to DOC + f_exude_l_in , & + k_bac_s_in , & ! Bacterial degredation of DOC (1/d) + k_bac_l_in , & + algaltype_diatoms_in , & ! mobility type + algaltype_sp_in , & ! + algaltype_phaeo_in , & ! + nitratetype_in , & ! + ammoniumtype_in , & ! + silicatetype_in , & ! + dmspptype_in , & ! + dmspdtype_in , & ! + humtype_in , & ! + doctype_s_in , & ! + doctype_l_in , & ! + dictype_1_in , & ! + dontype_protein_in , & ! + fedtype_1_in , & ! + feptype_1_in , & ! + zaerotype_bc1_in , & ! + zaerotype_bc2_in , & ! + zaerotype_dust1_in , & ! + zaerotype_dust2_in , & ! + zaerotype_dust3_in , & ! + zaerotype_dust4_in , & ! + ratio_C2N_diatoms_in , & ! algal C to N ratio (mol/mol) + ratio_C2N_sp_in , & ! + ratio_C2N_phaeo_in , & ! + ratio_chl2N_diatoms_in, & ! algal chlorophyll to N ratio (mg/mmol) + ratio_chl2N_sp_in , & ! + ratio_chl2N_phaeo_in , & ! + F_abs_chl_diatoms_in , & ! scales absorbed radiation for dEdd + F_abs_chl_sp_in , & ! + F_abs_chl_phaeo_in , & ! + ratio_C2N_proteins_in ! ratio of C to N in proteins (mol/mol) + real (kind=dbl_kind), intent(in), optional :: & fr_resp_in , & ! fraction of algal growth lost due to respiration algal_vel_in , & ! 0.5 cm/d(m/s) Lavoie 2005 1.5 cm/day @@ -912,6 +1152,7 @@ subroutine icepack_init_parameters( & if (present(dSin0_frazil_in) ) dSin0_frazil = dSin0_frazil_in if (present(hi_ssl_in) ) hi_ssl = hi_ssl_in if (present(hs_ssl_in) ) hs_ssl = hs_ssl_in + if (present(hs_ssl_min_in) ) hs_ssl_min = hs_ssl_min_in if (present(awtvdr_in) ) awtvdr = awtvdr_in if (present(awtidr_in) ) awtidr = awtidr_in if (present(awtvdf_in) ) awtvdf = awtvdf_in @@ -949,6 +1190,7 @@ subroutine icepack_init_parameters( & if (present(dT_mlt_in) ) dT_mlt = dT_mlt_in if (present(rsnw_mlt_in) ) rsnw_mlt = rsnw_mlt_in if (present(kalg_in) ) kalg = kalg_in + if (present(R_gC2molC_in) ) R_gC2molC = R_gC2molC_in if (present(kstrength_in) ) kstrength = kstrength_in if (present(krdg_partic_in) ) krdg_partic = krdg_partic_in if (present(krdg_redist_in) ) krdg_redist = krdg_redist_in @@ -1115,6 +1357,9 @@ subroutine icepack_init_parameters( & if (present(solve_zbgc_in) ) solve_zbgc = solve_zbgc_in if (present(dEdd_algae_in) ) dEdd_algae = dEdd_algae_in if (present(modal_aero_in) ) modal_aero = modal_aero_in + if (present(use_macromolecules_in)) use_macromolecules = use_macromolecules_in + if (present(use_atm_dust_iron_in) ) use_atm_dust_iron = use_atm_dust_iron_in + if (present(restartbgc_in) ) restartbgc = restartbgc_in if (present(conserv_check_in) ) conserv_check = conserv_check_in if (present(skl_bgc_in) ) skl_bgc = skl_bgc_in if (present(solve_zsal_in)) then @@ -1125,10 +1370,145 @@ subroutine icepack_init_parameters( & endif if (present(grid_o_in) ) grid_o = grid_o_in if (present(l_sk_in) ) l_sk = l_sk_in + if (present(grid_o_t_in) ) grid_o_t = grid_o_t_in + if (present(frazil_scav_in) ) frazil_scav = frazil_scav_in if (present(initbio_frac_in) ) initbio_frac = initbio_frac_in if (present(grid_oS_in) ) grid_oS = grid_oS_in if (present(l_skS_in) ) l_skS = l_skS_in if (present(phi_snow_in) ) phi_snow = phi_snow_in + + if (present(ratio_Si2N_diatoms_in) ) ratio_Si2N_diatoms = ratio_Si2N_diatoms_in + if (present(ratio_Si2N_sp_in) ) ratio_Si2N_sp = ratio_Si2N_sp_in + if (present(ratio_Si2N_phaeo_in) ) ratio_Si2N_phaeo = ratio_Si2N_phaeo_in + if (present(ratio_S2N_diatoms_in) ) ratio_S2N_diatoms = ratio_S2N_diatoms_in + if (present(ratio_S2N_sp_in ) ) ratio_S2N_sp = ratio_S2N_sp_in + if (present(ratio_S2N_phaeo_in) ) ratio_S2N_phaeo = ratio_S2N_phaeo_in + if (present(ratio_Fe2C_diatoms_in) ) ratio_Fe2C_diatoms = ratio_Fe2C_diatoms_in + if (present(ratio_Fe2C_sp_in) ) ratio_Fe2C_sp = ratio_Fe2C_sp_in + if (present(ratio_Fe2C_phaeo_in) ) ratio_Fe2C_phaeo = ratio_Fe2C_phaeo_in + if (present(ratio_Fe2N_diatoms_in) ) ratio_Fe2N_diatoms = ratio_Fe2N_diatoms_in + if ((solve_zbgc .or. skl_bgc) .and. (ratio_Fe2N_diatoms .LE. c0)) then + call icepack_warnings_add(subname//' WARNING: ratio_Fe2N_diatoms < = 0') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + endif + if (present(ratio_Fe2N_sp_in) ) ratio_Fe2N_sp = ratio_Fe2N_sp_in + if ((solve_zbgc .or. skl_bgc) .and. (ratio_Fe2N_sp .LE. c0)) then + call icepack_warnings_add(subname//' WARNING: ratio_Fe2N_sp < = 0') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + endif + if (present(ratio_Fe2N_phaeo_in) ) ratio_Fe2N_phaeo = ratio_Fe2N_phaeo_in + if ((solve_zbgc .or. skl_bgc) .and. (ratio_Fe2N_phaeo .LE. c0)) then + call icepack_warnings_add(subname//' WARNING: ratio_Fe2N_phaeo < = 0') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + endif + if (present(ratio_Fe2DON_in) ) ratio_Fe2DON = ratio_Fe2DON_in + if (present(ratio_Fe2DOC_s_in) ) ratio_Fe2DOC_s = ratio_Fe2DOC_s_in + if (present(ratio_Fe2DOC_l_in) ) ratio_Fe2DOC_l = ratio_Fe2DOC_l_in + if (present(tau_min_in) ) tau_min = tau_min_in + if (present(tau_max_in) ) tau_max = tau_max_in + if (present(chlabs_diatoms_in) ) chlabs_diatoms = chlabs_diatoms_in + if (present(chlabs_sp_in) ) chlabs_sp = chlabs_sp_in + if (present(chlabs_phaeo_in) ) chlabs_phaeo = chlabs_phaeo_in + if (present(alpha2max_low_diatoms_in) ) alpha2max_low_diatoms = alpha2max_low_diatoms_in + if (present(alpha2max_low_sp_in) ) alpha2max_low_sp = alpha2max_low_sp_in + if (present(alpha2max_low_phaeo_in) ) alpha2max_low_phaeo = alpha2max_low_phaeo_in + if (present(beta2max_diatoms_in) ) beta2max_diatoms = beta2max_diatoms_in + if (present(beta2max_sp_in) ) beta2max_sp = beta2max_sp_in + if (present(beta2max_phaeo_in) ) beta2max_phaeo = beta2max_phaeo_in + if (present(mu_max_diatoms_in) ) mu_max_diatoms = mu_max_diatoms_in + if (present(mu_max_sp_in) ) mu_max_sp = mu_max_sp_in + if (present(mu_max_phaeo_in) ) mu_max_phaeo = mu_max_phaeo_in + if (present(grow_Tdep_diatoms_in) ) grow_Tdep_diatoms = grow_Tdep_diatoms_in + if (present(grow_Tdep_sp_in) ) grow_Tdep_sp = grow_Tdep_sp_in + if (present(grow_Tdep_phaeo_in) ) grow_Tdep_phaeo = grow_Tdep_phaeo_in + if (present(fr_graze_diatoms_in) ) fr_graze_diatoms = fr_graze_diatoms_in + if (present(fr_graze_sp_in) ) fr_graze_sp = fr_graze_sp_in + if (present(fr_graze_phaeo_in) ) fr_graze_phaeo = fr_graze_phaeo_in + if (present(mort_pre_diatoms_in) ) mort_pre_diatoms = mort_pre_diatoms_in + if (present(mort_pre_sp_in) ) mort_pre_sp = mort_pre_sp_in + if (present(mort_pre_phaeo_in) ) mort_pre_phaeo = mort_pre_phaeo_in + if (present(mort_Tdep_diatoms_in) ) mort_Tdep_diatoms = mort_Tdep_diatoms_in + if (present(mort_Tdep_sp_in) ) mort_Tdep_sp = mort_Tdep_sp_in + if (present(mort_Tdep_phaeo_in) ) mort_Tdep_phaeo = mort_Tdep_phaeo_in + if (present(k_exude_diatoms_in) ) k_exude_diatoms = k_exude_diatoms_in + if (present(k_exude_sp_in) ) k_exude_sp = k_exude_sp_in + if (present(k_exude_phaeo_in) ) k_exude_phaeo = k_exude_phaeo_in + if (present(K_Nit_diatoms_in) ) K_Nit_diatoms = K_Nit_diatoms_in + if ((solve_zbgc .or. skl_bgc) .and. (K_Nit_diatoms .LE. c0)) then + call icepack_warnings_add(subname//' WARNING: K_Nit_diatoms < = 0') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + endif + if (present(K_Nit_sp_in) ) K_Nit_sp = K_Nit_sp_in + if ((solve_zbgc .or. skl_bgc) .and. (K_Nit_sp .LE. c0)) then + call icepack_warnings_add(subname//' WARNING: K_Nit_sp < = 0') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + endif + if (present(K_Nit_phaeo_in) ) K_Nit_phaeo = K_Nit_phaeo_in + if ((solve_zbgc .or. skl_bgc) .and. (K_Nit_phaeo .LE. c0)) then + call icepack_warnings_add(subname//' WARNING: K_Nit_phaeo < = 0') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + endif + if (present(K_Am_diatoms_in) ) K_Am_diatoms = K_Am_diatoms_in + if ((solve_zbgc .or. skl_bgc) .and. (K_Am_diatoms .LE. c0)) then + call icepack_warnings_add(subname//' WARNING: K_Am_diatoms < = 0') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + endif + if (present(K_Am_sp_in) ) K_Am_sp = K_Am_sp_in + if ((solve_zbgc .or. skl_bgc) .and. (K_Am_sp .LE. c0)) then + call icepack_warnings_add(subname//' WARNING: K_Am_sp < = 0') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + endif + if (present(K_Am_phaeo_in) ) K_Am_phaeo = K_Am_phaeo_in + if ((solve_zbgc .or. skl_bgc) .and. (K_Am_phaeo .LE. c0)) then + call icepack_warnings_add(subname//' WARNING: K_Am_phaeo < = 0') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + endif + if (present(K_Sil_diatoms_in) ) K_Sil_diatoms = K_Sil_diatoms_in + if (present(K_Sil_sp_in) ) K_Sil_sp = K_Sil_sp_in + if (present(K_Sil_phaeo_in) ) K_Sil_phaeo = K_Sil_phaeo_in + if (present(K_Fe_diatoms_in) ) K_Fe_diatoms = K_Fe_diatoms_in + if (present(K_Fe_sp_in) ) K_Fe_sp = K_Fe_sp_in + if (present(K_Fe_phaeo_in) ) K_Fe_phaeo = K_Fe_phaeo_in + if (present(f_don_protein_in) ) f_don_protein = f_don_protein_in + if (present(kn_bac_protein_in) ) kn_bac_protein = kn_bac_protein_in + if (present(f_don_Am_protein_in) ) f_don_Am_protein = f_don_Am_protein_in + if (present(f_doc_s_in) ) f_doc_s = f_doc_s_in + if (present(f_doc_l_in) ) f_doc_l = f_doc_l_in + if (present(f_exude_s_in) ) f_exude_s = f_exude_s_in + if (present(f_exude_l_in) ) f_exude_l = f_exude_l_in + if (present(k_bac_s_in) ) k_bac_s = k_bac_s_in + if (present(k_bac_l_in) ) k_bac_l = k_bac_l_in + if (present(algaltype_diatoms_in) ) algaltype_diatoms = algaltype_diatoms_in + if (present(algaltype_sp_in) ) algaltype_sp = algaltype_sp_in + if (present(algaltype_phaeo_in) ) algaltype_phaeo = algaltype_phaeo_in + if (present(nitratetype_in) ) nitratetype = nitratetype_in + if (present(ammoniumtype_in) ) ammoniumtype = ammoniumtype_in + if (present(silicatetype_in) ) silicatetype = silicatetype_in + if (present(dmspptype_in) ) dmspptype = dmspptype_in + if (present(dmspdtype_in) ) dmspdtype = dmspdtype_in + if (present(humtype_in) ) humtype = humtype_in + if (present(doctype_s_in) ) doctype_s = doctype_s_in + if (present(doctype_l_in) ) doctype_l = doctype_l_in + if (present(dictype_1_in) ) dictype_1 = dictype_1_in + if (present(dontype_protein_in) ) dontype_protein = dontype_protein_in + if (present(fedtype_1_in) ) fedtype_1 = fedtype_1_in + if (present(feptype_1_in) ) feptype_1 = feptype_1_in + if (present(zaerotype_bc1_in) ) zaerotype_bc1 = zaerotype_bc1_in + if (present(zaerotype_bc2_in) ) zaerotype_bc2 = zaerotype_bc2_in + if (present(zaerotype_dust1_in) ) zaerotype_dust1 = zaerotype_dust1_in + if (present(zaerotype_dust2_in) ) zaerotype_dust2 = zaerotype_dust2_in + if (present(zaerotype_dust3_in) ) zaerotype_dust3 = zaerotype_dust3_in + if (present(zaerotype_dust4_in) ) zaerotype_dust4 = zaerotype_dust4_in + if (present(ratio_C2N_diatoms_in) ) ratio_C2N_diatoms = ratio_C2N_diatoms_in + if (present(ratio_C2N_sp_in) ) ratio_C2N_sp = ratio_C2N_sp_in + if (present(ratio_C2N_phaeo_in) ) ratio_C2N_phaeo = ratio_C2N_phaeo_in + if (present(ratio_chl2N_diatoms_in)) ratio_chl2N_diatoms = ratio_chl2N_diatoms_in + if (present(ratio_chl2N_sp_in) ) ratio_chl2N_sp = ratio_chl2N_sp_in + if (present(ratio_chl2N_phaeo_in) ) ratio_chl2N_phaeo = ratio_chl2N_phaeo_in + if (present(F_abs_chl_diatoms_in) ) F_abs_chl_diatoms = F_abs_chl_diatoms_in + if (present(F_abs_chl_sp_in) ) F_abs_chl_sp = F_abs_chl_sp_in + if (present(F_abs_chl_phaeo_in) ) F_abs_chl_phaeo = F_abs_chl_phaeo_in + if (present(ratio_C2N_proteins_in) ) ratio_C2N_proteins = ratio_C2N_proteins_in if (present(fr_resp_in) ) fr_resp = fr_resp_in if (present(algal_vel_in) ) algal_vel = algal_vel_in if (present(R_dFe2dust_in) ) R_dFe2dust = R_dFe2dust_in @@ -1148,7 +1528,6 @@ subroutine icepack_init_parameters( & if (present(y_sk_DMS_in) ) y_sk_DMS = y_sk_DMS_in if (present(t_sk_conv_in) ) t_sk_conv = t_sk_conv_in if (present(t_sk_ox_in) ) t_sk_ox = t_sk_ox_in - if (present(frazil_scav_in) ) frazil_scav = frazil_scav_in if (present(sw_redist_in) ) sw_redist = sw_redist_in if (present(sw_frac_in) ) sw_frac = sw_frac_in if (present(sw_dtemp_in) ) sw_dtemp = sw_dtemp_in @@ -1189,7 +1568,7 @@ subroutine icepack_query_parameters( & zref_out, hs_min_out, snowpatch_out, rhosi_out, sk_l_out, & saltmax_out, phi_init_out, min_salin_out, salt_loss_out, & Tliquidus_max_out, & - min_bgc_out, dSin0_frazil_out, hi_ssl_out, hs_ssl_out, & + min_bgc_out, dSin0_frazil_out, hi_ssl_out, hs_ssl_out, hs_ssl_min_out, & awtvdr_out, awtidr_out, awtvdf_out, awtidf_out, cpl_frazil_out, & qqqice_out, TTTice_out, qqqocn_out, TTTocn_out, update_ocn_f_out, & Lfresh_out, cprho_out, Cp_out, ustar_min_out, hi_min_out, a_rapid_mode_out, & @@ -1199,7 +1578,7 @@ subroutine icepack_query_parameters( & albedo_type_out, albicev_out, albicei_out, albsnowv_out, & albsnowi_out, ahmax_out, R_ice_out, R_pnd_out, R_snw_out, dT_mlt_out, & rsnw_mlt_out, dEdd_algae_out, & - kalg_out, kstrength_out, krdg_partic_out, krdg_redist_out, mu_rdg_out, & + kalg_out, R_gC2molC_out, kstrength_out, krdg_partic_out, krdg_redist_out, mu_rdg_out, & atmbndy_out, calc_strair_out, formdrag_out, highfreq_out, natmiter_out, & atmiter_conv_out, calc_dragio_out, & tfrz_option_out, kitd_out, kcatbound_out, hs0_out, frzpnd_out, & @@ -1207,7 +1586,8 @@ subroutine icepack_query_parameters( & floeshape_out, wave_spec_out, wave_spec_type_out, nfreq_out, & dpscale_out, rfracmin_out, rfracmax_out, pndaspect_out, hs1_out, hp1_out, & 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, & + modal_aero_out, use_macromolecules_out, restartbgc_out, use_atm_dust_iron_out, & + skl_bgc_out, solve_zsal_out, grid_o_out, l_sk_out, & initbio_frac_out, grid_oS_out, l_skS_out, & phi_snow_out, conserv_check_out, & fr_resp_out, algal_vel_out, R_dFe2dust_out, dustFe_sol_out, & @@ -1221,7 +1601,37 @@ subroutine icepack_query_parameters( & 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, snw_ssp_table_out ) + snw_aging_table_out, snw_ssp_table_out, ratio_Si2N_diatoms_out, & + ratio_Si2N_sp_out, ratio_Si2N_phaeo_out, ratio_S2N_diatoms_out, & + ratio_S2N_sp_out, ratio_S2N_phaeo_out, ratio_Fe2C_diatoms_out, & + ratio_Fe2C_sp_out, ratio_Fe2C_phaeo_out, ratio_Fe2N_diatoms_out, & + ratio_Fe2N_sp_out, ratio_Fe2N_phaeo_out, ratio_Fe2DON_out, & + ratio_Fe2DOC_s_out, ratio_Fe2DOC_l_out, grid_o_t_out, tau_min_out, tau_max_out, & + chlabs_diatoms_out, chlabs_sp_out, chlabs_phaeo_out, alpha2max_low_diatoms_out, & + alpha2max_low_sp_out, alpha2max_low_phaeo_out, beta2max_diatoms_out, & + beta2max_sp_out, beta2max_phaeo_out, mu_max_diatoms_out, mu_max_sp_out, & + mu_max_phaeo_out, grow_Tdep_diatoms_out, grow_Tdep_sp_out, & + grow_Tdep_phaeo_out, fr_graze_diatoms_out, fr_graze_sp_out, & + fr_graze_phaeo_out, mort_pre_diatoms_out, mort_pre_sp_out, & + mort_pre_phaeo_out, mort_Tdep_diatoms_out, mort_Tdep_sp_out, & + mort_Tdep_phaeo_out, k_exude_diatoms_out, k_exude_sp_out, k_exude_phaeo_out, & + K_Nit_diatoms_out, K_Nit_sp_out, K_Nit_phaeo_out, & + K_Am_diatoms_out, K_Am_sp_out, K_Am_phaeo_out, & + K_Sil_diatoms_out, K_Sil_sp_out, K_Sil_phaeo_out, & + K_Fe_diatoms_out, K_Fe_sp_out, K_Fe_phaeo_out, & + f_don_protein_out, kn_bac_protein_out, f_don_Am_protein_out, & + f_doc_s_out, f_doc_l_out, f_exude_s_out, f_exude_l_out, & + k_bac_s_out, k_bac_l_out, algaltype_diatoms_out, & + algaltype_sp_out, algaltype_phaeo_out, nitratetype_out, & + ammoniumtype_out, silicatetype_out, dmspptype_out, & + dmspdtype_out, humtype_out, doctype_s_out, doctype_l_out, & + dictype_1_out, dontype_protein_out, fedtype_1_out, feptype_1_out, & + zaerotype_bc1_out, zaerotype_bc2_out, zaerotype_dust1_out, & + zaerotype_dust2_out, zaerotype_dust3_out, zaerotype_dust4_out, & + ratio_C2N_diatoms_out, ratio_C2N_sp_out, ratio_C2N_phaeo_out, & + ratio_chl2N_diatoms_out, ratio_chl2N_sp_out, ratio_chl2N_phaeo_out, & + F_abs_chl_diatoms_out, F_abs_chl_sp_out, F_abs_chl_phaeo_out, & + ratio_C2N_proteins_out ) !----------------------------------------------------------------- ! control settings @@ -1350,7 +1760,8 @@ subroutine icepack_query_parameters( & stefan_boltzmann_out, & ! W/m^2/K^4 kappav_out, & ! vis extnctn coef in ice, wvlngth<700nm (1/m) hi_ssl_out, & ! ice surface scattering layer thickness (m) - hs_ssl_out, & ! visible, direct + hs_ssl_out, & ! snow surface scattering layer thickness (m) + hs_ssl_min_out, & ! minimum snow surface scattering layer thickness for aerosols (m) awtvdr_out, & ! visible, direct ! for history and awtidr_out, & ! near IR, direct ! diagnostics awtvdf_out, & ! visible, diffuse @@ -1377,7 +1788,8 @@ subroutine icepack_query_parameters( & dT_mlt_out , & ! change in temp for non-melt to melt snow grain ! radius change (C) rsnw_mlt_out , & ! maximum melting snow grain radius (10^-6 m) - kalg_out ! algae absorption coefficient for 0.5 m thick layer + kalg_out , & ! algae absorption coefficient for 0.5 m thick layer + R_gC2molC_out ! grams carbon per mol logical (kind=log_kind), intent(out), optional :: & sw_redist_out ! redistribute shortwave @@ -1486,6 +1898,10 @@ subroutine icepack_query_parameters( & solve_zbgc_out, & ! if .true., solve vertical biochemistry portion of code dEdd_algae_out, & ! if .true., algal absorptionof Shortwave is computed in the modal_aero_out, & ! if .true., use modal aerosol formulation in shortwave + use_macromolecules_out, & ! if .true., ocean DOC is already split + ! into polysaccharid, lipid and protein fractions + use_atm_dust_iron_out, & ! if .true., compute iron contribution from dust + restartbgc_out, & conserv_check_out ! if .true., run conservation checks and abort if checks fail logical (kind=log_kind), intent(out), optional :: & @@ -1495,12 +1911,112 @@ subroutine icepack_query_parameters( & real (kind=dbl_kind), intent(out), optional :: & grid_o_out , & ! for bottom flux l_sk_out , & ! characteristic diffusive scale (zsalinity) (m) + grid_o_t_out , & ! top grid point length scale initbio_frac_out, & ! fraction of ocean tracer concentration used to initialize tracer phi_snow_out ! snow porosity at the ice/snow interface real (kind=dbl_kind), intent(out), optional :: & grid_oS_out , & ! for bottom flux (zsalinity) l_skS_out ! 0.02 characteristic skeletal layer thickness (m) (zsalinity) + + real (kind=dbl_kind), intent(out), optional :: & + ratio_Si2N_diatoms_out, & ! algal Si to N (mol/mol) + ratio_Si2N_sp_out , & + ratio_Si2N_phaeo_out , & + ratio_S2N_diatoms_out , & ! algal S to N (mol/mol) + ratio_S2N_sp_out , & + ratio_S2N_phaeo_out , & + ratio_Fe2C_diatoms_out, & ! algal Fe to C (umol/mol) + ratio_Fe2C_sp_out , & + ratio_Fe2C_phaeo_out , & + ratio_Fe2N_diatoms_out, & ! algal Fe to N (umol/mol) + ratio_Fe2N_sp_out , & + ratio_Fe2N_phaeo_out , & + ratio_Fe2DON_out , & ! Fe to N of DON (nmol/umol) + ratio_Fe2DOC_s_out , & ! Fe to C of DOC (nmol/umol) saccharids + ratio_Fe2DOC_l_out , & ! Fe to C of DOC (nmol/umol) lipids + tau_min_out , & ! rapid mobile to stationary exchanges (s) = 1.5 hours + tau_max_out , & ! long time mobile to stationary exchanges (s) = 2 days + chlabs_diatoms_out , & ! chl absorption (1/m/(mg/m^3)) + chlabs_sp_out , & ! + chlabs_phaeo_out , & ! + alpha2max_low_diatoms_out , & ! light limitation (1/(W/m^2)) + alpha2max_low_sp_out , & + alpha2max_low_phaeo_out , & + beta2max_diatoms_out , & ! light inhibition (1/(W/m^2)) + beta2max_sp_out , & + beta2max_phaeo_out , & + mu_max_diatoms_out , & ! maximum growth rate (1/day) + mu_max_sp_out , & + mu_max_phaeo_out , & + grow_Tdep_diatoms_out, & ! Temperature dependence of growth (1/C) + grow_Tdep_sp_out , & + grow_Tdep_phaeo_out , & + fr_graze_diatoms_out , & ! Fraction grazed + fr_graze_sp_out , & + fr_graze_phaeo_out , & + mort_pre_diatoms_out , & ! Mortality (1/day) + mort_pre_sp_out , & + mort_pre_phaeo_out , & + mort_Tdep_diatoms_out, & ! T dependence of mortality (1/C) + mort_Tdep_sp_out , & + mort_Tdep_phaeo_out , & + k_exude_diatoms_out , & ! algal exudation (1/d) + k_exude_sp_out , & + k_exude_phaeo_out , & + K_Nit_diatoms_out , & ! nitrate half saturation (mmol/m^3) + K_Nit_sp_out , & + K_Nit_phaeo_out , & + K_Am_diatoms_out , & ! ammonium half saturation (mmol/m^3) + K_Am_sp_out , & + K_Am_phaeo_out , & + K_Sil_diatoms_out , & ! silicate half saturation (mmol/m^3) + K_Sil_sp_out , & + K_Sil_phaeo_out , & + K_Fe_diatoms_out , & ! iron half saturation (nM) + K_Fe_sp_out , & + K_Fe_phaeo_out , & + f_don_protein_out , & ! fraction of spilled grazing to proteins + kn_bac_protein_out , & ! Bacterial degredation of DON (1/d) + f_don_Am_protein_out , & ! fraction of remineralized DON to ammonium + f_doc_s_out , & ! fraction of mortality to DOC + f_doc_l_out , & + f_exude_s_out , & ! fraction of exudation to DOC + f_exude_l_out , & + k_bac_s_out , & ! Bacterial degredation of DOC (1/d) + k_bac_l_out , & + algaltype_diatoms_out , & ! mobility type + algaltype_sp_out , & ! + algaltype_phaeo_out , & ! + nitratetype_out , & ! + ammoniumtype_out , & ! + silicatetype_out , & ! + dmspptype_out , & ! + dmspdtype_out , & ! + humtype_out , & ! + doctype_s_out , & ! + doctype_l_out , & ! + dictype_1_out , & ! + dontype_protein_out , & ! + fedtype_1_out , & ! + feptype_1_out , & ! + zaerotype_bc1_out , & ! + zaerotype_bc2_out , & ! + zaerotype_dust1_out , & ! + zaerotype_dust2_out , & ! + zaerotype_dust3_out , & ! + zaerotype_dust4_out , & ! + ratio_C2N_diatoms_out , & ! algal C to N ratio (mol/mol) + ratio_C2N_sp_out , & ! + ratio_C2N_phaeo_out , & ! + ratio_chl2N_diatoms_out, & ! algal chlorophyll to N ratio (mg/mmol) + ratio_chl2N_sp_out , & ! + ratio_chl2N_phaeo_out , & ! + F_abs_chl_diatoms_out , & ! scales absorbed radiation for dEdd + F_abs_chl_sp_out , & ! + F_abs_chl_phaeo_out , & ! + ratio_C2N_proteins_out ! ratio of C to N in proteins (mol/mol) + real (kind=dbl_kind), intent(out), optional :: & fr_resp_out , & ! fraction of algal growth lost due to respiration algal_vel_out , & ! 0.5 cm/d(m/s) Lavoie 2005 1.5 cm/day @@ -1688,6 +2204,7 @@ subroutine icepack_query_parameters( & if (present(dSin0_frazil_out) ) dSin0_frazil_out = dSin0_frazil if (present(hi_ssl_out) ) hi_ssl_out = hi_ssl if (present(hs_ssl_out) ) hs_ssl_out = hs_ssl + if (present(hs_ssl_min_out) ) hs_ssl_min_out = hs_ssl_min if (present(awtvdr_out) ) awtvdr_out = awtvdr if (present(awtidr_out) ) awtidr_out = awtidr if (present(awtvdf_out) ) awtvdf_out = awtvdf @@ -1725,6 +2242,7 @@ subroutine icepack_query_parameters( & if (present(dT_mlt_out) ) dT_mlt_out = dT_mlt if (present(rsnw_mlt_out) ) rsnw_mlt_out = rsnw_mlt if (present(kalg_out) ) kalg_out = kalg + if (present(R_gC2molC_out) ) R_gC2molC_out = R_gC2molC if (present(kstrength_out) ) kstrength_out = kstrength if (present(krdg_partic_out) ) krdg_partic_out = krdg_partic if (present(krdg_redist_out) ) krdg_redist_out = krdg_redist @@ -1780,15 +2298,116 @@ subroutine icepack_query_parameters( & if (present(solve_zbgc_out) ) solve_zbgc_out = solve_zbgc if (present(dEdd_algae_out) ) dEdd_algae_out = dEdd_algae if (present(modal_aero_out) ) modal_aero_out = modal_aero + if (present(use_macromolecules_out)) use_macromolecules_out = use_macromolecules + if (present(use_atm_dust_iron_out) ) use_atm_dust_iron_out = use_atm_dust_iron + if (present(restartbgc_out) ) restartbgc_out= restartbgc if (present(conserv_check_out) ) conserv_check_out= conserv_check if (present(skl_bgc_out) ) skl_bgc_out = skl_bgc if (present(solve_zsal_out) ) solve_zsal_out = solve_zsal if (present(grid_o_out) ) grid_o_out = grid_o if (present(l_sk_out) ) l_sk_out = l_sk if (present(initbio_frac_out) ) initbio_frac_out = initbio_frac + if (present(frazil_scav_out) ) frazil_scav_out = frazil_scav if (present(grid_oS_out) ) grid_oS_out = grid_oS if (present(l_skS_out) ) l_skS_out = l_skS + if (present(grid_o_t_out) ) grid_o_t_out = grid_o_t if (present(phi_snow_out) ) phi_snow_out = phi_snow + if (present(ratio_Si2N_diatoms_out) ) ratio_Si2N_diatoms_out = ratio_Si2N_diatoms + if (present(ratio_Si2N_sp_out) ) ratio_Si2N_sp_out = ratio_Si2N_sp + if (present(ratio_Si2N_phaeo_out) ) ratio_Si2N_phaeo_out = ratio_Si2N_phaeo + if (present(ratio_S2N_diatoms_out) ) ratio_S2N_diatoms_out = ratio_S2N_diatoms + if (present(ratio_S2N_sp_out) ) ratio_S2N_sp_out = ratio_S2N_sp + if (present(ratio_S2N_phaeo_out) ) ratio_S2N_phaeo_out = ratio_S2N_phaeo + if (present(ratio_Fe2C_diatoms_out) ) ratio_Fe2C_diatoms_out = ratio_Fe2C_diatoms + if (present(ratio_Fe2C_sp_out) ) ratio_Fe2C_sp_out = ratio_Fe2C_sp + if (present(ratio_Fe2C_phaeo_out) ) ratio_Fe2C_phaeo_out = ratio_Fe2C_phaeo + if (present(ratio_Fe2N_diatoms_out) ) ratio_Fe2N_diatoms_out = ratio_Fe2N_diatoms + if (present(ratio_Fe2N_sp_out) ) ratio_Fe2N_sp_out = ratio_Fe2N_sp + if (present(ratio_Fe2N_phaeo_out) ) ratio_Fe2N_phaeo_out = ratio_Fe2N_phaeo + if (present(ratio_Fe2DON_out) ) ratio_Fe2DON_out = ratio_Fe2DON + if (present(ratio_Fe2DOC_s_out) ) ratio_Fe2DOC_s_out = ratio_Fe2DOC_s + if (present(ratio_Fe2DOC_l_out) ) ratio_Fe2DOC_l_out = ratio_Fe2DOC_l + if (present(tau_min_out) ) tau_min_out = tau_min + if (present(tau_max_out) ) tau_max_out = tau_max + if (present(chlabs_diatoms_out) ) chlabs_diatoms_out = chlabs_diatoms + if (present(chlabs_sp_out) ) chlabs_sp_out = chlabs_sp + if (present(chlabs_phaeo_out) ) chlabs_phaeo_out = chlabs_phaeo + if (present(alpha2max_low_diatoms_out) ) alpha2max_low_diatoms_out = alpha2max_low_diatoms + if (present(alpha2max_low_sp_out) ) alpha2max_low_sp_out = alpha2max_low_sp + if (present(alpha2max_low_phaeo_out) ) alpha2max_low_phaeo_out = alpha2max_low_phaeo + if (present(beta2max_diatoms_out) ) beta2max_diatoms_out = beta2max_diatoms + if (present(beta2max_sp_out) ) beta2max_sp_out = beta2max_sp + if (present(beta2max_phaeo_out) ) beta2max_phaeo_out = beta2max_phaeo + if (present(mu_max_diatoms_out) ) mu_max_diatoms_out = mu_max_diatoms + if (present(mu_max_sp_out) ) mu_max_sp_out = mu_max_sp + if (present(mu_max_phaeo_out) ) mu_max_phaeo_out = mu_max_phaeo + if (present(grow_Tdep_diatoms_out) ) grow_Tdep_diatoms_out = grow_Tdep_diatoms + if (present(grow_Tdep_sp_out) ) grow_Tdep_sp_out = grow_Tdep_sp + if (present(grow_Tdep_phaeo_out) ) grow_Tdep_phaeo_out = grow_Tdep_phaeo + if (present(fr_graze_diatoms_out) ) fr_graze_diatoms_out = fr_graze_diatoms + if (present(fr_graze_sp_out) ) fr_graze_sp_out = fr_graze_sp + if (present(fr_graze_phaeo_out) ) fr_graze_phaeo_out = fr_graze_phaeo + if (present(mort_pre_diatoms_out) ) mort_pre_diatoms_out = mort_pre_diatoms + if (present(mort_pre_sp_out) ) mort_pre_sp_out = mort_pre_sp + if (present(mort_pre_phaeo_out) ) mort_pre_phaeo_out = mort_pre_phaeo + if (present(mort_Tdep_diatoms_out) ) mort_Tdep_diatoms_out = mort_Tdep_diatoms + if (present(mort_Tdep_sp_out) ) mort_Tdep_sp_out = mort_Tdep_sp + if (present(mort_Tdep_phaeo_out) ) mort_Tdep_phaeo_out = mort_Tdep_phaeo + if (present(k_exude_diatoms_out) ) k_exude_diatoms_out = k_exude_diatoms + if (present(k_exude_sp_out) ) k_exude_sp_out = k_exude_sp + if (present(k_exude_phaeo_out) ) k_exude_phaeo_out = k_exude_phaeo + if (present(K_Nit_diatoms_out) ) K_Nit_diatoms_out = K_Nit_diatoms + if (present(K_Nit_sp_out) ) K_Nit_sp_out = K_Nit_sp + if (present(K_Nit_phaeo_out) ) K_Nit_phaeo_out = K_Nit_phaeo + if (present(K_Am_diatoms_out) ) K_Am_diatoms_out = K_Am_diatoms + if (present(K_Am_sp_out) ) K_Am_sp_out = K_Am_sp + if (present(K_Am_phaeo_out) ) K_Am_phaeo_out = K_Am_phaeo + if (present(K_Sil_diatoms_out) ) K_Sil_diatoms_out = K_Sil_diatoms + if (present(K_Sil_sp_out) ) K_Sil_sp_out = K_Sil_sp + if (present(K_Sil_phaeo_out) ) K_Sil_phaeo_out = K_Sil_phaeo + if (present(K_Fe_diatoms_out) ) K_Fe_diatoms_out = K_Fe_diatoms + if (present(K_Fe_sp_out) ) K_Fe_sp_out = K_Fe_sp + if (present(K_Fe_phaeo_out) ) K_Fe_phaeo_out = K_Fe_phaeo + if (present(f_don_protein_out) ) f_don_protein_out = f_don_protein + if (present(kn_bac_protein_out) ) kn_bac_protein_out = kn_bac_protein + if (present(f_don_Am_protein_out) ) f_don_Am_protein_out = f_don_Am_protein + if (present(f_doc_s_out) ) f_doc_s_out = f_doc_s + if (present(f_doc_l_out) ) f_doc_l_out = f_doc_l + if (present(f_exude_s_out) ) f_exude_s_out = f_exude_s + if (present(f_exude_l_out) ) f_exude_l_out = f_exude_l + if (present(k_bac_s_out) ) k_bac_s_out = k_bac_s + if (present(k_bac_l_out) ) k_bac_l_out = k_bac_l + if (present(algaltype_diatoms_out) ) algaltype_diatoms_out = algaltype_diatoms + if (present(algaltype_sp_out) ) algaltype_sp_out = algaltype_sp + if (present(algaltype_phaeo_out) ) algaltype_phaeo_out = algaltype_phaeo + if (present(nitratetype_out) ) nitratetype_out = nitratetype + if (present(ammoniumtype_out) ) ammoniumtype_out = ammoniumtype + if (present(silicatetype_out) ) silicatetype_out = silicatetype + if (present(dmspptype_out) ) dmspptype_out = dmspptype + if (present(dmspdtype_out) ) dmspdtype_out = dmspdtype + if (present(humtype_out) ) humtype_out = humtype + if (present(doctype_s_out) ) doctype_s_out = doctype_s + if (present(doctype_l_out) ) doctype_l_out = doctype_l + if (present(dictype_1_out) ) dictype_1_out = dictype_1 + if (present(dontype_protein_out) ) dontype_protein_out = dontype_protein + if (present(fedtype_1_out) ) fedtype_1_out = fedtype_1 + if (present(feptype_1_out) ) feptype_1_out = feptype_1 + if (present(zaerotype_bc1_out) ) zaerotype_bc1_out = zaerotype_bc1 + if (present(zaerotype_bc2_out) ) zaerotype_bc2_out = zaerotype_bc2 + if (present(zaerotype_dust1_out) ) zaerotype_dust1_out = zaerotype_dust1 + if (present(zaerotype_dust2_out) ) zaerotype_dust2_out = zaerotype_dust2 + if (present(zaerotype_dust3_out) ) zaerotype_dust3_out = zaerotype_dust3 + if (present(zaerotype_dust4_out) ) zaerotype_dust4_out = zaerotype_dust4 + if (present(ratio_C2N_diatoms_out) ) ratio_C2N_diatoms_out = ratio_C2N_diatoms + if (present(ratio_C2N_sp_out) ) ratio_C2N_sp_out = ratio_C2N_sp + if (present(ratio_C2N_phaeo_out) ) ratio_C2N_phaeo_out = ratio_C2N_phaeo + if (present(ratio_chl2N_diatoms_out)) ratio_chl2N_diatoms_out = ratio_chl2N_diatoms + if (present(ratio_chl2N_sp_out) ) ratio_chl2N_sp_out = ratio_chl2N_sp + if (present(ratio_chl2N_phaeo_out) ) ratio_chl2N_phaeo_out = ratio_chl2N_phaeo + if (present(F_abs_chl_diatoms_out) ) F_abs_chl_diatoms_out = F_abs_chl_diatoms + if (present(F_abs_chl_sp_out) ) F_abs_chl_sp_out = F_abs_chl_sp + if (present(F_abs_chl_phaeo_out) ) F_abs_chl_phaeo_out = F_abs_chl_phaeo + if (present(ratio_C2N_proteins_out) ) ratio_C2N_proteins_out = ratio_C2N_proteins if (present(fr_resp_out) ) fr_resp_out = fr_resp if (present(algal_vel_out) ) algal_vel_out = algal_vel if (present(R_dFe2dust_out) ) R_dFe2dust_out = R_dFe2dust @@ -1808,7 +2427,6 @@ subroutine icepack_query_parameters( & if (present(y_sk_DMS_out) ) y_sk_DMS_out = y_sk_DMS if (present(t_sk_conv_out) ) t_sk_conv_out = t_sk_conv if (present(t_sk_ox_out) ) t_sk_ox_out = t_sk_ox - if (present(frazil_scav_out) ) frazil_scav_out = frazil_scav if (present(Lfresh_out) ) Lfresh_out = Lfresh if (present(cprho_out) ) cprho_out = cprho if (present(Cp_out) ) Cp_out = Cp @@ -1885,6 +2503,7 @@ subroutine icepack_write_parameters(iounit) write(iounit,*) " dSin0_frazil = ",dSin0_frazil write(iounit,*) " hi_ssl = ",hi_ssl write(iounit,*) " hs_ssl = ",hs_ssl + write(iounit,*) " hs_ssl_min = ",hs_ssl_min write(iounit,*) " awtvdr = ",awtvdr write(iounit,*) " awtidr = ",awtidr write(iounit,*) " awtvdf = ",awtvdf @@ -1933,6 +2552,7 @@ subroutine icepack_write_parameters(iounit) write(iounit,*) " dT_mlt = ", dT_mlt write(iounit,*) " rsnw_mlt = ", rsnw_mlt write(iounit,*) " kalg = ", kalg + write(iounit,*) " R_gC2molC = ", R_gC2molC write(iounit,*) " kstrength = ", kstrength write(iounit,*) " krdg_partic= ", krdg_partic write(iounit,*) " krdg_redist= ", krdg_redist @@ -1988,15 +2608,117 @@ subroutine icepack_write_parameters(iounit) write(iounit,*) " solve_zbgc = ", solve_zbgc write(iounit,*) " dEdd_algae = ", dEdd_algae write(iounit,*) " modal_aero = ", modal_aero + write(iounit,*) " use_macromolecules = ", use_macromolecules + write(iounit,*) " use_atm_dust_iron = ", use_atm_dust_iron + write(iounit,*) " restartbgc = ", restartbgc write(iounit,*) " conserv_check = ", conserv_check write(iounit,*) " skl_bgc = ", skl_bgc write(iounit,*) " solve_zsal = ", solve_zsal write(iounit,*) " grid_o = ", grid_o write(iounit,*) " l_sk = ", l_sk + write(iounit,*) " grid_o_t = ", grid_o_t write(iounit,*) " initbio_frac = ", initbio_frac + write(iounit,*) " frazil_scav= ", frazil_scav write(iounit,*) " grid_oS = ", grid_oS write(iounit,*) " l_skS = ", l_skS write(iounit,*) " phi_snow = ", phi_snow + + write(iounit,*) " ratio_Si2N_diatoms = ", ratio_Si2N_diatoms + write(iounit,*) " ratio_Si2N_sp = ", ratio_Si2N_sp + write(iounit,*) " ratio_Si2N_phaeo = ", ratio_Si2N_phaeo + write(iounit,*) " ratio_S2N_diatoms = ", ratio_S2N_diatoms + write(iounit,*) " ratio_S2N_sp = ", ratio_S2N_sp + write(iounit,*) " ratio_S2N_phaeo = ", ratio_S2N_phaeo + write(iounit,*) " ratio_Fe2C_diatoms = ", ratio_Fe2C_diatoms + write(iounit,*) " ratio_Fe2C_sp = ", ratio_Fe2C_sp + write(iounit,*) " ratio_Fe2C_phaeo = ", ratio_Fe2C_phaeo + write(iounit,*) " ratio_Fe2N_diatoms = ", ratio_Fe2N_diatoms + write(iounit,*) " ratio_Fe2N_sp = ", ratio_Fe2N_sp + write(iounit,*) " ratio_Fe2N_phaeo = ", ratio_Fe2N_phaeo + write(iounit,*) " ratio_Fe2DON = ", ratio_Fe2DON + write(iounit,*) " ratio_Fe2DOC_s = ", ratio_Fe2DOC_s + write(iounit,*) " ratio_Fe2DOC_l = ", ratio_Fe2DOC_l + write(iounit,*) " tau_min = ", tau_min + write(iounit,*) " tau_max = ", tau_max + write(iounit,*) " chlabs_diatoms = ", chlabs_diatoms + write(iounit,*) " chlabs_sp = ", chlabs_sp + write(iounit,*) " chlabs_phaeo = ", chlabs_phaeo + write(iounit,*) " alpha2max_low_diatoms = ", alpha2max_low_diatoms + write(iounit,*) " alpha2max_low_sp = ", alpha2max_low_sp + write(iounit,*) " alpha2max_low_phaeo = ", alpha2max_low_phaeo + write(iounit,*) " beta2max_diatoms = ", beta2max_diatoms + write(iounit,*) " beta2max_sp = ", beta2max_sp + write(iounit,*) " beta2max_phaeo = ", beta2max_phaeo + write(iounit,*) " mu_max_diatoms = ", mu_max_diatoms + write(iounit,*) " mu_max_sp = ", mu_max_sp + write(iounit,*) " mu_max_phaeo = ", mu_max_phaeo + write(iounit,*) " grow_Tdep_diatoms = ", grow_Tdep_diatoms + write(iounit,*) " grow_Tdep_sp = ", grow_Tdep_sp + write(iounit,*) " grow_Tdep_phaeo = ", grow_Tdep_phaeo + write(iounit,*) " fr_graze_diatoms = ", fr_graze_diatoms + write(iounit,*) " fr_graze_sp = ", fr_graze_sp + write(iounit,*) " fr_graze_phaeo = ", fr_graze_phaeo + write(iounit,*) " mort_pre_diatoms = ", mort_pre_diatoms + write(iounit,*) " mort_pre_sp = ", mort_pre_sp + write(iounit,*) " mort_pre_phaeo = ", mort_pre_phaeo + write(iounit,*) " mort_Tdep_diatoms = ", mort_Tdep_diatoms + write(iounit,*) " mort_Tdep_sp = ", mort_Tdep_sp + write(iounit,*) " mort_Tdep_phaeo = ", mort_Tdep_phaeo + write(iounit,*) " k_exude_diatoms = ", k_exude_diatoms + write(iounit,*) " k_exude_sp = ", k_exude_sp + write(iounit,*) " k_exude_phaeo = ", k_exude_phaeo + write(iounit,*) " K_Nit_diatoms = ", K_Nit_diatoms + write(iounit,*) " K_Nit_sp = ", K_Nit_sp + write(iounit,*) " K_Nit_phaeo = ", K_Nit_phaeo + write(iounit,*) " K_Am_diatoms = ", K_Am_diatoms + write(iounit,*) " K_Am_sp = ", K_Am_sp + write(iounit,*) " K_Am_phaeo = ", K_Am_phaeo + write(iounit,*) " K_Sil_diatoms = ", K_Sil_diatoms + write(iounit,*) " K_Sil_sp = ", K_Sil_sp + write(iounit,*) " K_Sil_phaeo = ", K_Sil_phaeo + write(iounit,*) " K_Fe_diatoms = ", K_Fe_diatoms + write(iounit,*) " K_Fe_sp = ", K_Fe_sp + write(iounit,*) " K_Fe_phaeo = ", K_Fe_phaeo + write(iounit,*) " f_don_protein = ", f_don_protein + write(iounit,*) " kn_bac_protein = ", kn_bac_protein + write(iounit,*) " f_don_Am_protein = ", f_don_Am_protein + write(iounit,*) " f_doc_s = ", f_doc_s + write(iounit,*) " f_doc_l = ", f_doc_l + write(iounit,*) " f_exude_s = ", f_exude_s + write(iounit,*) " f_exude_l = ", f_exude_l + write(iounit,*) " k_bac_s = ", k_bac_s + write(iounit,*) " k_bac_l = ", k_bac_l + write(iounit,*) " algaltype_diatoms = ", algaltype_diatoms + write(iounit,*) " algaltype_sp = ", algaltype_sp + write(iounit,*) " algaltype_phaeo = ", algaltype_phaeo + write(iounit,*) " nitratetype = ", nitratetype + write(iounit,*) " ammoniumtype = ", ammoniumtype + write(iounit,*) " silicatetype = ", silicatetype + write(iounit,*) " dmspptype = ", dmspptype + write(iounit,*) " dmspdtype = ", dmspdtype + write(iounit,*) " humtype = ", humtype + write(iounit,*) " doctype_s = ", doctype_s + write(iounit,*) " doctype_l = ", doctype_l + write(iounit,*) " dictype_1 = ", dictype_1 + write(iounit,*) " dontype_protein = ", dontype_protein + write(iounit,*) " fedtype_1 = ", fedtype_1 + write(iounit,*) " feptype_1 = ", feptype_1 + write(iounit,*) " zaerotype_bc1 = ", zaerotype_bc1 + write(iounit,*) " zaerotype_bc2 = ", zaerotype_bc2 + write(iounit,*) " zaerotype_dust1 = ", zaerotype_dust1 + write(iounit,*) " zaerotype_dust2 = ", zaerotype_dust2 + write(iounit,*) " zaerotype_dust3 = ", zaerotype_dust3 + write(iounit,*) " zaerotype_dust4 = ", zaerotype_dust4 + write(iounit,*) " ratio_C2N_diatoms = ", ratio_C2N_diatoms + write(iounit,*) " ratio_C2N_sp = ", ratio_C2N_sp + write(iounit,*) " ratio_C2N_phaeo = ", ratio_C2N_phaeo + write(iounit,*) " ratio_chl2N_diatoms = ", ratio_chl2N_diatoms + write(iounit,*) " ratio_chl2N_sp = ", ratio_chl2N_sp + write(iounit,*) " ratio_chl2N_phaeo = ", ratio_chl2N_phaeo + write(iounit,*) " F_abs_chl_diatoms = ", F_abs_chl_diatoms + write(iounit,*) " F_abs_chl_sp = ", F_abs_chl_sp + write(iounit,*) " F_abs_chl_phaeo = ", F_abs_chl_phaeo + write(iounit,*) " ratio_C2N_proteins = ", ratio_C2N_proteins write(iounit,*) " fr_resp = ", fr_resp write(iounit,*) " algal_vel = ", algal_vel write(iounit,*) " R_dFe2dust = ", R_dFe2dust @@ -2016,7 +2738,6 @@ subroutine icepack_write_parameters(iounit) write(iounit,*) " y_sk_DMS = ", y_sk_DMS write(iounit,*) " t_sk_conv = ", t_sk_conv write(iounit,*) " t_sk_ox = ", t_sk_ox - write(iounit,*) " frazil_scav= ", frazil_scav write(iounit,*) " sw_redist = ", sw_redist write(iounit,*) " sw_frac = ", sw_frac write(iounit,*) " sw_dtemp = ", sw_dtemp diff --git a/columnphysics/icepack_shortwave.F90 b/columnphysics/icepack_shortwave.F90 index 236e25f8a..7a3e5a4e5 100644 --- a/columnphysics/icepack_shortwave.F90 +++ b/columnphysics/icepack_shortwave.F90 @@ -64,7 +64,7 @@ module icepack_shortwave use icepack_tracers, only: nmodal1, nmodal2, max_aero use icepack_shortwave_data, only: nspint_3bd, nspint_5bd, rsnw_datatype use icepack_zbgc_shared,only: R_chl2N, F_abs_chl - use icepack_zbgc_shared,only: remap_zbgc + use icepack_zbgc_shared,only: remap_zbgc, igrid, swgrid use icepack_orbital, only: compute_coszen use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted @@ -3492,9 +3492,10 @@ subroutine compute_shortwave_trcr(bgcN, zaero, & do k = 1,nilyr+1 icegrid(k) = sw_grid(k) enddo - if (sw_grid(1)*hin*c2 > hi_ssl) then + if (sw_grid(1)*hin*c2 > hi_ssl .and. hin > puny) then icegrid(1) = hi_ssl/c2/hin endif + icegrid(2) = c2*sw_grid(1) + (sw_grid(2) - sw_grid(1)) if (z_tracers) then if (tr_bgc_N) then @@ -3704,7 +3705,6 @@ end subroutine icepack_prep_radiation ! Elizabeth C. Hunke, LANL subroutine icepack_step_radiation (dt, & - swgrid, igrid, & fbri, & aicen, vicen, & vsnon, Tsfcn, & @@ -3766,12 +3766,6 @@ subroutine icepack_step_radiation (dt, & real (kind=dbl_kind), intent(inout) :: & coszen ! cosine solar zenith angle, < 0 for sun below horizon - real (kind=dbl_kind), dimension (:), intent(in) :: & - igrid ! biology vertical interface points - - real (kind=dbl_kind), dimension (:), intent(in) :: & - swgrid ! grid for ice tracers used in dEdd scheme - real (kind=dbl_kind), dimension(:), intent(in) :: & aicen , & ! ice area fraction in each category vicen , & ! ice volume in each category (m) diff --git a/columnphysics/icepack_snow.F90 b/columnphysics/icepack_snow.F90 index 8def9b45f..3987d2922 100644 --- a/columnphysics/icepack_snow.F90 +++ b/columnphysics/icepack_snow.F90 @@ -17,6 +17,7 @@ module icepack_snow use icepack_parameters, only: snowage_rhos, snowage_Tgrd, snowage_T use icepack_parameters, only: snowage_tau, snowage_kappa, snowage_drdt0 use icepack_parameters, only: snw_aging_table, use_smliq_pnd + use icepack_tracers, only: ncat, nilyr, nslyr use icepack_therm_shared, only: icepack_ice_temperature use icepack_therm_shared, only: adjust_enthalpy @@ -240,8 +241,7 @@ end subroutine icepack_init_snow ! authors: Elizabeth C. Hunke, LANL ! Nicole Jeffery, LANL - subroutine icepack_step_snow(dt, nilyr, & - nslyr, ncat, & + subroutine icepack_step_snow(dt, & wind, aice, & aicen, vicen, & vsnon, Tsfc, & @@ -253,11 +253,6 @@ subroutine icepack_step_snow(dt, nilyr, & 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) @@ -329,7 +324,6 @@ subroutine icepack_step_snow(dt, nilyr, & if (snwredist(1:3) == 'ITD' .and. aice > puny) then call snow_redist(dt, & - nslyr, ncat, & wind, aicen(:), & vicen(:), vsnon(:), & zqsn(:,:), & @@ -368,8 +362,7 @@ subroutine icepack_step_snow(dt, nilyr, & endif enddo - call update_snow_radius (dt, ncat, & - nslyr, nilyr, & + call update_snow_radius (dt, & rsnw, hin, & Tsfc, zTin1, & hsn, zqsn, & @@ -397,13 +390,9 @@ end subroutine icepack_step_snow ! volume, mass and energy include factor of ain ! thickness does not - subroutine snow_redist(dt, nslyr, ncat, wind, ain, vin, vsn, zqsn, & + subroutine snow_redist(dt, wind, ain, vin, vsn, zqsn, & alvl, vlvl, fresh, fhocn, fsloss, rhos_cmpn, fsnow) - integer (kind=int_kind), intent(in) :: & - nslyr , & ! number of snow layers - ncat ! number of thickness categories - real (kind=dbl_kind), intent(in) :: & dt , & ! time step (s) wind , & ! wind speed (m/s) @@ -682,13 +671,13 @@ subroutine snow_redist(dt, nslyr, ncat, wind, ain, vin, vsn, zqsn, & zs2(k+1) = zs2(k) + hslyr ! new layer depths (equal thickness) enddo - call adjust_enthalpy (nslyr, & - zs1(:), zs2(:), & - hslyr, hsn_new(n), & + call adjust_enthalpy (nslyr, & + zs1(:), zs2(:), & + hslyr , hsn_new(n), & zqsn(:,n)) if (icepack_warnings_aborted(subname)) return else - hsn_new(1) = hsn_new(1) + dhsn + hsn_new(n) = hsn_new(n) + dhsn endif ! nslyr > 1 endif ! |dhsn| > puny endif ! ain > puny @@ -824,14 +813,9 @@ end subroutine snow_redist ! Snow grain metamorphism - subroutine update_snow_radius (dt, ncat, nslyr, nilyr, rsnw, hin, & + subroutine update_snow_radius (dt, rsnw, hin, & Tsfc, zTin, hsn, zqsn, smice, smliq) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of categories - nslyr , & ! number of snow layers - nilyr ! number of ice layers - real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -871,7 +855,7 @@ subroutine update_snow_radius (dt, ncat, nslyr, nilyr, rsnw, hin, & !----------------------------------------------------------------- ! dry metamorphism !----------------------------------------------------------------- - call snow_dry_metamorph (nslyr, nilyr, dt, rsnw(:,n), & + call snow_dry_metamorph (dt, rsnw(:,n), & drsnw_dry, zqsn(:,n), Tsfc(n), & zTin(n), hsn(n), hin(n)) if (icepack_warnings_aborted(subname)) return @@ -902,7 +886,7 @@ end subroutine update_snow_radius ! Snow grain metamorphism - subroutine snow_dry_metamorph (nslyr,nilyr, dt, rsnw, drsnw_dry, zqsn, & + subroutine snow_dry_metamorph (dt, rsnw, drsnw_dry, zqsn, & Tsfc, zTin1, hsn, hin) ! Vapor redistribution: Method is to retrieve 3 best-fit parameters that @@ -918,10 +902,6 @@ subroutine snow_dry_metamorph (nslyr,nilyr, dt, rsnw, drsnw_dry, zqsn, & ! dr_fresh is the difference between the current and fresh snow states ! (r_current - r_fresh). - integer (kind=int_kind), intent(in) :: & - nslyr, & ! number of snow layers - nilyr ! number of ice layers - real (kind=dbl_kind), intent(in) :: & dt ! time step (s) @@ -1175,12 +1155,9 @@ end subroutine snowtable_check_dimension ! Conversions between ice mass, liquid water mass in snow - subroutine drain_snow (nslyr, vsnon, aicen, & + subroutine drain_snow (vsnon, aicen, & massice, massliq, meltsliq) - integer (kind=int_kind), intent(in) :: & - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & vsnon, & ! snow volume (m) aicen ! aice area fraction diff --git a/columnphysics/icepack_therm_bl99.F90 b/columnphysics/icepack_therm_bl99.F90 index 36ec12681..30c247ac7 100644 --- a/columnphysics/icepack_therm_bl99.F90 +++ b/columnphysics/icepack_therm_bl99.F90 @@ -16,6 +16,7 @@ module icepack_therm_bl99 use icepack_parameters, only: rhoi, rhos, hs_min, cp_ice, cp_ocn, depressT, Lfresh, ksno, kice use icepack_parameters, only: conduct, calc_Tsfc use icepack_parameters, only: sw_redist, sw_frac, sw_dtemp + use icepack_tracers, only: nilyr, nslyr use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted @@ -53,7 +54,6 @@ module icepack_therm_bl99 ! C. M. Bitz, UW subroutine temperature_changes (dt, & - nilyr, nslyr, & rhoa, flw, & potT, Qa, & shcoef, lhcoef, & @@ -69,10 +69,6 @@ subroutine temperature_changes (dt, & fcondtopn,fcondbot, & einit ) - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -243,7 +239,6 @@ subroutine temperature_changes (dt, & !----------------------------------------------------------------- call conductivity (l_snow, & - nilyr, nslyr, & hilyr, hslyr, & zTin, kh, zSin) if (icepack_warnings_aborted(subname)) return @@ -405,7 +400,7 @@ subroutine temperature_changes (dt, & ! Compute elements of tridiagonal matrix. !----------------------------------------------------------------- - call get_matrix_elements_calc_Tsfc (nilyr, nslyr, & + call get_matrix_elements_calc_Tsfc ( & l_snow, l_cold, & Tsf, Tbot, & fsurfn, dfsurf_dT, & @@ -419,7 +414,7 @@ subroutine temperature_changes (dt, & else - call get_matrix_elements_know_Tsfc (nilyr, nslyr, & + call get_matrix_elements_know_Tsfc ( & l_snow, Tbot, & Tin_init, Tsn_init, & kh, Sswabs, & @@ -801,17 +796,12 @@ end subroutine temperature_changes ! C. M. Bitz, UW subroutine conductivity (l_snow, & - nilyr, nslyr, & hilyr, hslyr, & zTin, kh, zSin) logical (kind=log_kind), intent(in) :: & l_snow ! true if snow temperatures are computed - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & hilyr , & ! ice layer thickness (same for all ice layers) hslyr ! snow layer thickness (same for all snow layers) @@ -969,7 +959,7 @@ end subroutine surface_fluxes ! March 2004 by William H. Lipscomb for multiple snow layers ! April 2008 by E. C. Hunke, divided into two routines based on calc_Tsfc - subroutine get_matrix_elements_calc_Tsfc (nilyr, nslyr, & + subroutine get_matrix_elements_calc_Tsfc ( & l_snow, l_cold, & Tsf, Tbot, & fsurfn, dfsurf_dT, & @@ -980,10 +970,6 @@ subroutine get_matrix_elements_calc_Tsfc (nilyr, nslyr, & sbdiag, diag, & spdiag, rhs) - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - logical (kind=log_kind), intent(in) :: & l_snow , & ! true if snow temperatures are computed l_cold ! true if surface temperature is computed @@ -1216,7 +1202,7 @@ end subroutine get_matrix_elements_calc_Tsfc ! March 2004 by William H. Lipscomb for multiple snow layers ! April 2008 by E. C. Hunke, divided into two routines based on calc_Tsfc - subroutine get_matrix_elements_know_Tsfc (nilyr, nslyr, & + subroutine get_matrix_elements_know_Tsfc ( & l_snow, Tbot, & Tin_init, Tsn_init, & kh, Sswabs, & @@ -1226,10 +1212,6 @@ subroutine get_matrix_elements_know_Tsfc (nilyr, nslyr, & spdiag, rhs, & fcondtopn) - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - logical (kind=log_kind), intent(in) :: & l_snow ! true if snow temperatures are computed diff --git a/columnphysics/icepack_therm_itd.F90 b/columnphysics/icepack_therm_itd.F90 index 047b921bf..02a9ab4b8 100644 --- a/columnphysics/icepack_therm_itd.F90 +++ b/columnphysics/icepack_therm_itd.F90 @@ -23,7 +23,7 @@ module icepack_therm_itd use icepack_parameters, only: c0, c1, c2, c3, c4, c6, c10 use icepack_parameters, only: p001, p1, p333, p5, p666, puny, bignum use icepack_parameters, only: rhos, rhoi, Lfresh, ice_ref_salinity - use icepack_parameters, only: phi_init, dsin0_frazil, hs_ssl, salt_loss + use icepack_parameters, only: phi_init, dsin0_frazil, salt_loss use icepack_parameters, only: Tliquidus_max use icepack_parameters, only: rhosi, conserv_check, rhosmin, snwredist use icepack_parameters, only: kitd, ktherm @@ -31,7 +31,7 @@ module icepack_therm_itd use icepack_parameters, only: cpl_frazil, update_ocn_f, saltflux_option use icepack_parameters, only: icepack_chkoptargflag - use icepack_tracers, only: ntrcr, nbtrcr + use icepack_tracers, only: ncat, nilyr, nslyr, nblyr, ntrcr, nbtrcr, nfsd use icepack_tracers, only: nt_qice, nt_qsno, nt_fbri, nt_sice use icepack_tracers, only: nt_apnd, nt_hpnd, nt_aero, nt_isosno, nt_isoice use icepack_tracers, only: nt_Tsfc, nt_iage, nt_FY, nt_fsd, nt_rhos, nt_sice @@ -52,6 +52,7 @@ module icepack_therm_itd use icepack_mushy_physics, only: liquidus_temperature_mush, icepack_enthalpy_mush use icepack_zbgc, only: add_new_ice_bgc use icepack_zbgc, only: lateral_melt_bgc + use icepack_zbgc_shared, only: bgrid, cgrid, igrid implicit none @@ -87,9 +88,7 @@ module icepack_therm_itd ! authors: William H. Lipscomb, LANL ! Elizabeth C. Hunke, LANL - subroutine linear_itd (ncat, hin_max, & - nilyr, nslyr, & - ntrcr, trcr_depend, & + subroutine linear_itd (hin_max, trcr_depend, & trcr_base, n_trcr_strata,& nt_strata, & aicen_init, vicen_init, & @@ -98,12 +97,6 @@ subroutine linear_itd (ncat, hin_max, & aice, aice0, & fpond, Tf ) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nilyr , & ! number of ice layers - nslyr , & ! number of snow layers - ntrcr ! number of tracers in use - real (kind=dbl_kind), dimension(0:ncat), intent(in) :: & hin_max ! category boundaries (m) @@ -318,7 +311,7 @@ subroutine linear_itd (ncat, hin_max, & write(warnstr,*) subname, & 'ITD Thermodynamics: hicen_init(n+1) <= hicen_init(n)' - call icepack_warnings_setabort(.true.) + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) call icepack_warnings_add(warnstr) endif @@ -579,8 +572,7 @@ subroutine linear_itd (ncat, hin_max, & enddo endif - call shift_ice (ntrcr, ncat, & - trcr_depend, & + call shift_ice (trcr_depend, & trcr_base, & n_trcr_strata, & nt_strata, & @@ -626,7 +618,7 @@ subroutine linear_itd (ncat, hin_max, & ! Update fractional ice area in each grid cell. !----------------------------------------------------------------- - call aggregate_area (ncat, aicen, aice, aice0) + call aggregate_area (aicen, aice, aice0) if (icepack_warnings_aborted(subname)) return !----------------------------------------------------------------- @@ -795,10 +787,7 @@ end subroutine fit_line ! ! author: A. K. Turner, LANL ! - subroutine update_vertical_tracers(nilyr, trc, h1, h2, trc0) - - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers + subroutine update_vertical_tracers(trc, h1, h2, trc0) real (kind=dbl_kind), dimension(:), intent(inout) :: & trc ! vertical tracer @@ -877,10 +866,7 @@ end subroutine update_vertical_tracers ! 2003: Modified by William H. Lipscomb and Elizabeth C. Hunke, LANL ! 2016 Lettie Roach, NIWA/VUW, added floe size dependence ! - subroutine lateral_melt (dt, ncat, & - nilyr, nslyr, & - n_aero, & - fpond, & + subroutine lateral_melt (dt, fpond, & fresh, fsalt, & fhocn, faero_ocn, & fiso_ocn, & @@ -888,25 +874,12 @@ subroutine lateral_melt (dt, ncat, & fside, wlat, & aicen, vicen, & vsnon, trcrn, & - flux_bio, & - nbtrcr, nblyr, & - nfsd, d_afsd_latm,& + flux_bio, d_afsd_latm,& floe_rad_c, floe_binwidth) real (kind=dbl_kind), intent(in) :: & dt ! time step (s) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nilyr , & ! number of ice layers - nblyr , & ! number of bio layers - nslyr , & ! number of snow layers - n_aero , & ! number of aerosol tracers - nbtrcr ! number of bio tracers - - integer (kind=int_kind), intent(in), optional :: & - nfsd ! number of floe size categories - real (kind=dbl_kind), dimension (:), intent(inout) :: & aicen , & ! concentration of ice vicen , & ! volume per unit area of ice (m) @@ -970,6 +943,7 @@ subroutine lateral_melt (dt, ncat, & real (kind=dbl_kind), dimension (ncat) :: & aicen_init, & ! initial area fraction vicen_init, & ! volume per unit area of ice (m) + vsnon_init, & ! initial volume of snow (m) G_radialn , & ! rate of lateral melt (m/s) delta_an , & ! change in the ITD rsiden ! delta_an/aicen @@ -1001,13 +975,13 @@ subroutine lateral_melt (dt, ncat, & dvint = c0 bin1_arealoss = c0 tmp = c0 - vicen_init = c0 + vicen_init = vicen(:) G_radialn = c0 delta_an = c0 rsiden = c0 if (tr_fsd) then - call icepack_cleanup_fsd (ncat, nfsd, trcrn(nt_fsd:nt_fsd+nfsd-1,:)) + call icepack_cleanup_fsd (trcrn(nt_fsd:nt_fsd+nfsd-1,:)) if (icepack_warnings_aborted(subname)) return allocate(afsdn(nfsd,ncat)) @@ -1127,6 +1101,7 @@ subroutine lateral_melt (dt, ncat, & ! state variables vicen_init(n) = vicen(n) + vsnon_init(n) = vsnon(n) aicen(n) = aicen(n) * (c1 - rsiden(n)) vicen(n) = vicen(n) * (c1 - rsiden(n)) vsnon(n) = vsnon(n) * (c1 - rsiden(n)) @@ -1176,7 +1151,7 @@ subroutine lateral_melt (dt, ncat, & end do ! timestep required for this - subdt = get_subdt_fsd(nfsd, afsd_tmp(:), d_afsd_tmp(:)) + subdt = get_subdt_fsd(afsd_tmp(:), d_afsd_tmp(:)) subdt = MIN(subdt, dt) ! update fsd and elapsed time @@ -1236,8 +1211,8 @@ subroutine lateral_melt (dt, ncat, & !----------------------------------------------------------------- if (z_tracers) then ! snow tracers - dvssl = min(p5*vsnon(n)/real(nslyr,kind=dbl_kind), hs_ssl*aicen(n)) ! snow surface layer - dvint = vsnon(n) - dvssl ! snow interior + dvssl = p5*vsnon_init(n)/real(nslyr,kind=dbl_kind) ! snow surface layer + dvint = vsnon_init(n) - dvssl ! snow interior do k = 1, nbtrcr flux_bio(k) = flux_bio(k) & + (trcrn(bio_index(k)+nblyr+1,n)*dvssl & @@ -1250,10 +1225,8 @@ subroutine lateral_melt (dt, ncat, & if (z_tracers) & call lateral_melt_bgc(dt, & - ncat, nblyr, & - rside, vicen_init, & !echmod: use rsiden - trcrn, & - flux_bio, nbtrcr) + rsiden, vicen_init, & + trcrn, flux_bio) if (icepack_warnings_aborted(subname)) return endif ! flag @@ -1262,7 +1235,7 @@ subroutine lateral_melt (dt, ncat, & trcrn(nt_fsd:nt_fsd+nfsd-1,:) = afsdn - call icepack_cleanup_fsd (ncat, nfsd, trcrn(nt_fsd:nt_fsd+nfsd-1,:) ) + call icepack_cleanup_fsd (trcrn(nt_fsd:nt_fsd+nfsd-1,:) ) if (icepack_warnings_aborted(subname)) return ! diagnostics @@ -1306,13 +1279,10 @@ end subroutine lateral_melt ! Adrian Turner, LANL ! Lettie Roach, NIWA/VUW ! - subroutine add_new_ice (ncat, nilyr, & - nfsd, nblyr, & - n_aero, dt, & - ntrcr, nltrcr, & + subroutine add_new_ice (dt, & hin_max, ktherm, & aicen, trcrn, & - vicen, vsnon1, & + vicen, & aice0, aice, & frzmlt, frazil, & frz_onset, yday, & @@ -1320,8 +1290,7 @@ subroutine add_new_ice (ncat, nilyr, & Tf, sss, & salinz, phi_init, & dSin0_frazil, & - bgrid, cgrid, igrid, & - nbtrcr, flux_bio, & + flux_bio, & ocean_bio, & frazil_diag, & fiso_ocn, & @@ -1338,17 +1307,8 @@ subroutine add_new_ice (ncat, nilyr, & use icepack_fsd, only: fsd_lateral_growth, fsd_add_new_ice integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nilyr , & ! number of ice layers - nblyr , & ! number of bio layers - ntrcr , & ! number of tracers - nltrcr, & ! number of zbgc tracers - n_aero, & ! number of aerosol tracers ktherm ! type of thermodynamics (-1 none, 1 BL99, 2 mushy) - integer (kind=int_kind), intent(in), optional :: & - nfsd ! number of floe size categories - real (kind=dbl_kind), dimension(0:ncat), intent(in) :: & hin_max ! category boundaries (m) @@ -1357,8 +1317,7 @@ subroutine add_new_ice (ncat, nilyr, & aice , & ! total concentration of ice frzmlt, & ! freezing/melting potential (W/m^2) Tf , & ! freezing temperature (C) - sss , & ! sea surface salinity (ppt) - vsnon1 ! category 1 snow volume per ice area (m) + sss ! sea surface salinity (ppt) real (kind=dbl_kind), dimension (:), intent(inout) :: & aicen , & ! concentration of ice @@ -1389,17 +1348,6 @@ subroutine add_new_ice (ncat, nilyr, & dSin0_frazil ! initial frazil bulk salinity reduction from sss ! BGC - real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: & - bgrid ! biology nondimensional vertical grid points - - real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: & - igrid ! biology vertical interface points - - real (kind=dbl_kind), dimension (nilyr+1), intent(in) :: & - cgrid ! CICE vertical coordinate - - integer (kind=int_kind), intent(in) :: & - nbtrcr ! number of biology tracers real (kind=dbl_kind), dimension (:), intent(inout) :: & flux_bio ! tracer flux to ocean from biology (mmol/m^2/s) @@ -1539,7 +1487,7 @@ subroutine add_new_ice (ncat, nilyr, & if (tr_fsd) then allocate(afsdn(nfsd,ncat)) afsdn(:,:) = c0 - call icepack_cleanup_fsd (ncat, nfsd, trcrn(nt_fsd:nt_fsd+nfsd-1,:)) + call icepack_cleanup_fsd (trcrn(nt_fsd:nt_fsd+nfsd-1,:)) if (icepack_warnings_aborted(subname)) return endif @@ -1657,8 +1605,7 @@ subroutine add_new_ice (ncat, nilyr, & if (tr_fsd) then ! lateral growth of existing ice ! calculate change in conc due to lateral growth ! update vi0new, without change to afsdn or aicen - call fsd_lateral_growth (ncat, nfsd, & - dt, aice, & + call fsd_lateral_growth(dt, aice, & aicen, vicen, & vi0new, frazil, & floe_rad_c, afsdn, & @@ -1777,11 +1724,11 @@ subroutine add_new_ice (ncat, nilyr, & vsurp = hsurp * aicen(n) ! note - save this above? vtmp = vicen(n) - vsurp ! vicen is the new volume if (vicen(n) > c0) then - call update_vertical_tracers(nilyr, & + call update_vertical_tracers( & trcrn(nt_qice:nt_qice+nilyr-1,n), & vtmp, vicen(n), qi0new) if (icepack_warnings_aborted(subname)) return - call update_vertical_tracers(nilyr, & + call update_vertical_tracers( & trcrn(nt_sice:nt_sice+nilyr-1,n), & vtmp, vicen(n), Si0new) if (icepack_warnings_aborted(subname)) return @@ -1818,7 +1765,6 @@ subroutine add_new_ice (ncat, nilyr, & ncats = 1 ! add new ice to category 1 by default if (tr_fsd) ncats = ncat ! add new ice laterally to all categories - do n = 1, ncats if (d_an_tot(n) > c0 .and. vin0new(n) > c0) then ! add ice to category n @@ -1841,7 +1787,7 @@ subroutine add_new_ice (ncat, nilyr, & if (tr_fsd) then ! evolve the floe size distribution ! both new frazil ice and lateral growth - call fsd_add_new_ice (ncat, n, nfsd, & + call fsd_add_new_ice (n, & dt, ai0new, & d_an_latg, d_an_newi, & floe_rad_c, floe_binwidth, & @@ -1887,7 +1833,7 @@ subroutine add_new_ice (ncat, nilyr, & fiso_ocn(it) = fiso_ocn(it) & - frazil_conc*rhoi*vi0new/dt enddo - endif + endif ! if iso if (tr_lvl) then alvl = trcrn(nt_alvl,n) @@ -1906,7 +1852,7 @@ subroutine add_new_ice (ncat, nilyr, & trcrn(nt_apnd,n) * alvl*area1 / (trcrn(nt_alvl,n)*aicen(n)) endif endif - endif + endif ! vicen > 0 do k = 1, nilyr if (vicen(n) > c0) then @@ -1918,11 +1864,9 @@ subroutine add_new_ice (ncat, nilyr, & trcrn(nt_sice+k-1,n) = & (trcrn(nt_sice+k-1,n)*vice1 + Sprofile(k)*vin0new(n))/vicen(n) endif - enddo - - endif ! vi0new > 0 - - enddo ! ncats + enddo ! nilyr + endif ! vin0new > c0 + enddo ! n if (conserv_check) then @@ -1955,14 +1899,12 @@ subroutine add_new_ice (ncat, nilyr, & ! Biogeochemistry !----------------------------------------------------------------- if (tr_brine .or. nbtrcr > 0) then - call add_new_ice_bgc(dt, nblyr, & - ncat, nilyr, nltrcr, & - bgrid, cgrid, igrid, & + call add_new_ice_bgc(dt, ncats, & aicen_init, vicen_init, vi0_init, & - aicen, vicen, vsnon1, & - vi0new, ntrcr, trcrn, & - nbtrcr, sss, ocean_bio,& - flux_bio, hsurp) + aicen, vicen, vin0new, & + trcrn, & + ocean_bio, flux_bio, hsurp, & + d_an_tot) if (icepack_warnings_aborted(subname)) return endif @@ -1980,9 +1922,7 @@ end subroutine add_new_ice ! authors: William H. Lipscomb, LANL ! Elizabeth C. Hunke, LANL - subroutine icepack_step_therm2 (dt, ncat, nltrcr, & - nilyr, nslyr, & - hin_max, nblyr, & + subroutine icepack_step_therm2(dt, hin_max, & aicen, & vicen, vsnon, & aicen_init, vicen_init, & @@ -1999,15 +1939,14 @@ subroutine icepack_step_therm2 (dt, ncat, nltrcr, & frain, fpond, & fresh, fsalt, & fhocn, update_ocn_f, & - bgrid, cgrid, & - igrid, faero_ocn, & + faero_ocn, & first_ice, fzsal, & flux_bio, ocean_bio, & frazil_diag, & frz_onset, yday, & fiso_ocn, HDO_ocn, & H2_16O_ocn, H2_18O_ocn, & - nfsd, wave_sig_ht, & + wave_sig_ht, & wave_spectrum, & wavefreq, & dwavefreq, & @@ -2017,16 +1956,6 @@ subroutine icepack_step_therm2 (dt, ncat, nltrcr, & use icepack_parameters, only: icepack_init_parameters - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nltrcr , & ! number of zbgc tracers - nblyr , & ! number of bio layers - nilyr , & ! number of ice layers - nslyr ! number of snow layers - - integer (kind=int_kind), intent(in), optional :: & - nfsd ! number of floe size categories - logical (kind=log_kind), intent(in), optional :: & update_ocn_f ! if true, update fresh water and salt fluxes @@ -2051,15 +1980,6 @@ subroutine icepack_step_therm2 (dt, ncat, nltrcr, & integer (kind=int_kind), dimension (:,:), intent(in) :: & nt_strata ! indices of underlying tracer layers - real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: & - bgrid ! biology nondimensional vertical grid points - - real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: & - igrid ! biology vertical interface points - - real (kind=dbl_kind), dimension (nilyr+1), intent(in) :: & - cgrid ! CICE vertical coordinate - real (kind=dbl_kind), dimension(:), intent(in) :: & salinz , & ! initial salinity profile ocean_bio ! ocean concentration of biological tracer @@ -2162,8 +2082,7 @@ subroutine icepack_step_therm2 (dt, ncat, nltrcr, & endif endif if (tr_fsd) then - if (.not.(present(nfsd) .and. & - present(wlat) .and. & + if (.not.(present(wlat) .and. & present(wave_sig_ht) .and. & present(wave_spectrum) .and. & present(wavefreq) .and. & @@ -2198,7 +2117,9 @@ subroutine icepack_step_therm2 (dt, ncat, nltrcr, & ! Compute fractional ice area in each grid cell. !----------------------------------------------------------------- - call aggregate_area (ncat, aicen, aice, aice0) + flux_bio(:) = c0 + + call aggregate_area (aicen, aice, aice0) if (icepack_warnings_aborted(subname)) return if (kitd == 1) then @@ -2209,9 +2130,8 @@ subroutine icepack_step_therm2 (dt, ncat, nltrcr, & if (aice > puny) then - call linear_itd (ncat, hin_max, & - nilyr, nslyr, & - ntrcr, trcr_depend, & + call linear_itd (hin_max, & + trcr_depend, & trcr_base, & n_trcr_strata, & nt_strata, & @@ -2238,22 +2158,18 @@ subroutine icepack_step_therm2 (dt, ncat, nltrcr, & ! identify ice-ocean cells - call add_new_ice (ncat, nilyr, & - nfsd, nblyr, & - n_aero, dt, & - ntrcr, nltrcr, & + call add_new_ice (dt, & hin_max, ktherm, & aicen, trcrn, & - vicen, vsnon(1), & + vicen, & aice0, aice, & frzmlt, frazil, & frz_onset, yday, & fresh, fsalt, & Tf, sss, & salinz, phi_init, & - dSin0_frazil, bgrid, & - cgrid, igrid, & - nbtrcr, flux_bio, & + dSin0_frazil, & + flux_bio, & ocean_bio, & frazil_diag, fiso_ocn, & HDO_ocn, H2_16O_ocn, & @@ -2270,9 +2186,7 @@ subroutine icepack_step_therm2 (dt, ncat, nltrcr, & ! Melt ice laterally. !----------------------------------------------------------------- - call lateral_melt (dt, ncat, & - nilyr, nslyr, & - n_aero, fpond, & + call lateral_melt (dt, fpond, & fresh, fsalt, & fhocn, faero_ocn, & fiso_ocn, & @@ -2281,15 +2195,13 @@ subroutine icepack_step_therm2 (dt, ncat, nltrcr, & aicen, vicen, & vsnon, trcrn, & flux_bio, & - nbtrcr, nblyr, & - nfsd, d_afsd_latm, & + d_afsd_latm, & floe_rad_c,floe_binwidth) if (icepack_warnings_aborted(subname)) return ! Floe welding during freezing conditions if (tr_fsd) then - call fsd_weld_thermo (ncat, nfsd, & - dt, frzmlt, & + call fsd_weld_thermo (dt, frzmlt, & aicen, trcrn, & d_afsd_weld) if (icepack_warnings_aborted(subname)) return @@ -2312,14 +2224,10 @@ subroutine icepack_step_therm2 (dt, ncat, nltrcr, & ! categories with very small areas. !----------------------------------------------------------------- - call cleanup_itd (dt, ntrcr, & - nilyr, nslyr, & - ncat, hin_max, & + call cleanup_itd (dt, hin_max, & aicen, trcrn(1:ntrcr,:), & vicen, vsnon, & aice0, aice, & - n_aero, & - nbtrcr, nblyr, & tr_aero, & tr_pond_topo, & first_ice, & diff --git a/columnphysics/icepack_therm_mushy.F90 b/columnphysics/icepack_therm_mushy.F90 index c5a79ffd8..00438e8de 100644 --- a/columnphysics/icepack_therm_mushy.F90 +++ b/columnphysics/icepack_therm_mushy.F90 @@ -10,13 +10,13 @@ module icepack_therm_mushy use icepack_parameters, only: a_rapid_mode, Rac_rapid_mode, tscale_pnd_drain use icepack_parameters, only: aspect_rapid_mode, dSdt_slow_mode, phi_c_slow_mode use icepack_parameters, only: sw_redist, sw_frac, sw_dtemp + use icepack_tracers, only: nilyr, nslyr, tr_pond use icepack_mushy_physics, only: icepack_mushy_density_brine, enthalpy_brine, icepack_enthalpy_snow use icepack_mushy_physics, only: enthalpy_mush_liquid_fraction use icepack_mushy_physics, only: icepack_mushy_temperature_mush, icepack_mushy_liquid_fraction use icepack_mushy_physics, only: temperature_snow, temperature_mush_liquid_fraction use icepack_mushy_physics, only: liquidus_brine_salinity_mush, liquidus_temperature_mush use icepack_mushy_physics, only: conductivity_mush_array, conductivity_snow_array - use icepack_tracers, only: tr_pond use icepack_therm_shared, only: surface_heat_flux, dsurface_heat_flux_dTsf use icepack_therm_shared, only: ferrmax use icepack_warnings, only: warnstr, icepack_warnings_add @@ -40,7 +40,6 @@ module icepack_therm_mushy !======================================================================= subroutine temperature_changes_salinity(dt, & - nilyr, nslyr, & rhoa, flw, & potT, Qa, & shcoef, lhcoef, & @@ -61,10 +60,6 @@ subroutine temperature_changes_salinity(dt, & ! solve the enthalpy and bulk salinity of the ice for a single column - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & dt ! time step (s) @@ -185,8 +180,7 @@ subroutine temperature_changes_salinity(dt, & enddo ! k ! calculate vertical bulk darcy flow - call flushing_velocity(zTin, & - phi, nilyr, & + call flushing_velocity(zTin, phi, & hin, hsn, & hilyr, & hpond, apond, & @@ -194,7 +188,7 @@ subroutine temperature_changes_salinity(dt, & if (icepack_warnings_aborted(subname)) return ! calculate quantities related to drainage - call explicit_flow_velocities(nilyr, zSin, & + call explicit_flow_velocities(zSin, & zTin, Tsf, & Tbot, q, & dSdt, Sbr, & @@ -204,7 +198,7 @@ subroutine temperature_changes_salinity(dt, & if (icepack_warnings_aborted(subname)) return ! calculate the conductivities - call conductivity_mush_array(nilyr, zqin0, zSin0, km) + call conductivity_mush_array(zqin0, zSin0, km) if (icepack_warnings_aborted(subname)) return !----------------------------------------------------------------- @@ -251,8 +245,7 @@ subroutine temperature_changes_salinity(dt, & if (icepack_warnings_aborted(subname)) return ! run the two stage solver - call two_stage_solver_snow(nilyr, nslyr, & - Tsf, Tsf0, & + call two_stage_solver_snow(Tsf, Tsf0, & zqsn, zqsn0, & zqin, zqin0, & zSin, zSin0, & @@ -296,8 +289,7 @@ subroutine temperature_changes_salinity(dt, & ! case without snow ! run the two stage solver - call two_stage_solver_nosnow(nilyr, nslyr, & - Tsf, Tsf0, & + call two_stage_solver_nosnow(Tsf, Tsf0, & zqsn, & zqin, zqin0, & zSin, zSin0, & @@ -341,7 +333,6 @@ subroutine temperature_changes_salinity(dt, & ! flood snow ice call flood_ice(hsn, hin, & - nslyr, nilyr, & hslyr, hilyr, & zqsn, zqin, & phi, dt, & @@ -355,8 +346,7 @@ end subroutine temperature_changes_salinity !======================================================================= - subroutine two_stage_solver_snow(nilyr, nslyr, & - Tsf, Tsf0, & + subroutine two_stage_solver_snow(Tsf, Tsf0, & zqsn, zqsn0, & zqin, zqin0, & zSin, zSin0, & @@ -386,10 +376,6 @@ subroutine two_stage_solver_snow(nilyr, nslyr, & ! 4) If the surface condition is inconsistent resolve for the other surface condition ! 5) If neither solution is consistent the resolve the inconsistency - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real(kind=dbl_kind), intent(inout) :: & Tsf ! snow surface temperature (C) @@ -463,8 +449,7 @@ subroutine two_stage_solver_snow(nilyr, nslyr, & ! initially cold ! solve the system for cold and snow - call picard_solver(nilyr, nslyr, & - .true., .true., & + call picard_solver(.true., .true., & Tsf, zqsn, & zqin, zSin, & zTin, zTsn, & @@ -508,8 +493,7 @@ subroutine two_stage_solver_snow(nilyr, nslyr, & zSin = zSin0 ! solve the system for melting and snow - call picard_solver(nilyr, nslyr, & - .true., .false., & + call picard_solver(.true., .false., & Tsf, zqsn, & zqin, zSin, & zTin, zTsn, & @@ -561,8 +545,7 @@ subroutine two_stage_solver_snow(nilyr, nslyr, & Tsf = c0 ! solve the system for melting and snow - call picard_solver(nilyr, nslyr, & - .true., .false., & + call picard_solver(.true., .false., & Tsf, zqsn, & zqin, zSin, & zTin, zTsn, & @@ -610,8 +593,7 @@ subroutine two_stage_solver_snow(nilyr, nslyr, & zSin = zSin0 ! solve the system for cold and snow - call picard_solver(nilyr, nslyr, & - .true., .true., & + call picard_solver(.true., .true., & Tsf, zqsn, & zqin, zSin, & zTin, zTsn, & @@ -662,8 +644,7 @@ end subroutine two_stage_solver_snow !======================================================================= - subroutine two_stage_solver_nosnow(nilyr, nslyr, & - Tsf, Tsf0, & + subroutine two_stage_solver_nosnow(Tsf, Tsf0, & zqsn, & zqin, zqin0, & zSin, zSin0, & @@ -693,10 +674,6 @@ subroutine two_stage_solver_nosnow(nilyr, nslyr, & ! 4) If the surface condition is inconsistent resolve for the other surface condition ! 5) If neither solution is consistent the resolve the inconsistency - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real(kind=dbl_kind), intent(inout) :: & Tsf ! ice surface temperature (C) @@ -772,8 +749,7 @@ subroutine two_stage_solver_nosnow(nilyr, nslyr, & ! initially cold ! solve the system for cold and no snow - call picard_solver(nilyr, nslyr, & - .false., .true., & + call picard_solver(.false., .true., & Tsf, zqsn, & zqin, zSin, & zTin, zTsn, & @@ -815,8 +791,7 @@ subroutine two_stage_solver_nosnow(nilyr, nslyr, & zSin = zSin0 ! solve the system for melt and no snow - call picard_solver(nilyr, nslyr, & - .false., .false., & + call picard_solver(.false., .false., & Tsf, zqsn, & zqin, zSin, & zTin, zTsn, & @@ -869,8 +844,7 @@ subroutine two_stage_solver_nosnow(nilyr, nslyr, & ! solve the system for melt and no snow Tsf = Tmlt - call picard_solver(nilyr, nslyr, & - .false., .false., & + call picard_solver(.false., .false., & Tsf, zqsn, & zqin, zSin, & zTin, zTsn, & @@ -917,8 +891,7 @@ subroutine two_stage_solver_nosnow(nilyr, nslyr, & zSin = zSin0 ! solve the system for cold and no snow - call picard_solver(nilyr, nslyr, & - .false., .true., & + call picard_solver(.false., .true., & Tsf, zqsn, & zqin, zSin, & zTin, zTsn, & @@ -1039,8 +1012,7 @@ end subroutine two_stage_inconsistency ! Picard/TDMA based solver !======================================================================= - subroutine prep_picard(nilyr, nslyr, & - lsnow, zqsn, & + subroutine prep_picard(lsnow, zqsn, & zqin, zSin, & hilyr, hslyr, & km, ks, & @@ -1049,10 +1021,6 @@ subroutine prep_picard(nilyr, nslyr, & dxp, kcstar, & einit) - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - logical, intent(in) :: & lsnow ! snow presence: T: has snow, F: no snow @@ -1098,17 +1066,15 @@ subroutine prep_picard(nilyr, nslyr, & endif ! lsnow ! interface distances - call calc_intercell_thickness(nilyr, nslyr, lsnow, hilyr, hslyr, dxp) + call calc_intercell_thickness(lsnow, hilyr, hslyr, dxp) if (icepack_warnings_aborted(subname)) return ! interface conductivities - call calc_intercell_conductivity(lsnow, nilyr, nslyr, & - km, ks, hilyr, hslyr, kcstar) + call calc_intercell_conductivity(lsnow, km, ks, hilyr, hslyr, kcstar) if (icepack_warnings_aborted(subname)) return ! total energy content call total_energy_content(lsnow, & - nilyr, nslyr, & zqin, zqsn, & hilyr, hslyr, & einit) @@ -1118,8 +1084,7 @@ end subroutine prep_picard !======================================================================= - subroutine picard_solver(nilyr, nslyr, & - lsnow, lcold, & + subroutine picard_solver(lsnow, lcold, & Tsf, zqsn, & zqin, zSin, & zTin, zTsn, & @@ -1141,10 +1106,6 @@ subroutine picard_solver(nilyr, nslyr, & q, dSdt, & w ) - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - logical, intent(in) :: & lsnow , & ! snow presence: T: has snow, F: no snow lcold ! surface cold: T: surface is cold, F: surface is melting @@ -1243,8 +1204,7 @@ subroutine picard_solver(nilyr, nslyr, & lconverged = .false. ! prepare quantities for picard iteration - call prep_picard(nilyr, nslyr, & - lsnow, zqsn, & + call prep_picard(lsnow, zqsn, & zqin, zSin, & hilyr, hslyr, & km, ks, & @@ -1287,7 +1247,6 @@ subroutine picard_solver(nilyr, nslyr, & ! tridiagonal solve of new temperatures call solve_heat_conduction(lsnow, lcold, & - nilyr, nslyr, & Tsf, Tbot, & zqin0, zqsn0, & phi, dt, & @@ -1301,26 +1260,22 @@ subroutine picard_solver(nilyr, nslyr, & if (icepack_warnings_aborted(subname)) return ! update brine enthalpy - call picard_updates_enthalpy(nilyr, zTin, qbr) + call picard_updates_enthalpy(zTin, qbr) if (icepack_warnings_aborted(subname)) return ! drainage fluxes call picard_drainage_fluxes(fadvheat_nit, q, & - qbr, qocn, & - nilyr) + qbr, qocn) if (icepack_warnings_aborted(subname)) return ! flushing fluxes - call picard_flushing_fluxes(nilyr, & - fadvheat_nit, w, & + call picard_flushing_fluxes(fadvheat_nit, w, & qbr, & qpond) if (icepack_warnings_aborted(subname)) return ! perform convergence check - call check_picard_convergence(nilyr, nslyr, & - lsnow, & - lconverged, & + call check_picard_convergence(lsnow, lconverged, & Tsf, Tsf_prev, & zTin, zTin_prev,& zTsn, zTsn_prev,& @@ -1345,8 +1300,7 @@ subroutine picard_solver(nilyr, nslyr, & fadvheat = fadvheat_nit ! update the picard iterants - call picard_updates(nilyr, zTin, & - Sbr, qbr) + call picard_updates(zTin, Sbr, qbr) if (icepack_warnings_aborted(subname)) return ! solve for the salinity @@ -1354,7 +1308,7 @@ subroutine picard_solver(nilyr, nslyr, & Spond, sss, & q, dSdt, & w, hilyr, & - dt, nilyr) + dt) if (icepack_warnings_aborted(subname)) return ! final surface heat flux @@ -1369,8 +1323,7 @@ subroutine picard_solver(nilyr, nslyr, & ! if not converged if (.not. lconverged) then - call picard_nonconvergence(nilyr, nslyr, & - Tsf0, Tsf, & + call picard_nonconvergence(Tsf0, Tsf, & zTsn0, zTsn, & zTin0, zTin, & zSin0, zSin, & @@ -1405,8 +1358,7 @@ end subroutine picard_solver !======================================================================= - subroutine picard_nonconvergence(nilyr, nslyr, & - Tsf0, Tsf, & + subroutine picard_nonconvergence(Tsf0, Tsf, & zTsn0, zTsn, & zTin0, zTin, & zSin0, zSin, & @@ -1430,10 +1382,6 @@ subroutine picard_nonconvergence(nilyr, nslyr, & q, dSdt, & w) - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real(kind=dbl_kind), intent(in) :: & Tsf0 , & ! snow surface temperature (C) at beginning of timestep Tsf ! snow surface temperature (C) @@ -1604,8 +1552,7 @@ end subroutine picard_nonconvergence !======================================================================= - subroutine check_picard_convergence(nilyr, nslyr, & - lsnow, & + subroutine check_picard_convergence(lsnow, & lconverged, & Tsf, Tsf_prev, & zTin, zTin_prev,& @@ -1619,10 +1566,6 @@ subroutine check_picard_convergence(nilyr, nslyr, & fcondtop, fcondbot, & fadvheat) - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - logical, intent(inout) :: & lconverged ! has Picard solver converged? @@ -1671,14 +1614,12 @@ subroutine check_picard_convergence(nilyr, nslyr, & character(len=*),parameter :: subname='(check_picard_convergence)' call picard_final(lsnow, & - nilyr, nslyr, & zqin, zqsn, & zTin, zTsn, & phi) if (icepack_warnings_aborted(subname)) return call total_energy_content(lsnow, & - nilyr, nslyr, & zqin, zqsn, & hilyr, hslyr, & efinal) @@ -1710,11 +1651,7 @@ end subroutine check_picard_convergence !======================================================================= subroutine picard_drainage_fluxes(fadvheat, q, & - qbr, qocn, & - nilyr) - - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers + qbr, qocn) real(kind=dbl_kind), intent(out) :: & fadvheat ! flow of heat to ocean due to advection (W m-2) @@ -1750,14 +1687,10 @@ end subroutine picard_drainage_fluxes !======================================================================= - subroutine picard_flushing_fluxes(nilyr, & - fadvheat, w, & + subroutine picard_flushing_fluxes(fadvheat, w, & qbr, & qpond) - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers - real(kind=dbl_kind), intent(inout) :: & fadvheat ! flow of heat to ocean due to advection (W m-2) @@ -1816,7 +1749,6 @@ end subroutine maximum_variables_changes !======================================================================= subroutine total_energy_content(lsnow, & - nilyr, nslyr, & zqin, zqsn, & hilyr, hslyr, & energy) @@ -1824,10 +1756,6 @@ subroutine total_energy_content(lsnow, & logical, intent(in) :: & lsnow ! snow presence: T: has snow, F: no snow - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real(kind=dbl_kind), dimension(:), intent(in) :: & zqin , & ! ice layer enthalpy (J m-3) zqsn ! snow layer enthalpy (J m-3) @@ -1866,14 +1794,11 @@ end subroutine total_energy_content !======================================================================= - subroutine picard_updates(nilyr, zTin, & + subroutine picard_updates(zTin, & Sbr, qbr) ! update brine salinity and liquid fraction based on new temperatures - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers - real(kind=dbl_kind), dimension(:), intent(in) :: & zTin ! ice layer temperature (C) @@ -1897,13 +1822,10 @@ end subroutine picard_updates !======================================================================= - subroutine picard_updates_enthalpy(nilyr, zTin, qbr) + subroutine picard_updates_enthalpy(zTin, qbr) ! update brine salinity and liquid fraction based on new temperatures - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers - real(kind=dbl_kind), dimension(:), intent(in) :: & zTin ! ice layer temperature (C) @@ -1926,15 +1848,10 @@ end subroutine picard_updates_enthalpy !======================================================================= subroutine picard_final(lsnow, & - nilyr, nslyr, & zqin, zqsn, & zTin, zTsn, & phi) - integer (kind=int_kind), intent(in) :: & - nilyr, & ! number of ice layers - nslyr ! number of snow layers - logical, intent(in) :: & lsnow ! snow presence: T: has snow, F: no snow @@ -1968,11 +1885,7 @@ end subroutine picard_final !======================================================================= - subroutine calc_intercell_thickness(nilyr, nslyr, lsnow, hilyr, hslyr, dxp) - - integer (kind=int_kind), intent(in) :: & - nilyr, & ! number of ice layers - nslyr ! number of snow layers + subroutine calc_intercell_thickness(lsnow, hilyr, hslyr, dxp) logical, intent(in) :: & lsnow ! snow presence: T: has snow, F: no snow @@ -2034,15 +1947,10 @@ end subroutine calc_intercell_thickness !======================================================================= subroutine calc_intercell_conductivity(lsnow, & - nilyr, nslyr, & km, ks, & hilyr, hslyr, & kcstar) - integer (kind=int_kind), intent(in) :: & - nilyr, & ! number of ice layers - nslyr ! number of snow layers - logical, intent(in) :: & lsnow ! snow presence: T: has snow, F: no snow @@ -2115,7 +2023,6 @@ end subroutine calc_intercell_conductivity !======================================================================= subroutine solve_heat_conduction(lsnow, lcold, & - nilyr, nslyr, & Tsf, Tbot, & zqin0, zqsn0, & phi, dt, & @@ -2131,10 +2038,6 @@ subroutine solve_heat_conduction(lsnow, lcold, & lsnow , & ! snow presence: T: has snow, F: no snow lcold ! surface cold: T: surface is cold, F: surface is melting - integer (kind=int_kind), intent(in) :: & - nilyr, & ! number of ice layers - nslyr ! number of snow layers - real(kind=dbl_kind), dimension(:), intent(in) :: & zqin0 , & ! ice layer enthalpy (J m-3) at beggining of timestep Iswabs , & ! SW radiation absorbed in ice layers (W m-2) @@ -2187,7 +2090,6 @@ subroutine solve_heat_conduction(lsnow, lcold, & if (lcold) then call matrix_elements_snow_cold(Ap, As, An, b, nyn, & - nilyr, nslyr, & Tsf, Tbot, & zqin0, zqsn0, & qpond, qocn, & @@ -2203,7 +2105,6 @@ subroutine solve_heat_conduction(lsnow, lcold, & else ! lcold call matrix_elements_snow_melt(Ap, As, An, b, nyn, & - nilyr, nslyr, & Tsf, Tbot, & zqin0, zqsn0, & qpond, qocn, & @@ -2222,7 +2123,6 @@ subroutine solve_heat_conduction(lsnow, lcold, & if (lcold) then call matrix_elements_nosnow_cold(Ap, As, An, b, nyn, & - nilyr, & Tsf, Tbot, & zqin0, & qpond, qocn, & @@ -2238,7 +2138,6 @@ subroutine solve_heat_conduction(lsnow, lcold, & else ! lcold call matrix_elements_nosnow_melt(Ap, As, An, b, nyn, & - nilyr, & Tsf, Tbot, & zqin0, & qpond, qocn, & @@ -2255,12 +2154,11 @@ subroutine solve_heat_conduction(lsnow, lcold, & endif ! lsnow ! tridiag to get new temperatures - call tdma_solve_sparse(nilyr, nslyr, & + call tdma_solve_sparse( & An(1:nyn), Ap(1:nyn), As(1:nyn), b(1:nyn), T(1:nyn), nyn) if (icepack_warnings_aborted(subname)) return call update_temperatures(lsnow, lcold, & - nilyr, nslyr, & T, Tsf, & zTin, zTsn) if (icepack_warnings_aborted(subname)) return @@ -2270,7 +2168,6 @@ end subroutine solve_heat_conduction !======================================================================= subroutine update_temperatures(lsnow, lcold, & - nilyr, nslyr, & T, Tsf, & zTin, zTsn) @@ -2278,10 +2175,6 @@ subroutine update_temperatures(lsnow, lcold, & lsnow , & ! snow presence: T: has snow, F: no snow lcold ! surface cold: T: surface is cold, F: surface is melting - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real(kind=dbl_kind), dimension(:), intent(in) :: & T ! matrix solution vector @@ -2355,7 +2248,6 @@ end subroutine update_temperatures !======================================================================= subroutine matrix_elements_nosnow_melt(Ap, As, An, b, nyn, & - nilyr, & Tsf, Tbot, & zqin0, & qpond, qocn, & @@ -2375,9 +2267,6 @@ subroutine matrix_elements_nosnow_melt(Ap, As, An, b, nyn, & integer, intent(out) :: & nyn ! matrix size - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers - real(kind=dbl_kind), dimension(:), intent(in) :: & zqin0 , & ! ice layer enthalpy (J m-3) at beggining of timestep Iswabs , & ! SW radiation absorbed in ice layers (W m-2) @@ -2462,7 +2351,6 @@ end subroutine matrix_elements_nosnow_melt !======================================================================= subroutine matrix_elements_nosnow_cold(Ap, As, An, b, nyn, & - nilyr, & Tsf, Tbot, & zqin0, & qpond, qocn, & @@ -2483,9 +2371,6 @@ subroutine matrix_elements_nosnow_cold(Ap, As, An, b, nyn, & integer, intent(out) :: & nyn ! matrix size - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers - real(kind=dbl_kind), dimension(:), intent(in) :: & zqin0 , & ! ice layer enthalpy (J m-3) at beggining of timestep Iswabs , & ! SW radiation absorbed in ice layers (W m-2) @@ -2578,7 +2463,6 @@ end subroutine matrix_elements_nosnow_cold !======================================================================= subroutine matrix_elements_snow_melt(Ap, As, An, b, nyn, & - nilyr, nslyr, & Tsf, Tbot, & zqin0, zqsn0, & qpond, qocn, & @@ -2598,10 +2482,6 @@ subroutine matrix_elements_snow_melt(Ap, As, An, b, nyn, & integer, intent(out) :: & nyn ! matrix size - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real(kind=dbl_kind), dimension(:), intent(in) :: & zqin0 , & ! ice layer enthalpy (J m-3) at beggining of timestep Iswabs , & ! SW radiation absorbed in ice layers (W m-2) @@ -2714,7 +2594,6 @@ end subroutine matrix_elements_snow_melt !======================================================================= subroutine matrix_elements_snow_cold(Ap, As, An, b, nyn, & - nilyr, nslyr, & Tsf, Tbot, & zqin0, zqsn0, & qpond, qocn, & @@ -2735,10 +2614,6 @@ subroutine matrix_elements_snow_cold(Ap, As, An, b, nyn, & integer, intent(out) :: & nyn ! matrix size - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real(kind=dbl_kind), dimension(:), intent(in) :: & zqin0 , & ! ice layer enthalpy (J m-3) at beggining of timestep Iswabs , & ! SW radiation absorbed in ice layers (W m-2) @@ -2864,14 +2739,11 @@ end subroutine matrix_elements_snow_cold !======================================================================= - subroutine solve_salinity(zSin, Sbr, & + subroutine solve_salinity(zSin, Sbr, & Spond, sss, & q, dSdt, & w, hilyr, & - dt, nilyr) - - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers + dt) real(kind=dbl_kind), dimension(:), intent(inout) :: & zSin ! ice layer bulk salinity (ppt) @@ -2949,14 +2821,10 @@ end subroutine solve_salinity !======================================================================= - subroutine tdma_solve_sparse(nilyr, nslyr, a, b, c, d, x, n) + subroutine tdma_solve_sparse(a, b, c, d, x, n) ! perform a tri-diagonal solve with TDMA using a sparse tridiagoinal matrix - integer (kind=int_kind), intent(in) :: & - nilyr, & ! number of ice layers - nslyr ! number of snow layers - integer(kind=int_kind), intent(in) :: & n ! matrix size @@ -3023,7 +2891,7 @@ end function permeability !======================================================================= - subroutine explicit_flow_velocities(nilyr, zSin, & + subroutine explicit_flow_velocities(zSin, & zTin, Tsf, & Tbot, q, & dSdt, Sbr, & @@ -3034,9 +2902,6 @@ subroutine explicit_flow_velocities(nilyr, zSin, & ! calculate the rapid gravity drainage mode Darcy velocity and the ! slow mode drainage rate - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers - real(kind=dbl_kind), dimension(:), intent(in) :: & zSin, & ! ice layer bulk salinity (ppt) zTin ! ice layer temperature (C) @@ -3197,8 +3062,7 @@ end subroutine explicit_flow_velocities ! Flushing !======================================================================= - subroutine flushing_velocity(zTin, & - phi, nilyr, & + subroutine flushing_velocity(zTin, phi, & hin, hsn, & hilyr, & hpond, apond, & @@ -3206,9 +3070,6 @@ subroutine flushing_velocity(zTin, & ! calculate the vertical flushing Darcy velocity (positive downward) - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers - real(kind=dbl_kind), dimension(:), intent(in) :: & zTin , & ! ice layer temperature (C) phi ! ice layer liquid fraction @@ -3353,7 +3214,6 @@ end subroutine flush_pond !======================================================================= subroutine flood_ice(hsn, hin, & - nslyr, nilyr, & hslyr, hilyr, & zqsn, zqin, & phi, dt, & @@ -3365,10 +3225,6 @@ subroutine flood_ice(hsn, hin, & ! given upwards flushing brine flow calculate amount of snow ice and ! convert snow to ice with appropriate properties - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real(kind=dbl_kind), intent(in) :: & dt , & ! time step (s) hsn , & ! snow thickness (m) @@ -3476,7 +3332,7 @@ subroutine flood_ice(hsn, hin, & dh = max(min(dh,hsn),c0) ! enthalpy of snow that becomes snow-ice - call enthalpy_snow_snowice(nslyr, dh, hsn, zqsn, zqsn_snowice) + call enthalpy_snow_snowice(dh, hsn, zqsn, zqsn_snowice) if (icepack_warnings_aborted(subname)) return ! change thicknesses @@ -3491,23 +3347,23 @@ subroutine flood_ice(hsn, hin, & zqin_snowice = phi_snowice * qocn + zqsn_snowice ! change snow properties - call update_vertical_tracers_snow(nslyr, zqsn, hslyr, hslyr2) + call update_vertical_tracers_snow(zqsn, hslyr, hslyr2) if (icepack_warnings_aborted(subname)) return if (snwgrain .and. hslyr2 > puny) then - call update_vertical_tracers_snow(nslyr, smice, hslyr, hslyr2) - call update_vertical_tracers_snow(nslyr, smliq, hslyr, hslyr2) + call update_vertical_tracers_snow(smice, hslyr, hslyr2) + call update_vertical_tracers_snow(smliq, hslyr, hslyr2) if (icepack_warnings_aborted(subname)) return endif ! change ice properties - call update_vertical_tracers_ice(nilyr, zqin, hilyr, hilyr2, & + call update_vertical_tracers_ice(zqin, hilyr, hilyr2, & hin, hin2, zqin_snowice) if (icepack_warnings_aborted(subname)) return - call update_vertical_tracers_ice(nilyr, zSin, hilyr, hilyr2, & + call update_vertical_tracers_ice(zSin, hilyr, hilyr2, & hin, hin2, zSin_snowice) if (icepack_warnings_aborted(subname)) return - call update_vertical_tracers_ice(nilyr, phi, hilyr, hilyr2, & + call update_vertical_tracers_ice(phi, hilyr, hilyr2, & hin, hin2, phi_snowice) if (icepack_warnings_aborted(subname)) return @@ -3532,13 +3388,10 @@ end subroutine flood_ice !======================================================================= - subroutine enthalpy_snow_snowice(nslyr, dh, hsn, zqsn, zqsn_snowice) + subroutine enthalpy_snow_snowice(dh, hsn, zqsn, zqsn_snowice) ! determine enthalpy of the snow being converted to snow ice - integer (kind=int_kind), intent(in) :: & - nslyr ! number of snow layers - real(kind=dbl_kind), intent(in) :: & dh , & ! thickness of new snowice formation (m) hsn ! initial snow thickness @@ -3580,13 +3433,10 @@ end subroutine enthalpy_snow_snowice !======================================================================= - subroutine update_vertical_tracers_snow(nslyr, trc, hlyr1, hlyr2) + subroutine update_vertical_tracers_snow(trc, hlyr1, hlyr2) ! given some snow ice formation regrid snow layers - integer (kind=int_kind), intent(in) :: & - nslyr ! number of snow layers - real(kind=dbl_kind), dimension(:), intent(inout) :: & trc ! vertical tracer @@ -3648,14 +3498,11 @@ end subroutine update_vertical_tracers_snow !======================================================================= - subroutine update_vertical_tracers_ice(nilyr, trc, hlyr1, hlyr2, & + subroutine update_vertical_tracers_ice(trc, hlyr1, hlyr2, & h1, h2, trc0) ! given some snow ice formation regrid ice layers - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers - real(kind=dbl_kind), dimension(:), intent(inout) :: & trc ! vertical tracer diff --git a/columnphysics/icepack_therm_shared.F90 b/columnphysics/icepack_therm_shared.F90 index eed1677a9..8f566bb9c 100644 --- a/columnphysics/icepack_therm_shared.F90 +++ b/columnphysics/icepack_therm_shared.F90 @@ -14,6 +14,7 @@ module icepack_therm_shared use icepack_parameters, only: saltmax, min_salin, depressT use icepack_parameters, only: ktherm, tfrz_option use icepack_parameters, only: calc_Tsfc + use icepack_tracers, only: nilyr, nslyr use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted @@ -215,10 +216,7 @@ end subroutine dsurface_heat_flux_dTsf ! authors: C. M. Bitz, UW ! William H. Lipscomb, LANL - subroutine icepack_init_thermo(nilyr, sprofile) - - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers + subroutine icepack_init_thermo(sprofile) real (kind=dbl_kind), dimension(:), intent(out) :: & sprofile ! vertical salinity profile @@ -296,13 +294,8 @@ end function icepack_salinity_profile subroutine icepack_init_trcr(Tair, Tf, & Sprofile, Tprofile, & Tsfc, & - nilyr, nslyr, & qin, qsn) - integer (kind=int_kind), intent(in) :: & - nilyr, & ! number of ice layers - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & Tair, & ! air temperature (K) Tf ! freezing temperature (C) diff --git a/columnphysics/icepack_therm_vertical.F90 b/columnphysics/icepack_therm_vertical.F90 index 233e38546..6dda193af 100644 --- a/columnphysics/icepack_therm_vertical.F90 +++ b/columnphysics/icepack_therm_vertical.F90 @@ -30,6 +30,7 @@ module icepack_therm_vertical use icepack_parameters, only: saltflux_option, congel_freeze use icepack_parameters, only: icepack_chkoptargflag + use icepack_tracers, only: ncat, nilyr, nslyr use icepack_tracers, only: tr_iage, tr_FY, tr_aero, tr_pond, tr_fsd, tr_iso use icepack_tracers, only: tr_pond_lvl, tr_pond_topo use icepack_tracers, only: n_aero, n_iso @@ -75,8 +76,7 @@ module icepack_therm_vertical ! authors: William H. Lipscomb, LANL ! C. M. Bitz, UW - subroutine thermo_vertical (nilyr, nslyr, & - dt, aicen, & + subroutine thermo_vertical (dt, aicen, & vicen, vsnon, & Tsf, zSin, & zqin, zqsn, & @@ -106,10 +106,6 @@ subroutine thermo_vertical (nilyr, nslyr, & yday, dsnow, & prescribed_ice) - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & dt , & ! time step frain ! rainfall rate (kg/m2/s) @@ -279,8 +275,7 @@ subroutine thermo_vertical (nilyr, nslyr, & ! Compute variables needed for vertical thermo calculation !----------------------------------------------------------------- - call init_vertical_profile (nilyr, nslyr, & - aicen, & + call init_vertical_profile (aicen, & vicen, vsnon, & hin, hilyr, & hsn, hslyr, & @@ -310,7 +305,6 @@ subroutine thermo_vertical (nilyr, nslyr, & if (ktherm == 2) then call temperature_changes_salinity(dt, & - nilyr, nslyr, & rhoa, flw, & potT, Qa, & shcoef, lhcoef, & @@ -333,7 +327,6 @@ subroutine thermo_vertical (nilyr, nslyr, & else ! ktherm call temperature_changes(dt, & - nilyr, nslyr, & rhoa, flw, & potT, Qa, & shcoef, lhcoef, & @@ -385,8 +378,7 @@ subroutine thermo_vertical (nilyr, nslyr, & ! Repartition ice into equal-thickness layers, conserving energy. !----------------------------------------------------------------- - call thickness_changes(nilyr, nslyr, & - dt, yday, & + call thickness_changes(dt, yday, & efinal, & hin, hilyr, & hsn, hslyr, & @@ -464,8 +456,7 @@ subroutine thermo_vertical (nilyr, nslyr, & ! state variables. !----------------------------------------------------------------- - call update_state_vthermo(nilyr, nslyr, & - Tbot, Tsf, & + call update_state_vthermo(Tbot, Tsf, & hin, hsn, & zqin, zSin, & zqsn, & @@ -484,8 +475,7 @@ end subroutine thermo_vertical ! William H. Lipscomb, LANL ! Elizabeth C. Hunke, LANL - subroutine frzmlt_bottom_lateral (dt, ncat, & - nilyr, nslyr, & + subroutine frzmlt_bottom_lateral (dt, & aice, frzmlt, & vicen, vsnon, & qicen, qsnon, & @@ -497,11 +487,6 @@ subroutine frzmlt_bottom_lateral (dt, ncat, & rside, Cdn_ocn, & fside, wlat) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -662,8 +647,7 @@ end subroutine frzmlt_bottom_lateral ! authors William H. Lipscomb, LANL ! C. M. Bitz, UW - subroutine init_vertical_profile(nilyr, nslyr, & - aicen, vicen, & + subroutine init_vertical_profile(aicen, vicen, & vsnon, & hin, hilyr, & hsn, hslyr, & @@ -672,10 +656,6 @@ subroutine init_vertical_profile(nilyr, nslyr, & zSin, & einit ) - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & aicen , & ! concentration of ice vicen , & ! volume per unit area of ice (m) @@ -996,8 +976,7 @@ end subroutine init_vertical_profile ! authors William H. Lipscomb, LANL ! C. M. Bitz, UW - subroutine thickness_changes (nilyr, nslyr, & - dt, yday, & + subroutine thickness_changes (dt, yday, & efinal, & hin, hilyr, & hsn, hslyr, & @@ -1019,10 +998,6 @@ subroutine thickness_changes (nilyr, nslyr, & sst, & dsnow, rsnw) - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & dt , & ! time step yday ! day of the year @@ -1266,15 +1241,17 @@ subroutine thickness_changes (nilyr, nslyr, & qbotp = qbotm - qbotw dhi = ebot_gro / qbotp ! dhi > 0 hstot = dzi(nilyr)*zSin(nilyr) + dhi*sss*phi_i_mushy + hqtot = dzi(nilyr)*zqin(nilyr) + dhi*qbotm + emlt_ocn = emlt_ocn - qbotw * dhi else ! two-step qbotm = icepack_enthalpy_mush(Tbot, sss) qbotp = -Lfresh * rhoi * (c1 - phi_i_mushy) qbotw = qbotm - qbotp dhi = ebot_gro / qbotp ! dhi > 0 hstot = dzi(nilyr)*zSin(nilyr) + dhi*sss + hqtot = dzi(nilyr)*zqin(nilyr) + dhi*qbotm + emlt_ocn = emlt_ocn - qbotw * dhi endif - hqtot = dzi(nilyr)*zqin(nilyr) + dhi*qbotm - emlt_ocn = emlt_ocn - qbotw * dhi else @@ -1533,7 +1510,7 @@ subroutine thickness_changes (nilyr, nslyr, & !------------------------------------------------------------------- if (ktherm /= 2) & - call freeboard (nslyr, snoice, & + call freeboard (snoice, & hin, hsn, & zqin, zqsn, & dzi, dzs, & @@ -1768,17 +1745,13 @@ end subroutine thickness_changes ! authors William H. Lipscomb, LANL ! Elizabeth C. Hunke, LANL - subroutine freeboard (nslyr, & - snoice, & + subroutine freeboard (snoice, & hin, hsn, & zqin, zqsn, & dzi, dzs, & dsnow, & massice, massliq) - integer (kind=int_kind), intent(in) :: & - nslyr ! number of snow layers - ! real (kind=dbl_kind), intent(in) :: & ! dt ! time step @@ -2011,18 +1984,13 @@ end subroutine conservation_check_vthermo ! C. M. Bitz, UW ! Elizabeth C. Hunke, LANL - subroutine update_state_vthermo(nilyr, nslyr, & - Tf, Tsf, & + subroutine update_state_vthermo(Tf, Tsf, & hin, hsn, & zqin, zSin, & zqsn, & aicen, vicen, & vsnon) - integer (kind=int_kind), intent(in) :: & - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & Tf ! freezing temperature (C) @@ -2082,7 +2050,7 @@ end subroutine update_state_vthermo ! authors: William H. Lipscomb, LANL ! Elizabeth C. Hunke, LANL - subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + subroutine icepack_step_therm1(dt, & aicen_init , & vicen_init , vsnon_init , & aice , aicen , & @@ -2171,11 +2139,6 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & yday , prescribed_ice, & zlvs) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & dt , & ! time step uvel , & ! x-component of velocity (m/s) @@ -2524,7 +2487,7 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & hdraft , hridge , & distrdg , hkeel , & dkeel , lfloe , & - dfloe , ncat) + dfloe) if (icepack_warnings_aborted(subname)) return endif @@ -2534,8 +2497,7 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & ! Compute lateral and bottom heat fluxes. !----------------------------------------------------------------- - call frzmlt_bottom_lateral (dt, ncat, & - nilyr, nslyr, & + call frzmlt_bottom_lateral (dt, & aice, frzmlt, & vicen, vsnon, & zqin, zqsn, & @@ -2654,8 +2616,7 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & smliq(:) = smliqn(:,n) endif - call thermo_vertical(nilyr=nilyr, nslyr=nslyr, & - dt=dt, aicen=aicen (n), & + call thermo_vertical(dt=dt, aicen=aicen (n), & vicen=vicen (n), vsnon=vsnon (n), & Tsf=Tsfc (n), zSin=zSin (:,n), & zqin=zqin (:,n), zqsn=zqsn (:,n), & @@ -2709,7 +2670,6 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & if (tr_aero) then call update_aerosol (dt, & - nilyr, nslyr, n_aero, & melttn (n), meltsn (n), & meltbn (n), congeln (n), & snoicen (n), fsnow, & @@ -2724,7 +2684,6 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & if (tr_iso) then call update_isotope (dt = dt, & - nilyr = nilyr, nslyr = nslyr, & meltt = melttn(n),melts = meltsn(n), & meltb = meltbn(n),congel=congeln(n), & snoice=snoicen(n),evap=evapn, & @@ -2749,8 +2708,7 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & endif ! aicen_init if (snwgrain) then - call drain_snow (nslyr = nslyr, & - vsnon = vsnon(n), & + call drain_snow (vsnon = vsnon(n), & aicen = aicen(n), & massice = massicen(:,n), & massliq = massliqn(:,n), & @@ -2920,12 +2878,12 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & !----------------------------------------------------------------- !call ice_timer_start(timer_ponds) if (tr_pond_topo) then - call compute_ponds_topo(dt, ncat, nilyr, & + call compute_ponds_topo(dt, & ktherm, & aice, aicen, & vice, vicen, & vsno, vsnon, & - meltt, & + meltt, & fsurf, fpond, & Tsfc, Tf, & zqin, zSin, & diff --git a/columnphysics/icepack_tracers.F90 b/columnphysics/icepack_tracers.F90 index 8414e0c98..fc3fafa8b 100644 --- a/columnphysics/icepack_tracers.F90 +++ b/columnphysics/icepack_tracers.F90 @@ -31,15 +31,14 @@ module icepack_tracers !----------------------------------------------------------------- integer (kind=int_kind), parameter, public :: & max_iso = 3 , & ! maximum number of isotopes + nmodal1 = 10 , & ! dimension for modal aerosol radiation parameters + nmodal2 = 8 , & ! dimension for modal aerosol radiation parameters max_algae = 3 , & ! maximum number of algal types max_dic = 1 , & ! maximum number of dissolved inorganic carbon types max_doc = 3 , & ! maximum number of dissolved organic carbon types max_don = 1 , & ! maximum number of dissolved organic nitrogen types max_fe = 2 , & ! maximum number of iron types - nmodal1 = 10 , & ! dimension for modal aerosol radiation parameters - nmodal2 = 8 , & ! dimension for modal aerosol radiation parameters max_aero = 6 , & ! maximum number of aerosols - max_nbtrcr = max_algae*2 & ! algal nitrogen and chlorophyll + max_dic & ! dissolved inorganic carbon + max_doc & ! dissolved organic carbon @@ -1198,15 +1197,12 @@ end subroutine icepack_write_tracer_sizes ! Compute tracer fields. ! Given atrcrn = aicen*trcrn (or vicen*trcrn, vsnon*trcrn), compute trcrn. - subroutine icepack_compute_tracers (ntrcr, trcr_depend, & + subroutine icepack_compute_tracers (trcr_depend, & atrcrn, aicen, & vicen, vsnon, & trcr_base, n_trcr_strata, & nt_strata, trcrn, Tf) - integer (kind=int_kind), intent(in) :: & - ntrcr ! number of tracers in use - integer (kind=int_kind), dimension (ntrcr), intent(in) :: & trcr_depend, & ! = 0 for aicen tracers, 1 for vicen, 2 for vsnon n_trcr_strata ! number of underlying tracer layers diff --git a/columnphysics/icepack_warnings.F90 b/columnphysics/icepack_warnings.F90 index 459f2dc80..76858e9a1 100644 --- a/columnphysics/icepack_warnings.F90 +++ b/columnphysics/icepack_warnings.F90 @@ -1,8 +1,20 @@ module icepack_warnings - use icepack_kinds +! Provides a logging and abort package for Icepack. +! Icepack has no idea about MPI, OpenMP, or IO. +! Store error message and provide methods for the driver +! to write these messages to a Fortran unit number. +! Needs to be thread safe. This could be called within +! a threaded or non-threaded region or both. Need to make +! sure multiple threads are not adding to the warnings +! buffer at the same time. Also need to make sure warnings +! buffers are not added at the same time messages are +! cleared by a different thread. Use multiple critical +! regions using the same ID to allow threads to block +! each other during multiple operations. + use icepack_kinds implicit none private @@ -10,7 +22,7 @@ module icepack_warnings ! warning messages character(len=char_len_long), dimension(:), allocatable :: warnings integer :: nWarnings = 0 - integer, parameter :: nWarningsBuffer = 10 ! incremental number of messages + integer :: nWarningsBuffer = 10 ! incremental number of messages ! abort flag, accessed via icepack_warnings_setabort and icepack_warnings_aborted logical :: warning_abort = .false. @@ -30,6 +42,10 @@ module icepack_warnings private :: & icepack_warnings_getone +! variables are shared by default +! have warnstr be private +!$OMP THREADPRIVATE(warnstr) + !======================================================================= contains @@ -68,9 +84,15 @@ subroutine icepack_warnings_setabort(abortflag,file,line) if (abortflag) then write(warnstr,*) subname,abortflag - if (present(file)) write(warnstr,*) trim(warnstr)//' :file '//trim(file) - if (present(line)) write(warnstr,*) trim(warnstr)//' :line ',line call icepack_warnings_add(warnstr) + if (present(file)) then + write(warnstr,*) trim(warnstr)//' :file '//trim(file) + call icepack_warnings_add(warnstr) + endif + if (present(line)) then + write(warnstr,*) trim(warnstr)//' :line ',line + call icepack_warnings_add(warnstr) + endif endif warning_abort = abortflag @@ -127,14 +149,9 @@ subroutine icepack_warnings_print(iounit) integer :: iWarning character(len=*),parameter :: subname='(icepack_warnings_print)' -! tcraig -! this code intermittenly aborts on recursive IO errors with intel -! not sure if it's OMP or something else causing this -!$OMP MASTER do iWarning = 1, nWarnings write(iounit,*) trim(icepack_warnings_getone(iWarning)) enddo -!$OMP END MASTER end subroutine icepack_warnings_print @@ -150,10 +167,12 @@ subroutine icepack_warnings_flush(iounit) character(len=*),parameter :: subname='(icepack_warnings_flush)' +!$OMP CRITICAL (omp_warnings) if (nWarnings > 0) then call icepack_warnings_print(iounit) endif call icepack_warnings_clear() +!$OMP END CRITICAL (omp_warnings) end subroutine icepack_warnings_flush @@ -171,7 +190,7 @@ subroutine icepack_warnings_add(warning) iWarning ! warning index character(len=*),parameter :: subname='(icepack_warnings_add)' -!$OMP CRITICAL (omp_warnings_add) +!$OMP CRITICAL (omp_warnings) ! check if warnings array is not allocated if (.not. allocated(warnings)) then @@ -181,7 +200,6 @@ subroutine icepack_warnings_add(warning) ! set initial number of nWarnings nWarnings = 0 - ! already allocated else ! find the size of the warnings array at the start @@ -210,16 +228,18 @@ subroutine icepack_warnings_add(warning) ! deallocate the temporary storage deallocate(warningsTmp) + ! increase nWarningsBuffer for next reallocation + nWarningsBuffer = nWarningsBuffer * 2 endif endif ! increase warning number nWarnings = nWarnings + 1 -!$OMP END CRITICAL (omp_warnings_add) ! add the new warning warnings(nWarnings) = trim(warning) +!$OMP END CRITICAL (omp_warnings) end subroutine icepack_warnings_add diff --git a/columnphysics/icepack_wavefracspec.F90 b/columnphysics/icepack_wavefracspec.F90 index 540ab6722..1beb7a234 100644 --- a/columnphysics/icepack_wavefracspec.F90 +++ b/columnphysics/icepack_wavefracspec.F90 @@ -31,7 +31,7 @@ module icepack_wavefracspec use icepack_kinds use icepack_parameters, only: p01, p5, c0, c1, c2, c3, c4, c10 use icepack_parameters, only: bignum, puny, gravit, pi - use icepack_tracers, only: nt_fsd + use icepack_tracers, only: nt_fsd, ncat, nfsd use icepack_warnings, only: warnstr, icepack_warnings_add, icepack_warnings_aborted use icepack_fsd @@ -128,12 +128,9 @@ end subroutine icepack_init_wave ! ! authors: 2017 Lettie Roach, NIWA/VUW ! - function get_dafsd_wave(nfsd, afsd_init, fracture_hist, frac) & + function get_dafsd_wave(afsd_init, fracture_hist, frac) & result(d_afsd) - integer (kind=int_kind), intent(in) :: & - nfsd ! number of floe size categories - real (kind=dbl_kind), dimension (:), intent(in) :: & afsd_init, fracture_hist @@ -183,8 +180,7 @@ end function get_dafsd_wave ! authors: 2018 Lettie Roach, NIWA/VUW ! subroutine icepack_step_wavefracture(wave_spec_type, & - dt, ncat, nfsd, & - nfreq, & + dt, nfreq, & aice, vice, aicen, & floe_rad_l, floe_rad_c, & wave_spectrum, wavefreq, dwavefreq, & @@ -192,12 +188,10 @@ subroutine icepack_step_wavefracture(wave_spec_type, & character (len=char_len), intent(in) :: & - wave_spec_type ! type of wave spectrum forcing + wave_spec_type ! type of wave spectrum forcing integer (kind=int_kind), intent(in) :: & - nfreq, & ! number of wave frequency categories - ncat, & ! number of thickness categories - nfsd ! number of floe size categories + nfreq ! number of wave frequency categories real (kind=dbl_kind), intent(in) :: & dt, & ! time step @@ -269,7 +263,7 @@ subroutine icepack_step_wavefracture(wave_spec_type, & hbar = vice / aice ! calculate fracture histogram - call wave_frac(nfsd, nfreq, wave_spec_type, & + call wave_frac(nfreq, wave_spec_type, & floe_rad_l, floe_rad_c, & wavefreq, dwavefreq, & hbar, wave_spectrum, fracture_hist) @@ -279,7 +273,7 @@ subroutine icepack_step_wavefracture(wave_spec_type, & ! if fracture occurs if (MAXVAL(fracture_hist) > puny) then ! protect against small numerical errors - call icepack_cleanup_fsd (ncat, nfsd, trcrn(nt_fsd:nt_fsd+nfsd-1,:) ) + call icepack_cleanup_fsd (trcrn(nt_fsd:nt_fsd+nfsd-1,:) ) if (icepack_warnings_aborted(subname)) return do n = 1, ncat @@ -312,7 +306,7 @@ subroutine icepack_step_wavefracture(wave_spec_type, & if (afsd_tmp(1).ge.c1-puny) EXIT ! calculate d_afsd using current afstd - d_afsd_tmp = get_dafsd_wave(nfsd, afsd_tmp, fracture_hist, frac) + d_afsd_tmp = get_dafsd_wave(afsd_tmp, fracture_hist, frac) ! check in case wave fracture struggles to converge if (nsubt>100) then @@ -322,7 +316,7 @@ subroutine icepack_step_wavefracture(wave_spec_type, & endif ! required timestep - subdt = get_subdt_fsd(nfsd, afsd_tmp, d_afsd_tmp) + subdt = get_subdt_fsd(afsd_tmp, d_afsd_tmp) subdt = MIN(subdt, dt) ! update afsd @@ -367,7 +361,7 @@ subroutine icepack_step_wavefracture(wave_spec_type, & ! update trcrn trcrn(nt_fsd:nt_fsd+nfsd-1,n) = afsd_tmp/SUM(afsd_tmp) - call icepack_cleanup_fsd (ncat, nfsd, trcrn(nt_fsd:nt_fsd+nfsd-1,:) ) + call icepack_cleanup_fsd (trcrn(nt_fsd:nt_fsd+nfsd-1,:) ) if (icepack_warnings_aborted(subname)) return ! for diagnostics @@ -398,13 +392,12 @@ end subroutine icepack_step_wavefracture ! ! authors: 2018 Lettie Roach, NIWA/VUW - subroutine wave_frac(nfsd, nfreq, wave_spec_type, & + subroutine wave_frac(nfreq, wave_spec_type, & floe_rad_l, floe_rad_c, & wavefreq, dwavefreq, & hbar, spec_efreq, frac_local) integer (kind=int_kind), intent(in) :: & - nfsd, & ! number of floe size categories nfreq ! number of wave frequency categories character (len=char_len), intent(in) :: & diff --git a/columnphysics/icepack_zbgc.F90 b/columnphysics/icepack_zbgc.F90 index 928b4ca65..1cb7a6c34 100644 --- a/columnphysics/icepack_zbgc.F90 +++ b/columnphysics/icepack_zbgc.F90 @@ -9,24 +9,42 @@ module icepack_zbgc use icepack_kinds - use icepack_parameters, only: c0, c1, c2, p001, p1, p5, puny - use icepack_parameters, only: depressT, rhosi, min_salin, salt_loss - use icepack_parameters, only: fr_resp, algal_vel, R_dFe2dust, dustFe_sol, T_max - use icepack_parameters, only: op_dep_min, fr_graze_s, fr_graze_e, fr_mort2min, fr_dFe - use icepack_parameters, only: k_nitrif, t_iron_conv, max_loss, max_dfe_doc1 - use icepack_parameters, only: fr_resp_s, y_sk_DMS, t_sk_conv, t_sk_ox - use icepack_parameters, only: scale_bgc, ktherm, skl_bgc - use icepack_parameters, only: z_tracers, fsal, conserv_check - - use icepack_tracers, only: nt_sice, bio_index + use icepack_parameters + + !use icepack_parameters, only: c0, c1, c2, p001, p1, p5, puny + !use icepack_parameters, only: depressT, rhosi, min_salin, salt_loss + !use icepack_parameters, only: fr_resp, algal_vel, R_dFe2dust, dustFe_sol, T_max + !use icepack_parameters, only: op_dep_min, fr_graze_s, fr_graze_e, fr_mort2min, fr_dFe + !use icepack_parameters, only: k_nitrif, t_iron_conv, max_loss, max_dfe_doc1 + !use icepack_parameters, only: fr_resp_s, y_sk_DMS, t_sk_conv, t_sk_ox + !use icepack_parameters, only: scale_bgc, ktherm, skl_bgc + !use icepack_parameters, only: z_tracers, fsal, conserv_check + + use icepack_tracers, only: max_algae, max_dic, max_doc, max_don, max_fe + use icepack_tracers, only: max_aero, max_nbtrcr + use icepack_tracers, only: ncat, nilyr, nslyr, nblyr, nbtrcr, ntrcr, ntrcr_o use icepack_tracers, only: tr_brine, nt_fbri, nt_qice, nt_Tsfc - use icepack_tracers, only: nt_zbgc_frac - use icepack_tracers, only: bio_index_o, bio_index + use icepack_tracers, only: tr_zaero, tr_bgc_Nit, tr_bgc_N + use icepack_tracers, only: tr_bgc_DON, tr_bgc_C, tr_bgc_chl + use icepack_tracers, only: tr_bgc_Am, tr_bgc_Sil, tr_bgc_DMS + use icepack_tracers, only: tr_bgc_Fe, tr_bgc_hum, tr_bgc_PON + use icepack_tracers, only: nt_bgc_Nit, nlt_bgc_Nit + use icepack_tracers, only: nt_bgc_N, nlt_bgc_N, nt_bgc_Am, nlt_bgc_Am + use icepack_tracers, only: nt_bgc_DMSPp, nlt_bgc_DMSPp, nt_bgc_Sil, nlt_bgc_Sil + use icepack_tracers, only: nt_bgc_DMSPd, nlt_bgc_DMSPd, nt_bgc_DMS, nlt_bgc_DMS + use icepack_tracers, only: nt_bgc_hum, nlt_bgc_hum, nt_bgc_PON, nlt_bgc_PON + use icepack_tracers, only: nt_bgc_C, nlt_bgc_C, nt_bgc_chl, nlt_bgc_chl + use icepack_tracers, only: nt_bgc_DOC, nlt_bgc_DOC, nt_bgc_DON, nlt_bgc_DON + use icepack_tracers, only: nt_bgc_DIC, nlt_bgc_DIC, nt_bgc_Fed, nlt_bgc_Fed + use icepack_tracers, only: nt_sice, bio_index, bio_index_o + use icepack_tracers, only: nt_zaero, nlt_zaero, nt_bgc_Fep, nlt_bgc_Fep + use icepack_tracers, only: nlt_zaero_sw, nlt_chl_sw, nt_zbgc_frac + use icepack_tracers, only: n_algae, n_doc, n_dic, n_don, n_fed, n_fep, n_zaero use icepack_zbgc_shared, only: zbgc_init_frac use icepack_zbgc_shared, only: zbgc_frac_init + use icepack_zbgc_shared, only: bgrid, cgrid, igrid, icgrid use icepack_zbgc_shared, only: bgc_tracer_type, remap_zbgc - use icepack_zbgc_shared, only: regrid_stationary use icepack_zbgc_shared, only: R_S2N, R_Si2N, R_Fe2C, R_Fe2N, R_Fe2DON, R_Fe2DOC use icepack_zbgc_shared, only: chlabs, alpha2max_low, beta2max use icepack_zbgc_shared, only: mu_max, grow_Tdep, fr_graze @@ -35,7 +53,10 @@ module icepack_zbgc use icepack_zbgc_shared, only: f_don, kn_bac, f_don_Am, f_doc use icepack_zbgc_shared, only: f_exude, k_bac use icepack_zbgc_shared, only: tau_ret, tau_rel - use icepack_zbgc_shared, only: R_C2N, R_CHL2N, f_abs_chl, R_C2N_DON + use icepack_zbgc_shared, only: R_C2N, R_chl2N, f_abs_chl, R_C2N_DON + use icepack_zbgc_shared, only: doc_pool_fractions + use icepack_zbgc_shared, only: algaltype, doctype, dictype + use icepack_zbgc_shared, only: dontype, fedtype, feptype, zaerotype use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted @@ -65,54 +86,34 @@ module icepack_zbgc ! Adjust biogeochemical tracers when new frazil ice forms - subroutine add_new_ice_bgc (dt, nblyr, & - ncat, nilyr, nltrcr, & - bgrid, cgrid, igrid, & + subroutine add_new_ice_bgc (dt, ncats, & aicen_init, vicen_init, vi0_init, & - aicen, vicen, vsnon1, & - vi0new, & - ntrcr, trcrn, nbtrcr, & - sss, ocean_bio, flux_bio, & - hsurp) + aicen, vicen, vin0new, & + trcrn, & + ocean_bio, flux_bio, hsurp, & + d_an_tot) integer (kind=int_kind), intent(in) :: & - nblyr , & ! number of bio layers - ncat , & ! number of thickness categories - nilyr , & ! number of ice layers - nltrcr , & ! number of zbgc tracers - nbtrcr , & ! number of biology tracers - ntrcr ! number of tracers in use - - real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: & - bgrid ! biology nondimensional vertical grid points - - real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: & - igrid ! biology vertical interface points - - real (kind=dbl_kind), dimension (nilyr+1), intent(in) :: & - cgrid ! CICE vertical coordinate + ncats ! 1 without floe size distribution or ncat real (kind=dbl_kind), intent(in) :: & dt ! time step (s) real (kind=dbl_kind), dimension (:), intent(in) :: & aicen_init , & ! initial concentration of ice - vicen_init , & ! intiial volume per unit area of ice (m) + vicen_init , & ! initial volume per unit area of ice (m) aicen , & ! concentration of ice - vicen ! volume per unit area of ice (m) - - real (kind=dbl_kind), intent(in) :: & - vsnon1 ! category 1 snow volume per unit area (m) + vicen , & ! volume per unit area of ice (m) + d_an_tot real (kind=dbl_kind), dimension (:,:), intent(inout) :: & trcrn ! ice tracers - real (kind=dbl_kind), intent(in) :: & - sss !sea surface salinity (ppt) + real (kind=dbl_kind), dimension (:), intent(in) :: & + vin0new ! ice tracers real (kind=dbl_kind), intent(in) :: & - vi0_init , & ! volume of new ice added to cat 1 (intial) - vi0new ! volume of new ice added to cat 1 + vi0_init ! volume of new ice added to cat 1 (intial) real (kind=dbl_kind), intent(in) :: & hsurp ! thickness of new ice added to each cat @@ -127,8 +128,10 @@ subroutine add_new_ice_bgc (dt, nblyr, & integer (kind=int_kind) :: & location , & ! 1 (add frazil to bottom), 0 (add frazil throughout) + m , & ! bio index n , & ! ice category index - k ! ice layer index + k , & ! ice layer index + nbiolayer real (kind=dbl_kind) :: & vbri1 , & ! starting volume of existing brine @@ -143,7 +146,8 @@ subroutine add_new_ice_bgc (dt, nblyr, & vbrin ! trcrn(nt_fbri,n)*vicen(n) real (kind=dbl_kind) :: & - vice_new ! vicen_init + vsurp + vice_new , & ! vicen_init + vsurp + bio0new ! ocean_bio * zbgc_init_fac real (kind=dbl_kind) :: & Tmlts ! melting temperature (oC) @@ -153,9 +157,15 @@ subroutine add_new_ice_bgc (dt, nblyr, & character(len=*),parameter :: subname='(add_new_ice_bgc)' + real (kind=dbl_kind), dimension (nblyr+1) :: & + zspace ! vertical grid spacing !----------------------------------------------------------------- ! brine !----------------------------------------------------------------- + + zspace(:) = c1/real(nblyr,kind=dbl_kind) + zspace(1) = p5*zspace(2) + zspace(nblyr+1) = zspace(1) vbrin(:) = c0 do n = 1, ncat vbrin(n) = vicen_init(n) @@ -190,67 +200,57 @@ subroutine add_new_ice_bgc (dt, nblyr, & vsurp = hsurp * aicen_init(n) vbrin(n) = vbrin(n) + vsurp vice_new = vicen_init(n) + vsurp - if (tr_brine .and. vicen(n) > c0) then - trcrn(nt_fbri,n) = vbrin(n)/vicen(n) + + if (tr_brine .and. vice_new > puny) then !c0) then + trcrn(nt_fbri,n) = vbrin(n)/vice_new elseif (tr_brine .and. vicen(n) <= c0) then trcrn(nt_fbri,n) = c1 endif - if (nltrcr > 0) then - location = 1 - call adjust_tracer_profile(nbtrcr, dt, ntrcr, & - aicen_init(n), & - vbrin(n), & - vice_new, & - trcrn(:,n), & - vtmp, & - vsurp, sss, & - nilyr, nblyr, & - bgrid, & - cgrid, & - ocean_bio, igrid, & - location) + if (nbtrcr > 0) then + do m = 1, nbtrcr + bio0new = ocean_bio(m)*zbgc_init_frac(m) + nbiolayer = nblyr+1 + call update_vertical_bio_tracers(nbiolayer, trcrn(bio_index(m):bio_index(m) + nblyr,n), & + vtmp, vbrin(n), bio0new,zspace(:)) + enddo !nbtrcr if (icepack_warnings_aborted(subname)) return - endif ! nltrcr + endif ! nbtrcr endif ! hsurp > 0 enddo ! n !----------------------------------------------------------------- ! Combine bgc in new ice grown in open water with category 1 ice. !----------------------------------------------------------------- + do n = 1, ncats + if (vin0new(n) > c0 .and. d_an_tot(n) > c0) then - if (vi0new > c0) then - - vbri1 = vbrin(1) - vbrin(1) = vbrin(1) + vi0new - if (tr_brine .and. vicen(1) > c0) then - trcrn(nt_fbri,1) = vbrin(1)/vicen(1) - elseif (tr_brine .and. vicen(1) <= c0) then - trcrn(nt_fbri,1) = c1 + vbri1 = vbrin(n) + vbrin(n) = vbrin(n) + vin0new(n) + if (tr_brine .and. vicen(n) > puny) then + trcrn(nt_fbri,n) = vbrin(n)/vicen(n) + elseif (tr_brine .and. vicen(n) <= puny) then + trcrn(nt_fbri,n) = c1 endif ! Diffuse_bio handles concentration changes from ice growth/melt ! ice area changes ! add salt throughout, location = 0 - if (nltrcr > 0) then - location = 0 - call adjust_tracer_profile(nbtrcr, dt, ntrcr, & - aicen(1), & - vbrin(1), & - vicen(1), & - trcrn(:,1), & - vbri1, & - vi0new, sss, & - nilyr, nblyr, & - bgrid, & - cgrid, & - ocean_bio, igrid, & - location) + if (nbtrcr > 0 .and. vbrin(n) > puny) then + do m = 1, nbtrcr + bio0new = ocean_bio(m)*zbgc_init_frac(m) + do k = 1, nblyr+1 + trcrn(bio_index(m) + k-1,n) = & + (trcrn(bio_index(m) + k-1,n)*vbri1 + bio0new * vin0new(n))/vbrin(n) + enddo + enddo + if (icepack_warnings_aborted(subname)) return - endif ! nltrcr > 0 - endif ! vi0new > 0 + endif ! nbtrcr > 0 + endif ! vin0new(n) > 0 + enddo ! n = 1,ncats if (tr_brine .and. conserv_check) then call column_sum (ncat, vbrin, vbri_final) @@ -270,196 +270,62 @@ end subroutine add_new_ice_bgc ! When sea ice melts laterally, flux bgc to ocean - subroutine lateral_melt_bgc (dt, & - ncat, nblyr, & - rside, vicen, & - trcrn, & - flux_bio, nbltrcr) - - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nblyr , & ! number of bio layers - nbltrcr ! number of biology tracers + subroutine lateral_melt_bgc (dt, & + rsiden, vicen_init,& + trcrn, flux_bio) real (kind=dbl_kind), intent(in) :: & dt ! time step (s) real (kind=dbl_kind), dimension(:), intent(in) :: & - vicen ! volume per unit area of ice (m) + vicen_init! volume per unit area of ice (m) real (kind=dbl_kind), dimension (:,:), intent(in) :: & trcrn ! tracer array - real (kind=dbl_kind), intent(in) :: & - rside ! fraction of ice that melts laterally + real (kind=dbl_kind), dimension(:), intent(in) :: & + rsiden ! fraction of ice that melts laterally real (kind=dbl_kind), dimension(:), intent(inout) :: & flux_bio ! biology tracer flux from layer bgc (mmol/m^2/s) ! local variables + real (kind=dbl_kind) :: & + total_bio_initial, & ! initial column tracer concentration (mmol/m2) + total_bio_final ! final column tracer concentration (mmol/m20 + integer (kind=int_kind) :: & k , & ! layer index m , & ! n ! category index - real (kind=dbl_kind) :: & - zspace ! bio grid spacing + real (kind=dbl_kind), dimension (nblyr+1) :: & + zspace ! vertical grid spacing character(len=*),parameter :: subname='(lateral_melt_bgc)' - zspace = c1/(real(nblyr,kind=dbl_kind)) + zspace(:) = c1/real(nblyr,kind=dbl_kind) + zspace(1) = p5*zspace(2) + zspace(nblyr+1) = zspace(1) - do m = 1, nbltrcr + do m = 1, nbtrcr do n = 1, ncat do k = 1, nblyr+1 flux_bio(m) = flux_bio(m) + trcrn(nt_fbri,n) & - * vicen(n)*zspace*trcrn(bio_index(m)+k-1,n) & - * rside/dt + * vicen_init(n)*zspace(k)*trcrn(bio_index(m)+k-1,n) & + * rsiden(n)/dt enddo enddo enddo end subroutine lateral_melt_bgc -!======================================================================= -! -! Add new ice tracers to the ice bottom and adjust the vertical profile -! -! author: Nicole Jeffery, LANL - - subroutine adjust_tracer_profile (nbtrcr, dt, ntrcr, & - aicen, vbrin, & - vicen, trcrn, & - vtmp, & - vsurp, sss, & - nilyr, nblyr, & - bgrid, & - cgrid, ocean_bio, & - igrid, location) - - integer (kind=int_kind), intent(in) :: & - location , & ! 1 (add frazil to bottom), 0 (add frazil throughout) - ntrcr , & ! number of tracers in use - nilyr , & ! number of ice layers - nbtrcr , & ! number of biology tracers - nblyr ! number of biology layers - - real (kind=dbl_kind), intent(in) :: & - dt ! timestep (s) - - real (kind=dbl_kind), intent(in) :: & - aicen , & ! concentration of ice - vicen , & ! volume of ice - sss , & ! ocean salinity (ppt) - ! hsurp , & ! flags new ice added to each cat - vsurp , & ! volume of new ice added to each cat - vtmp ! total volume of new and old ice - - real (kind=dbl_kind), dimension (nbtrcr), intent(in) :: & - ocean_bio - - real (kind=dbl_kind), intent(in) :: & - vbrin ! fbri*volume per unit area of ice (m) - - real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: & - igrid ! zbio grid - - real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: & - bgrid ! zsal grid - - real (kind=dbl_kind), dimension (nilyr+1), intent(in) :: & - cgrid ! CICE grid - - real (kind=dbl_kind), dimension (ntrcr), intent(inout) :: & - trcrn ! ice tracers - - ! local variables - - real (kind=dbl_kind), dimension (ntrcr+2) :: & - trtmp0, & ! temporary, remapped tracers - trtmp ! temporary, remapped tracers - - real (kind=dbl_kind) :: & - hin , & ! ice height - hinS_new, & ! brine height - temp_S - - integer (kind=int_kind) :: & - k, m - - real (kind=dbl_kind), dimension (nblyr+1) :: & - C_stationary ! stationary bulk concentration*h (mmol/m^2) - - real (kind=dbl_kind), dimension (nblyr) :: & - S_stationary ! stationary bulk concentration*h (ppt*m) - - real(kind=dbl_kind) :: & - top_conc , & ! salinity or bgc ocean concentration of frazil - fluxb , & ! needed for regrid (set to zero here) - hbri_old , & ! previous timestep brine height - hbri ! brine height - - character(len=*),parameter :: subname='(adjust_tracer_profile)' - - trtmp0(:) = c0 - trtmp(:) = c0 - fluxb = c0 - - if (location == 1 .and. vbrin > c0) then ! add frazil to bottom - - hbri = vbrin - hbri_old = vtmp - - do m = 1, nbtrcr - top_conc = ocean_bio(m)*zbgc_init_frac(m) - do k = 1, nblyr+1 - C_stationary(k) = trcrn(bio_index(m) + k-1)* hbri_old - enddo !k - call regrid_stationary (C_stationary, hbri_old, & - hbri, dt, & - ntrcr, & - nblyr, top_conc, & - igrid, fluxb ) - if (icepack_warnings_aborted(subname)) return - do k = 1, nblyr+1 - trcrn(bio_index(m) + k-1) = C_stationary(k)/hbri - enddo !k - enddo !m - - elseif (vbrin > c0) then ! add frazil throughout location == 0 .and. - - do k = 1, nblyr+1 - do m = 1, nbtrcr - trcrn(bio_index(m) + k-1) = (trcrn(bio_index(m) + k-1) * vtmp & - + ocean_bio(m)*zbgc_init_frac(m) * vsurp) / vbrin - enddo - enddo - - endif ! location - - end subroutine adjust_tracer_profile - !======================================================================= !autodocument_start icepack_init_bgc ! - subroutine icepack_init_bgc(ncat, nblyr, nilyr, ntrcr_o, & - cgrid, igrid, ntrcr, nbtrcr, & - sicen, trcrn, sss, ocean_bio_all) - - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nilyr , & ! number of ice layers - nblyr , & ! number of bio layers - ntrcr_o,& ! number of tracers not including bgc - ntrcr , & ! number of tracers in use - nbtrcr ! number of bio tracers in use - - real (kind=dbl_kind), dimension (nblyr+1), intent(inout) :: & - igrid ! biology vertical interface points - - real (kind=dbl_kind), dimension (nilyr+1), intent(inout) :: & - cgrid ! CICE vertical coordinate + subroutine icepack_init_bgc( & + sicen, trcrn, sss, ocean_bio_all, DOCPoolFractions) real (kind=dbl_kind), dimension(nilyr, ncat), intent(in) :: & sicen ! salinity on the cice grid @@ -470,9 +336,12 @@ subroutine icepack_init_bgc(ncat, nblyr, nilyr, ntrcr_o, & real (kind=dbl_kind), intent(in) :: & sss ! sea surface salinity (ppt) - real (kind=dbl_kind), dimension (:), intent(inout) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & ocean_bio_all ! fixed order, all values even for tracers false + real (kind=dbl_kind), dimension (:), optional, intent(out) :: & + DOCPoolFractions ! Fraction of DOC in polysacharids, lipids, and proteins + !autodocument_end ! local variables @@ -493,6 +362,8 @@ subroutine icepack_init_bgc(ncat, nblyr, nilyr, ntrcr_o, & ! The skeletal layer model assumes a constant ! layer depth (sk_l) and porosity (phi_sk) !----------------------------------------------------------------------------- + if (.not. restartbgc) then + if (skl_bgc) then do n = 1,ncat @@ -547,6 +418,16 @@ subroutine icepack_init_bgc(ncat, nblyr, nilyr, ntrcr_o, & endif ! scale_bgc endif ! skl_bgc + endif ! restart + + if (present(DOCPoolFractions)) then + DOCPoolFractions(:) = c1 + if (.not. use_macromolecules) then + do mm = 1,max_doc + DOCPoolFractions(mm) = doc_pool_fractions(mm) + end do + end if + endif end subroutine icepack_init_bgc @@ -554,76 +435,14 @@ end subroutine icepack_init_bgc !autodocument_start icepack_init_zbgc ! - subroutine icepack_init_zbgc ( & - R_Si2N_in, R_S2N_in, R_Fe2C_in, R_Fe2N_in, R_C2N_in, R_C2N_DON_in, & - R_chl2N_in, F_abs_chl_in, R_Fe2DON_in, R_Fe2DOC_in, chlabs_in, & - alpha2max_low_in, beta2max_in, mu_max_in, fr_graze_in, mort_pre_in, & - mort_Tdep_in, k_exude_in, K_Nit_in, K_Am_in, K_sil_in, K_Fe_in, & - f_don_in, kn_bac_in, f_don_Am_in, f_doc_in, f_exude_in, k_bac_in, & - grow_Tdep_in, zbgc_frac_init_in, & - zbgc_init_frac_in, tau_ret_in, tau_rel_in, bgc_tracer_type_in, & - fr_resp_in, algal_vel_in, R_dFe2dust_in, dustFe_sol_in, T_max_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, y_sk_DMS_in, t_sk_conv_in, t_sk_ox_in, fsal_in) - - real (kind=dbl_kind), optional :: R_C2N_in(:) ! algal C to N (mole/mole) - real (kind=dbl_kind), optional :: R_chl2N_in(:) ! 3 algal chlorophyll to N (mg/mmol) - real (kind=dbl_kind), optional :: F_abs_chl_in(:) ! to scale absorption in Dedd - real (kind=dbl_kind), optional :: R_C2N_DON_in(:) ! increase compare to algal R_Fe2C - real (kind=dbl_kind), optional :: R_Si2N_in(:) ! algal Sil to N (mole/mole) - real (kind=dbl_kind), optional :: R_S2N_in(:) ! algal S to N (mole/mole) - real (kind=dbl_kind), optional :: R_Fe2C_in(:) ! algal Fe to carbon (umol/mmol) - real (kind=dbl_kind), optional :: R_Fe2N_in(:) ! algal Fe to N (umol/mmol) - real (kind=dbl_kind), optional :: R_Fe2DON_in(:) ! Fe to N of DON (nmol/umol) - real (kind=dbl_kind), optional :: R_Fe2DOC_in(:) ! Fe to C of DOC (nmol/umol) - - real (kind=dbl_kind), optional :: fr_resp_in ! frac of algal growth lost due to respiration - real (kind=dbl_kind), optional :: algal_vel_in ! 0.5 cm/d(m/s) Lavoie 2005 1.5 cm/day - real (kind=dbl_kind), optional :: R_dFe2dust_in ! g/g (3.5% content) Tagliabue 2009 - real (kind=dbl_kind), optional :: dustFe_sol_in ! solubility fraction - real (kind=dbl_kind), optional :: T_max_in ! maximum temperature (C) - real (kind=dbl_kind), optional :: op_dep_min_in ! Light attenuates for optical depths exceeding min - real (kind=dbl_kind), optional :: fr_graze_s_in ! fraction of grazing spilled or slopped - real (kind=dbl_kind), optional :: fr_graze_e_in ! fraction of assimilation excreted - real (kind=dbl_kind), optional :: fr_mort2min_in ! fractionation of mortality to Am - real (kind=dbl_kind), optional :: fr_dFe_in ! fraction of remineralized nitrogen - ! (in units of algal iron) - real (kind=dbl_kind), optional :: k_nitrif_in ! nitrification rate (1/day) - real (kind=dbl_kind), optional :: t_iron_conv_in ! desorption loss pFe to dFe (day) - real (kind=dbl_kind), optional :: max_loss_in ! restrict uptake to % of remaining value - real (kind=dbl_kind), optional :: max_dfe_doc1_in ! max ratio of dFe to saccharides in the ice (nM Fe/muM C) - real (kind=dbl_kind), optional :: fr_resp_s_in ! DMSPd fraction of respiration loss as DMSPd - real (kind=dbl_kind), optional :: y_sk_DMS_in ! fraction conversion given high yield - real (kind=dbl_kind), optional :: t_sk_conv_in ! Stefels conversion time (d) - real (kind=dbl_kind), optional :: t_sk_ox_in ! DMS oxidation time (d) - real (kind=dbl_kind), optional :: fsal_in ! salinity limitation factor (1) - - real (kind=dbl_kind), optional :: chlabs_in(:) ! chla absorption 1/m/(mg/m^3) - real (kind=dbl_kind), optional :: alpha2max_low_in(:) ! light limitation (1/(W/m^2)) - real (kind=dbl_kind), optional :: beta2max_in(:) ! light inhibition (1/(W/m^2)) - real (kind=dbl_kind), optional :: mu_max_in(:) ! maximum growth rate (1/d) - real (kind=dbl_kind), optional :: grow_Tdep_in(:) ! T dependence of growth (1/C) - real (kind=dbl_kind), optional :: fr_graze_in(:) ! fraction of algae grazed - real (kind=dbl_kind), optional :: mort_pre_in(:) ! mortality (1/day) - real (kind=dbl_kind), optional :: mort_Tdep_in(:) ! T dependence of mortality (1/C) - real (kind=dbl_kind), optional :: k_exude_in(:) ! algal carbon exudation rate (1/d) - real (kind=dbl_kind), optional :: K_Nit_in(:) ! nitrate half saturation (mmol/m^3) - real (kind=dbl_kind), optional :: K_Am_in(:) ! ammonium half saturation (mmol/m^3) - real (kind=dbl_kind), optional :: K_Sil_in(:) ! silicon half saturation (mmol/m^3) - real (kind=dbl_kind), optional :: K_Fe_in(:) ! iron half saturation or micromol/m^3 - real (kind=dbl_kind), optional :: f_don_in(:) ! fraction of spilled grazing to DON - real (kind=dbl_kind), optional :: kn_bac_in(:) ! Bacterial degredation of DON (1/d) - real (kind=dbl_kind), optional :: f_don_Am_in(:) ! fraction of remineralized DON to Am - real (kind=dbl_kind), optional :: f_doc_in(:) ! fraction of mort_N that goes to each doc pool - real (kind=dbl_kind), optional :: f_exude_in(:) ! fraction of exuded carbon to each DOC pool - real (kind=dbl_kind), optional :: k_bac_in(:) ! Bacterial degredation of DOC (1/d) - - real (kind=dbl_kind), optional :: zbgc_frac_init_in(:) ! initializes mobile fraction - real (kind=dbl_kind), optional :: bgc_tracer_type_in(:) ! described tracer in mobile or stationary phases - real (kind=dbl_kind), optional :: zbgc_init_frac_in(:) ! fraction of ocean tracer concentration in new ice - real (kind=dbl_kind), optional :: tau_ret_in(:) ! retention timescale (s), mobile to stationary phase - real (kind=dbl_kind), optional :: tau_rel_in(:) ! release timescale (s), stationary to mobile phase + subroutine icepack_init_zbgc (& + zbgc_frac_init_in, zbgc_init_frac_in, tau_ret_in, tau_rel_in, bgc_tracer_type_in) + + real (kind=dbl_kind), dimension (:), intent(in), optional :: zbgc_frac_init_in(:) ! initializes mobile fraction + real (kind=dbl_kind), dimension (:), intent(in), optional :: bgc_tracer_type_in(:) ! described tracer in mobile or stationary phases + real (kind=dbl_kind), dimension (:), intent(in), optional :: zbgc_init_frac_in(:) ! fraction of ocean tracer concentration in new ice + real (kind=dbl_kind), dimension (:), intent(in), optional :: tau_ret_in(:) ! retention timescale (s), mobile to stationary phase + real (kind=dbl_kind), dimension (:), intent(in), optional :: tau_rel_in(:) ! release timescale (s), stationary to mobile phase !autodocument_end @@ -631,117 +450,176 @@ subroutine icepack_init_zbgc ( & !-------- - if (present(R_C2N_in)) R_C2N(:) = R_C2N_in(:) - if (present(R_chl2N_in)) R_chl2N(:) = R_chl2N_in(:) - if (present(F_abs_chl_in)) F_abs_chl(:) = F_abs_chl_in(:) - if (present(R_C2N_DON_in)) R_C2N_DON(:) = R_C2N_DON_in(:) - if (present(R_Si2N_in)) R_Si2N(:) = R_Si2N_in(:) - if (present(R_S2N_in)) R_S2N(:) = R_S2N_in(:) - if (present(R_Fe2C_in)) R_Fe2C(:) = R_Fe2C_in(:) - if (present(R_Fe2N_in)) R_Fe2N(:) = R_Fe2N_in(:) - if (present(R_Fe2DON_in)) R_Fe2DON(:) = R_Fe2DON_in(:) - if (present(R_Fe2DOC_in)) R_Fe2DOC(:) = R_Fe2DOC_in(:) - - if (present(fr_resp_in)) fr_resp = fr_resp_in - if (present(algal_vel_in)) algal_vel = algal_vel_in - if (present(R_dFe2dust_in)) R_dFe2dust = R_dFe2dust_in - if (present(dustFe_sol_in)) dustFe_sol = dustFe_sol_in - if (present(T_max_in)) T_max = T_max_in - if (present(op_dep_min_in)) op_dep_min = op_dep_min_in - if (present(fr_graze_s_in)) fr_graze_s = fr_graze_s_in - if (present(fr_graze_e_in)) fr_graze_e = fr_graze_e_in - if (present(fr_mort2min_in)) fr_mort2min = fr_mort2min_in - if (present(fr_dFe_in)) fr_dFe = fr_dFe_in - if (present(k_nitrif_in)) k_nitrif = k_nitrif_in - if (present(t_iron_conv_in)) t_iron_conv = t_iron_conv_in - if (present(max_loss_in)) max_loss = max_loss_in - if (present(max_dfe_doc1_in)) max_dfe_doc1 = max_dfe_doc1_in - if (present(fr_resp_s_in)) fr_resp_s = fr_resp_s_in - if (present(y_sk_DMS_in)) y_sk_DMS = y_sk_DMS_in - if (present(t_sk_conv_in)) t_sk_conv = t_sk_conv_in - if (present(t_sk_ox_in)) t_sk_ox = t_sk_ox_in - if (present(fsal_in)) fsal = fsal_in - - if (present(chlabs_in)) chlabs(:) = chlabs_in(:) - if (present(alpha2max_low_in)) alpha2max_low(:) = alpha2max_low_in(:) - if (present(beta2max_in)) beta2max(:) = beta2max_in(:) - if (present(mu_max_in)) mu_max(:) = mu_max_in(:) - if (present(grow_Tdep_in)) grow_Tdep(:) = grow_Tdep_in(:) - if (present(fr_graze_in)) fr_graze(:) = fr_graze_in(:) - if (present(mort_pre_in)) mort_pre(:) = mort_pre_in(:) - if (present(mort_Tdep_in)) mort_Tdep(:) = mort_Tdep_in(:) - if (present(k_exude_in)) k_exude(:) = k_exude_in(:) - if (present(K_Nit_in)) K_Nit(:) = K_Nit_in(:) - if (present(K_Am_in)) K_Am(:) = K_Am_in(:) - if (present(K_Sil_in)) K_Sil(:) = K_Sil_in(:) - if (present(K_Fe_in)) K_Fe(:) = K_Fe_in(:) - if (present(f_don_in)) f_don(:) = f_don_in(:) - if (present(kn_bac_in)) kn_bac(:) = kn_bac_in(:) - if (present(f_don_Am_in)) f_don_Am(:) = f_don_Am_in(:) - if (present(f_doc_in)) f_doc(:) = f_doc_in(:) - if (present(f_exude_in)) f_exude(:) = f_exude_in(:) - if (present(k_bac_in)) k_bac(:) = k_bac_in(:) - if (present(zbgc_frac_init_in)) zbgc_frac_init(:) = zbgc_frac_init_in(:) if (present(bgc_tracer_type_in)) bgc_tracer_type(:) = bgc_tracer_type_in(:) if (present(zbgc_init_frac_in)) zbgc_init_frac(:) = zbgc_init_frac_in(:) if (present(tau_ret_in)) tau_ret(:) = tau_ret_in(:) if (present(tau_rel_in)) tau_rel(:) = tau_rel_in(:) + R_Si2N(1) = ratio_Si2N_diatoms + R_Si2N(2) = ratio_Si2N_sp + R_Si2N(3) = ratio_Si2N_phaeo + + R_S2N(1) = ratio_S2N_diatoms + R_S2N(2) = ratio_S2N_sp + R_S2N(3) = ratio_S2N_phaeo + + R_Fe2C(1) = ratio_Fe2C_diatoms + R_Fe2C(2) = ratio_Fe2C_sp + R_Fe2C(3) = ratio_Fe2C_phaeo + + R_Fe2N(1) = ratio_Fe2N_diatoms + R_Fe2N(2) = ratio_Fe2N_sp + R_Fe2N(3) = ratio_Fe2N_phaeo + + R_C2N(1) = ratio_C2N_diatoms + R_C2N(2) = ratio_C2N_sp + R_C2N(3) = ratio_C2N_phaeo + + R_chl2N(1) = ratio_chl2N_diatoms + R_chl2N(2) = ratio_chl2N_sp + R_chl2N(3) = ratio_chl2N_phaeo + + F_abs_chl(1) = F_abs_chl_diatoms + F_abs_chl(2) = F_abs_chl_sp + F_abs_chl(3) = F_abs_chl_phaeo + + R_Fe2DON(1) = ratio_Fe2DON + R_C2N_DON(1) = ratio_C2N_proteins + + R_Fe2DOC(1) = ratio_Fe2DOC_s + R_Fe2DOC(2) = ratio_Fe2DOC_l + R_Fe2DOC(3) = c0 + + chlabs(1) = chlabs_diatoms + chlabs(2) = chlabs_sp + chlabs(3) = chlabs_phaeo + + alpha2max_low(1) = alpha2max_low_diatoms + alpha2max_low(2) = alpha2max_low_sp + alpha2max_low(3) = alpha2max_low_phaeo + + beta2max(1) = beta2max_diatoms + beta2max(2) = beta2max_sp + beta2max(3) = beta2max_phaeo + + mu_max(1) = mu_max_diatoms + mu_max(2) = mu_max_sp + mu_max(3) = mu_max_phaeo + + grow_Tdep(1) = grow_Tdep_diatoms + grow_Tdep(2) = grow_Tdep_sp + grow_Tdep(3) = grow_Tdep_phaeo + + fr_graze(1) = fr_graze_diatoms + fr_graze(2) = fr_graze_sp + fr_graze(3) = fr_graze_phaeo + + mort_pre(1) = mort_pre_diatoms + mort_pre(2) = mort_pre_sp + mort_pre(3) = mort_pre_phaeo + + mort_Tdep(1) = mort_Tdep_diatoms + mort_Tdep(2) = mort_Tdep_sp + mort_Tdep(3) = mort_Tdep_phaeo + + k_exude(1) = k_exude_diatoms + k_exude(2) = k_exude_sp + k_exude(3) = k_exude_phaeo + + K_Nit(1) = K_Nit_diatoms + K_Nit(2) = K_Nit_sp + K_Nit(3) = K_Nit_phaeo + + K_Am(1) = K_Am_diatoms + K_Am(2) = K_Am_sp + K_Am(3) = K_Am_phaeo + + K_Sil(1) = K_Sil_diatoms + K_Sil(2) = K_Sil_sp + K_Sil(3) = K_Sil_phaeo + + K_Fe(1) = K_Fe_diatoms + K_Fe(2) = K_Fe_sp + K_Fe(3) = K_Fe_phaeo + + f_doc(:) = c0 + f_doc(1) = f_doc_s + f_doc(2) = f_doc_l + + f_don(1) = f_don_protein + kn_bac(1) = kn_bac_protein + f_don_Am(1) = f_don_Am_protein + + f_exude(:) = c0 + f_exude(1) = f_exude_s + f_exude(2) = f_exude_l + + k_bac(:) = c0 + k_bac(1) = k_bac_s + k_bac(2) = k_bac_l + + algaltype(1) = algaltype_diatoms + algaltype(2) = algaltype_sp + algaltype(3) = algaltype_phaeo + + doctype(:) = c0 + doctype(1) = doctype_s + doctype(2) = doctype_l + + dictype(:) = dictype_1 + + dontype(:) = dontype_protein + + fedtype(:) = fedtype_1 + feptype(:) = feptype_1 + + zaerotype(1) = zaerotype_bc1 + zaerotype(2) = zaerotype_bc2 + zaerotype(3) = zaerotype_dust1 + zaerotype(4) = zaerotype_dust2 + zaerotype(5) = zaerotype_dust3 + zaerotype(6) = zaerotype_dust4 end subroutine icepack_init_zbgc !======================================================================= !autodocument_start icepack_biogeochemistry ! - subroutine icepack_biogeochemistry(dt, & - ntrcr, nbtrcr, & upNO, upNH, iDi, iki, zfswin, & - zsal_tot, darcy_V, grow_net, & + darcy_V, grow_net, & PP_net, hbri,dhbr_bot, dhbr_top, Zoo,& - fbio_snoice, fbio_atmice, ocean_bio, & + fbio_snoice, fbio_atmice, ocean_bio_dh, ocean_bio, & first_ice, fswpenln, bphi, bTiz, ice_bio_net, & - snow_bio_net, fswthrun, Rayleigh_criteria, & - sice_rho, fzsal, fzsal_g, & - bgrid, igrid, icgrid, cgrid, & - nblyr, nilyr, nslyr, n_algae, n_zaero, ncat, & - n_doc, n_dic, n_don, n_fed, n_fep, & + snow_bio_net, totalChla, fswthrun, & meltbn, melttn, congeln, snoicen, & - sst, sss, fsnow, meltsn, & + sst, sss, Tf, fsnow, meltsn, & !hmix, & hin_old, flux_bio, flux_bio_atm, & aicen_init, vicen_init, aicen, vicen, vsnon, & - aice0, trcrn, vsnon_init, skl_bgc) + aice0, trcrn, vsnon_init, & + flux_bion, bioPorosityIceCell, & + bioSalinityIceCell, bioTemperatureIceCell) real (kind=dbl_kind), intent(in) :: & dt ! time step - integer (kind=int_kind), intent(in) :: & - ncat, & - nilyr, & - nslyr, & - nblyr, & - ntrcr, & - nbtrcr, & - n_algae, n_zaero, & - n_doc, n_dic, n_don, n_fed, n_fep - real (kind=dbl_kind), dimension (:), intent(inout) :: & - bgrid , & ! biology nondimensional vertical grid points - igrid , & ! biology vertical interface points - cgrid , & ! CICE vertical coordinate - icgrid , & ! interface grid for CICE (shortwave variable) - ocean_bio , & ! contains all the ocean bgc tracer concentrations fbio_snoice , & ! fluxes from snow to ice fbio_atmice , & ! fluxes from atm to ice dhbr_top , & ! brine top change dhbr_bot , & ! brine bottom change darcy_V , & ! darcy velocity positive up (m/s) hin_old , & ! old ice thickness - sice_rho , & ! avg sea ice density (kg/m^3) ice_bio_net , & ! depth integrated tracer (mmol/m^2) snow_bio_net , & ! depth integrated snow tracer (mmol/m^2) - flux_bio ! all bio fluxes to ocean + flux_bio ! all bio fluxes to ocean + + real (kind=dbl_kind), dimension (:), intent(in) :: & + ocean_bio ! contains the ocean bgc tracer concentrations in use (mmol/m^3) + + real (kind=dbl_kind), optional, dimension (:), intent(out) :: & + ocean_bio_dh ! The ocean bgc tracer concentrations in use * brine thickness * phi (mmol/m^2) logical (kind=log_kind), dimension (:), intent(inout) :: & first_ice ! distinguishes ice that disappears (e.g. melts) @@ -749,6 +627,14 @@ subroutine icepack_biogeochemistry(dt, & ! during a single time step from ice that was ! there the entire time step (true until ice forms) + real (kind=dbl_kind), optional, dimension (:,:), intent(out) :: & + flux_bion ! per categeory ice to ocean biogeochemistry flux (mmol/m2/s) + + real (kind=dbl_kind), optional, dimension (:), intent(inout) :: & + bioPorosityIceCell, & ! category average porosity on the interface bio grid + bioSalinityIceCell, & ! (ppt) category average porosity on the interface bio grid + bioTemperatureIceCell ! (oC) category average porosity on the interface bio grid + real (kind=dbl_kind), dimension (:,:), intent(inout) :: & Zoo , & ! N losses accumulated in timestep (ie. zooplankton/bacteria) ! mmol/m^3 @@ -766,15 +652,8 @@ subroutine icepack_biogeochemistry(dt, & upNO , & ! nitrate uptake rate (mmol/m^2/d) times aice upNH ! ammonium uptake rate (mmol/m^2/d) times aice - real (kind=dbl_kind), intent(inout), optional :: & - zsal_tot ! Total ice salinity in per grid cell (g/m^2) (deprecated) - - real (kind=dbl_kind), intent(inout), optional :: & - fzsal , & ! Total flux of salt to ocean at time step for conservation (deprecated) - fzsal_g ! Total gravity drainage flux (deprecated) - - logical (kind=log_kind), intent(inout), optional :: & - Rayleigh_criteria ! .true. means Ra_c was reached (deprecated) + real (kind=dbl_kind), optional, intent(inout) :: & + totalChla ! ice integrated chla and summed over all algal groups (mg/m^2) real (kind=dbl_kind), dimension (:,:), intent(in) :: & fswpenln ! visible SW entering ice layers (W m-2) @@ -798,17 +677,17 @@ subroutine icepack_biogeochemistry(dt, & aice0 , & ! open water area fraction sss , & ! sea surface salinity (ppt) sst , & ! sea surface temperature (C) + !hmix , & ! mixed layer depth (m) + Tf , & ! basal freezing temperature (C) fsnow ! snowfall rate (kg/m^2 s) - logical (kind=log_kind), intent(in) :: & - skl_bgc ! if true, solve skeletal biochemistry - !autodocument_end ! local variables integer (kind=int_kind) :: & - n, mm ! thickness category index + k , & ! vertical index + n, mm ! thickness category index real (kind=dbl_kind) :: & hin , & ! new ice thickness @@ -831,10 +710,14 @@ subroutine icepack_biogeochemistry(dt, & iphin , & ! porosity ibrine_sal , & ! brine salinity (ppt) ibrine_rho , & ! brine_density (kg/m^3) + iSin , & ! Salinity on the interface grid (ppt) iTin ! Temperature on the interface grid (oC) real (kind=dbl_kind) :: & - sloss ! brine flux contribution from surface runoff (g/m^2) + sloss ! brine flux contribution from surface runoff (g/m^2) + + real (kind=dbl_kind), dimension (nbtrcr) :: & + flux_bion_n ! temporary ! for bgc sk real (kind=dbl_kind) :: & @@ -842,14 +725,25 @@ subroutine icepack_biogeochemistry(dt, & dh_top_chl , & ! Chlorophyll may or may not flush darcy_V_chl + real (kind=dbl_kind), dimension (nblyr+1) :: & + zspace ! vertical grid spacing + character(len=*),parameter :: subname='(icepack_biogeochemistry)' + zspace(:) = c1/real(nblyr,kind=dbl_kind) + zspace(1) = p5*zspace(2) + zspace(nblyr+1) = zspace(1) + + if (present(bioPorosityIceCell)) bioPorosityIceCell(:) = c0 + if (present(bioSalinityIceCell)) bioSalinityIceCell(:) = c0 + if (present(bioTemperatureIceCell)) bioTemperatureIceCell(:) = c0 do n = 1, ncat !----------------------------------------------------------------- ! initialize !----------------------------------------------------------------- + flux_bion_n(:) = c0 hin_old(n) = c0 if (aicen_init(n) > puny) then hin_old(n) = vicen_init(n) & @@ -896,7 +790,7 @@ subroutine icepack_biogeochemistry(dt, & trcrn(nt_fbri,n), & dhbr_top(n), dhbr_bot(n), & hbr_old, hin, & - hsn, first_ice(n) ) + hsn) if (icepack_warnings_aborted(subname)) return ! Requires the average ice permeability = kavg(:) @@ -905,22 +799,20 @@ subroutine icepack_biogeochemistry(dt, & iDi(:,n) = c0 - call compute_microS_mushy (nilyr, nblyr, & - bgrid, cgrid, igrid, & + call compute_microS_mushy ( & trcrn(:,n), hin_old(n), hbr_old, & sss, sst, bTiz(:,n), & iTin(:), bphi(:,n), kavg, & bphi_o, bSin(:), & brine_sal(:), brine_rho(:), iphin(:), & - ibrine_rho(:), ibrine_sal(:), sice_rho(n), & - iDi(:,n) ) + ibrine_rho(:), ibrine_sal(:), & + iDi(:,n) , iSin(:)) if (icepack_warnings_aborted(subname)) return call update_hbrine (melttn(n), & meltsn (n), dt, & hin, hsn, & hin_old (n), hbrin, & - hbr_old, & trcrn(nt_fbri,n), & dhbr_top(n), dhbr_bot(n), & @@ -941,50 +833,49 @@ subroutine icepack_biogeochemistry(dt, & if (z_tracers) then - call zbio (dt, nblyr, & - nslyr, nilyr, & + call zbio (dt, & melttn(n), & meltsn(n), meltbn (n), & congeln(n), snoicen(n), & - nbtrcr, fsnow, & - ntrcr, trcrn(1:ntrcr,n), & - bio_index(1:nbtrcr), aicen_init(n), & + fsnow, trcrn(1:ntrcr,n), & + bio_index(1:nbtrcr), bio_index_o(:), & + aicen_init(n), & vicen_init(n), vsnon_init(n), & vicen(n), vsnon(n), & aicen(n), flux_bio_atm(1:nbtrcr), & - n, n_algae, & - n_doc, n_dic, & - n_don, & - n_fed, n_fep, & - n_zaero, first_ice(n), & + n, first_ice(n), & hin_old(n), ocean_bio(1:nbtrcr), & + ocean_bio_dh, & bphi(:,n), iphin, & - iDi(:,n), & + iDi(:,n), & fswpenln(:,n), & dhbr_top(n), dhbr_bot(n), & zfswin(:,n), & hbrin, hbr_old, & -! darcy_V(n), darcy_V_chl, & - darcy_V(n), & - bgrid, & - igrid, icgrid, & + darcy_V(n), & bphi_o, & - iTin, & + iTin, & Zoo(:,n), & flux_bio(1:nbtrcr), dh_direct, & upNO, upNH, & fbio_snoice, fbio_atmice, & PP_net, ice_bio_net (1:nbtrcr), & - snow_bio_net(1:nbtrcr),grow_net ) + snow_bio_net(1:nbtrcr),grow_net, & + totalChla, & + flux_bion_n(1:nbtrcr), iSin, & + bioPorosityIceCell, bioSalinityIceCell, & + bioTemperatureIceCell ) if (icepack_warnings_aborted(subname)) return + if (present(flux_bion)) then + do mm = 1, nbtrcr + flux_bion(mm,n) = flux_bion_n(mm) + enddo + endif + elseif (skl_bgc) then - call sklbio (dt, ntrcr, & - nbtrcr, n_algae, & - n_doc, & - n_dic, n_don, & - n_fed, n_fep, & + call sklbio (dt, Tf, & flux_bio (1:nbtrcr), ocean_bio(1:nbtrcr), & aicen (n), & meltbn (n), congeln (n), & @@ -998,6 +889,20 @@ subroutine icepack_biogeochemistry(dt, & first_ice(n) = .false. + else + if (z_tracers) then + do mm = 1, nbtrcr + do k = 1, nblyr+1 + if (present(flux_bion)) then + flux_bion(mm,n) = flux_bion(mm,n) + trcrn(bio_index(mm) + k-1,n) * & + hin_old(n) * zspace(k)/dt * trcrn(nt_fbri,n) + endif + flux_bio(mm) = flux_bio(mm) + trcrn(bio_index(mm) + k-1,n) * & + vicen_init(n) * zspace(k)/dt * trcrn(nt_fbri,n) + trcrn(bio_index(mm) + k-1,n) = c0 + enddo + enddo + endif endif ! aicen > puny enddo ! ncat @@ -1007,20 +912,10 @@ end subroutine icepack_biogeochemistry !autodocument_start icepack_load_ocean_bio_array ! basic initialization for ocean_bio_all - subroutine icepack_load_ocean_bio_array(max_nbtrcr, & - max_algae, max_don, max_doc, max_dic, max_aero, max_fe, & + subroutine icepack_load_ocean_bio_array(& nit, amm, sil, dmsp, dms, algalN, & doc, don, dic, fed, fep, zaeros, ocean_bio_all, hum) - integer (kind=int_kind), intent(in) :: & - max_algae , & ! maximum number of algal types - max_dic , & ! maximum number of dissolved inorganic carbon types - max_doc , & ! maximum number of dissolved organic carbon types - max_don , & ! maximum number of dissolved organic nitrogen types - max_fe , & ! maximum number of iron types - max_aero , & ! maximum number of aerosols - max_nbtrcr ! maximum number of bio tracers - real (kind=dbl_kind), intent(in) :: & nit , & ! ocean nitrate (mmol/m^3) amm , & ! ammonia/um (mmol/m^3) @@ -1029,25 +924,25 @@ subroutine icepack_load_ocean_bio_array(max_nbtrcr, & dms , & ! dms (mmol/m^3) hum ! humic material (mmol/m^3) - real (kind=dbl_kind), dimension (max_algae), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & algalN ! ocean algal nitrogen (mmol/m^3) (diatoms, phaeo, pico) - real (kind=dbl_kind), dimension (max_doc), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & doc ! ocean doc (mmol/m^3) (proteins, EPS, lipid) - real (kind=dbl_kind), dimension (max_don), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & don ! ocean don (mmol/m^3) - real (kind=dbl_kind), dimension (max_dic), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & dic ! ocean dic (mmol/m^3) - real (kind=dbl_kind), dimension (max_fe), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & fed, fep ! ocean disolved and particulate fe (nM) - real (kind=dbl_kind), dimension (max_aero), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & zaeros ! ocean aerosols (mmol/m^3) - real (kind=dbl_kind), dimension (max_nbtrcr), intent(inout) :: & + real (kind=dbl_kind), dimension (:), intent(out) :: & ocean_bio_all ! fixed order, all values even for tracers false !autodocument_end @@ -1120,16 +1015,9 @@ end subroutine icepack_load_ocean_bio_array ! Initialize ocean concentration subroutine icepack_init_ocean_bio (amm, dmsp, dms, algalN, doc, dic, don, & - fed, fep, hum, nit, sil, zaeros, max_dic, max_don, max_fe, max_aero,& - CToN, CToN_DON) - - integer (kind=int_kind), intent(in) :: & - max_dic, & - max_don, & - max_fe, & - max_aero + fed, fep, hum, nit, sil, zaeros,CToN, CToN_DON) - real (kind=dbl_kind), intent(out):: & + real (kind=dbl_kind), intent(out), optional:: & amm , & ! ammonium dmsp , & ! DMSPp dms , & ! DMS @@ -1137,7 +1025,7 @@ subroutine icepack_init_ocean_bio (amm, dmsp, dms, algalN, doc, dic, don, & nit , & ! nitrate sil ! silicate - real (kind=dbl_kind), dimension(:), intent(out):: & + real (kind=dbl_kind), dimension(:), intent(out), optional:: & algalN , & ! algae doc , & ! DOC dic , & ! DIC @@ -1146,7 +1034,7 @@ subroutine icepack_init_ocean_bio (amm, dmsp, dms, algalN, doc, dic, don, & fep , & ! Particulate Iron zaeros ! BC and dust - real (kind=dbl_kind), dimension(:), intent(inout), optional :: & + real (kind=dbl_kind), dimension(:), intent(out), optional :: & CToN , & ! carbon to nitrogen ratio for algae CToN_DON ! nitrogen to carbon ratio for proteins @@ -1160,50 +1048,153 @@ subroutine icepack_init_ocean_bio (amm, dmsp, dms, algalN, doc, dic, don, & character(len=*),parameter :: subname='(icepack_init_ocean_bio)' if (present(CToN)) then - CToN(1) = R_C2N(1) - CToN(2) = R_C2N(2) - CToN(3) = R_C2N(3) + CToN(:) = c0 + CToN(1) = R_C2N(1) + CToN(2) = R_C2N(2) + CToN(3) = R_C2N(3) endif if (present(CToN_DON)) then - CToN_DON(1) = R_C2N_DON(1) + CToN_DON(:) = c0 + CToN_DON(1) = R_C2N_DON(1) endif - amm = c1 ! ISPOL < 1 mmol/m^3 - dmsp = p1 - dms = p1 - algalN(1) = c1 !0.0026_dbl_kind ! ISPOL, Lannuzel 2013(pennate) - algalN(2) = 0.0057_dbl_kind ! ISPOL, Lannuzel 2013(small plankton) - algalN(3) = 0.0027_dbl_kind ! ISPOL, Lannuzel 2013(Phaeocystis) - ! 0.024_dbl_kind ! 5% of 1 mgchl/m^3 - doc(1) = 16.2_dbl_kind ! 18% saccharides - doc(2) = 9.0_dbl_kind ! lipids - doc(3) = c1 ! - do k = 1, max_dic - dic(k) = c1 - enddo - do k = 1, max_don - don(k) = 12.9_dbl_kind - ! 64.3_dbl_kind ! 72% Total DOC~90 mmolC/m^3 ISPOL with N:C of 0.2 - enddo - !ki = 1 - !if (trim(fe_data_type) == 'clim') ki = 2 - do k = 1, max_fe ! ki, max_fe - fed(k) = 0.4_dbl_kind ! c1 (nM) Lannuzel2007 DFe, - ! range 0.14-2.6 (nM) van der Merwe 2011 - ! Tagliabue 2012 (0.4 nM) - fep(k) = c2 ! (nM) van der Merwe 2011 - ! (0.6 to 2.9 nM ocean) - enddo - hum = c1 ! mmol C/m^3 - nit = 12.0_dbl_kind - sil = 25.0_dbl_kind - do k = 1, max_aero - zaeros(k) = c0 - enddo - + if (present(amm)) & + amm = c1 ! ISPOL < 1 mmol/m^3 + if (present(dmsp)) & + dmsp = p1 + if (present(dms)) & + dms = p1 + if (present(algalN)) then + algalN(:) = c0 + algalN(1) = c1 !0.0026_dbl_kind ! ISPOL, Lannuzel 2013(pennate) + algalN(2) = 0.0057_dbl_kind ! ISPOL, Lannuzel 2013(small plankton) + algalN(3) = 0.0027_dbl_kind ! ISPOL, Lannuzel 2013(Phaeocystis) + endif + if (present(doc))then + doc(:) = c0 + doc(1) = 16.2_dbl_kind ! 18% saccharides + doc(2) = 9.0_dbl_kind ! lipids + doc(3) = c1 ! + endif + if (present(dic)) then + dic(:) = c0 + dic(1) = 1950.0_dbl_kind ! 1950-2260 mmol C/m3 (Tynan et al. 2015) + endif + if (present(don)) then + don(:) = c0 + don(1) = 12.9_dbl_kind ! 64.3_dbl_kind ! 72% Total DOC~90 mmolC/m^3 ISPOL with N:C of 0.2 + endif + if (present(fed)) then + fed(:) = c0 + fed(1) = 0.4_dbl_kind ! c1 (nM) Lannuzel2007 DFe,! range 0.14-2.6 (nM) van der Merwe 2011 + ! Tagliabue 2012 (0.4 nM) + endif + if (present(fep)) then + fep(:) = c0 + fep(1) = c2 ! (nM) van der Merwe 2011 + ! (0.6 to 2.9 nM ocean) + endif + if (present(hum)) & + hum = c1 ! mmol C/m^3 + if (present(nit)) & + nit = 12.0_dbl_kind + if (present(sil)) & + sil = 25.0_dbl_kind + if (present(zaeros)) & + zaeros(:) = c0 end subroutine icepack_init_ocean_bio +! +!======================================================================= +! +! Given some added new ice to the base of the existing ice, recalculate +! vertical bio tracer so that new grid cells are all the same size. +! +! author: N. Jeffery, LANL +! date : Mar 3, 2024 +! +! Based on update_vertical_tracers modified for vertical biogeochemistry +! + subroutine update_vertical_bio_tracers(nbiolyr, trc, h1, h2, trc0, zspace) + + integer (kind=int_kind), intent(in) :: & + nbiolyr ! number of bio layers nblyr+1 + + real (kind=dbl_kind), dimension(:), intent(inout) :: & + trc ! vertical tracer + + real (kind=dbl_kind), intent(in) :: & + h1, & ! old thickness + h2, & ! new thickness + trc0 ! tracer value of added ice on ice bottom + + real (kind=dbl_kind), dimension(nbiolyr), intent(in) :: & + zspace + + ! local variables + + real(kind=dbl_kind), dimension(nbiolyr) :: trc2 ! updated tracer temporary + + ! vertical indices for old and new grid + integer :: k1, k2 + + real (kind=dbl_kind) :: & + z1a, z1b, & ! upper, lower boundary of old cell/added new ice at bottom + z2a, z2b, & ! upper, lower boundary of new cell + overlap , & ! overlap between old and new cell + rnilyr + + !rnilyr = real(nilyr,dbl_kind) + z2a = c0 + z2b = c0 + if (h2 > puny) then + ! loop over new grid cells + do k2 = 1, nbiolyr + + ! initialize new tracer + trc2(k2) = c0 + + ! calculate upper and lower boundary of new cell + z2a = z2b !((k2 - 1) * h2) * zspace(k2)+z2b ! / rnilyr + z2b = z2b + h2 * zspace(k2) !(k2 * h2) * zspace(k2)+z2a !/ rnilyr + + z1a = c0 + z1b = c0 + ! loop over old grid cells + do k1 = 1, nbiolyr + + ! calculate upper and lower boundary of old cell + z1a = z1b !((k1 - 1) * h1) * zspace(k1)+z1b !/ rnilyr + z1b = z1b + h1 * zspace(k1) !(k1 * h1) * zspace(k1)+z1a !/ rnilyr + + ! calculate overlap between old and new cell + overlap = max(min(z1b, z2b) - max(z1a, z2a), c0) + + ! aggregate old grid cell contribution to new cell + trc2(k2) = trc2(k2) + overlap * trc(k1) + + enddo ! k1 + + ! calculate upper and lower boundary of added new ice at bottom + z1a = h1 + z1b = h2 + + ! calculate overlap between added ice and new cell + overlap = max(min(z1b, z2b) - max(z1a, z2a), c0) + ! aggregate added ice contribution to new cell + trc2(k2) = trc2(k2) + overlap * trc0 + ! renormalize new grid cell + trc2(k2) = trc2(k2)/zspace(k2)/h2 !(rnilyr * trc2(k2)) / h2 + + enddo ! k2 + else + trc2 = trc + endif + ! update vertical tracer array with the adjusted tracer + trc = trc2 + + end subroutine update_vertical_bio_tracers !======================================================================= diff --git a/columnphysics/icepack_zbgc_shared.F90 b/columnphysics/icepack_zbgc_shared.F90 index 757044a89..08c6753d5 100644 --- a/columnphysics/icepack_zbgc_shared.F90 +++ b/columnphysics/icepack_zbgc_shared.F90 @@ -14,9 +14,11 @@ module icepack_zbgc_shared use icepack_parameters, only: rhoi, cp_ocn, cp_ice, Lfresh use icepack_parameters, only: solve_zbgc use icepack_parameters, only: fr_resp - use icepack_tracers, only: max_nbtrcr, max_algae, max_doc - use icepack_tracers, only: max_don - use icepack_tracers, only: nt_bgc_N, nt_fbri + use icepack_tracers, only: nbtrcr, ntrcr, nblyr, nilyr, nslyr + use icepack_tracers, only: n_algae + use icepack_tracers, only: max_nbtrcr, max_algae, max_doc, max_fe + use icepack_tracers, only: max_don, max_aero, max_dic + use icepack_tracers, only: nt_bgc_N, nt_fbri, nlt_bgc_N use icepack_warnings, only: warnstr, icepack_warnings_add use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted @@ -57,7 +59,7 @@ module icepack_zbgc_shared real (kind=dbl_kind), dimension(max_don), public :: & ! increase compare to algal R_Fe2C R_C2N_DON - real (kind=dbl_kind), dimension(max_algae), public :: & + real (kind=dbl_kind), dimension(max_algae), public :: & R_Si2N , & ! algal Sil to N (mole/mole) R_S2N , & ! algal S to N (mole/mole) ! Marchetti et al 2006, 3 umol Fe/mol C for iron limited Pseudo-nitzschia @@ -100,6 +102,15 @@ module icepack_zbgc_shared ! general biogeochemistry !----------------------------------------------------------------- + real (kind=dbl_kind), parameter, dimension(max_algae), public :: & + graze_exponent = (/ 0.333_dbl_kind, c1, c1/) ! Implicit grazing exponent (Dunneet al. 2005) + + real (kind=dbl_kind), parameter, public :: & + graze_conc = 1.36_dbl_kind, & ! (mmol N/m^3) converted from Dunne et al 2005 + ! data fit for phytoplankton (1.9 mmol C/m^3) to + ! ice algal N with 20% porosity and C/N = 7 + large_bgc = 1.0e8_dbl_kind ! warning value for large bgc concentrations (mmol/m^3) + real (kind=dbl_kind), dimension(max_nbtrcr), public :: & zbgc_frac_init,&! initializes mobile fraction bgc_tracer_type ! described tracer in mobile or stationary phases @@ -141,6 +152,29 @@ module icepack_zbgc_shared f_exude , & ! fraction of exuded carbon to each DOC pool k_bac ! Bacterial degredation of DOC (1/d) + ! polysaccharids, lipids, proteins+nucleic acids (Lonborg et al. 2020) + real (kind=dbl_kind), dimension(max_doc), parameter, public :: & + doc_pool_fractions = (/0.26_dbl_kind, 0.17_dbl_kind, 0.57_dbl_kind/) + + real (kind=dbl_kind), dimension(max_algae), public :: & + algaltype ! mobility type for algae + + real (kind=dbl_kind), dimension(max_doc), public :: & + doctype ! mobility type for DOC + + real (kind=dbl_kind), dimension(max_dic), public :: & + dictype ! mobility type for DIC + + real (kind=dbl_kind), dimension(max_don), public :: & + dontype ! mobility type for DON + + real (kind=dbl_kind), dimension(max_fe), public :: & + fedtype, & ! mobility type for iron + feptype + + real (kind=dbl_kind), dimension(max_aero), public :: & + zaerotype ! mobility type for aerosols + !----------------------------------------------------------------- ! brine !----------------------------------------------------------------- @@ -163,6 +197,13 @@ module icepack_zbgc_shared Dm = 1.0e-9_dbl_kind, & ! molecular diffusion (m^2/s) Ra_c = 0.05_dbl_kind ! critical Rayleigh number for bottom convection + real (kind=dbl_kind), dimension (:), allocatable, public :: & + bgrid , & ! biology nondimensional vertical grid points + igrid , & ! biology vertical interface points + cgrid , & ! CICE vertical coordinate + icgrid , & ! interface grid for CICE (shortwave variable) + swgrid ! grid for ice tracers used in dEdd scheme + !======================================================================= contains @@ -397,15 +438,10 @@ end subroutine zap_small_bgc subroutine regrid_stationary (C_stationary, hbri_old, & hbri, dt, & - ntrcr, nblyr, & top_conc, igrid, & flux_bio, & melt_b, con_gel) - integer (kind=int_kind), intent(in) :: & - ntrcr, & ! number of tracers - nblyr ! number of bio layers - real (kind=dbl_kind), intent(inout) :: & flux_bio ! ocean tracer flux (mmol/m^2/s) positive into ocean @@ -548,13 +584,12 @@ end subroutine regrid_stationary ! Aggregate flux information from all ice thickness categories ! for z layer biogeochemistry ! - subroutine merge_bgc_fluxes (dt, nblyr, & - nslyr, & - bio_index, n_algae, & - nbtrcr, aicen, & + subroutine merge_bgc_fluxes (dt, & + bio_index, & + aicen, & vicen, vsnon, & - iphin, & - trcrn, & + iphin, & + trcrn, aice_init, & flux_bion, flux_bio, & upNOn, upNHn, & upNO, upNH, & @@ -562,28 +597,29 @@ subroutine merge_bgc_fluxes (dt, nblyr, & zbgc_snow, zbgc_atm, & PP_net, ice_bio_net,& snow_bio_net, grow_alg, & - grow_net) + grow_net, totalChla, & + iTin, iSin, & + bioPorosityIceCell, & + bioSalinityIceCell, & + bioTemperatureIceCell) real (kind=dbl_kind), intent(in) :: & dt ! timestep (s) - integer (kind=int_kind), intent(in) :: & - nblyr , & ! number of bio layers - nslyr , & ! number of snow layers - n_algae , & ! number of algal tracers - nbtrcr ! number of biology tracer tracers - integer (kind=int_kind), dimension(:), intent(in) :: & bio_index ! relates bio indices, ie. nlt_bgc_N to nt_bgc_N real (kind=dbl_kind), dimension (:), intent(in) :: & trcrn , & ! input tracer fields - iphin ! porosity + iphin , & ! porosity + iTin , & ! temperature per cat on vertical bio interface points (oC) + iSin ! salinity per cat on vertical bio interface points (ppt) real (kind=dbl_kind), intent(in):: & aicen , & ! concentration of ice vicen , & ! volume of ice (m) - vsnon ! volume of snow(m) + vsnon , & ! volume of snow(m) + aice_init ! initial concentration of ice ! single category rates real (kind=dbl_kind), dimension(:), intent(in):: & @@ -605,6 +641,11 @@ subroutine merge_bgc_fluxes (dt, nblyr, & ice_bio_net, & ! integrated ice tracers mmol or mg/m^2) snow_bio_net ! integrated snow tracers mmol or mg/m^2) + real (kind=dbl_kind), optional, dimension(:), intent(inout):: & + bioPorosityIceCell, & ! average cell porosity on interface points + bioSalinityIceCell, & ! average cell salinity on interface points (ppt) + bioTemperatureIceCell ! average cell temperature on interface points (oC) + ! cumulative variables and rates real (kind=dbl_kind), intent(inout):: & PP_net , & ! net PP (mg C/m^2/d) times aice @@ -612,6 +653,10 @@ subroutine merge_bgc_fluxes (dt, nblyr, & upNO , & ! tot nitrate uptake rate (mmol/m^2/d) times aice upNH ! tot ammonium uptake rate (mmol/m^2/d) times aice + ! cumulative variables and rates + real (kind=dbl_kind), optional, intent(inout):: & + totalChla ! total Chla (mg chla/m^2) + ! local variables real (kind=dbl_kind) :: & @@ -645,18 +690,25 @@ subroutine merge_bgc_fluxes (dt, nblyr, & !----------------------------------------------------------------- ! Merge fluxes !----------------------------------------------------------------- - dvssl = min(p5*vsnon/real(nslyr,kind=dbl_kind), hs_ssl*aicen) ! snow surface layer - dvint = vsnon - dvssl ! snow interior + dvssl = p5*vsnon/real(nslyr,kind=dbl_kind) !snow surface layer + dvint = vsnon - dvssl ! snow interior snow_bio_net(mm) = snow_bio_net(mm) & + trcrn(bio_index(mm)+nblyr+1)*dvssl & + trcrn(bio_index(mm)+nblyr+2)*dvint flux_bio (mm) = flux_bio (mm) + flux_bion (mm)*aicen zbgc_snow (mm) = zbgc_snow(mm) + zbgc_snown(mm)*aicen/dt zbgc_atm (mm) = zbgc_atm (mm) + zbgc_atmn (mm)*aicen/dt - enddo ! mm + enddo ! mm + ! diagnostics : mean cell bio interface grid profiles + do k = 1, nblyr+1 + if (present(bioPorosityIceCell)) bioPorosityIceCell(k) = bioPorosityIceCell(k) + iphin(k)*vicen + if (present(bioSalinityIceCell)) bioSalinityIceCell(k) = bioSalinityIceCell(k) + iSin(k)*vicen + if (present(bioTemperatureIceCell)) bioTemperatureIceCell(k) = bioTemperatureIceCell(k) + iTin(k)*vicen + end do if (solve_zbgc) then do mm = 1, n_algae + if (present(totalChla)) totalChla = totalChla + ice_bio_net(nlt_bgc_N(mm))*R_chl2N(mm) do k = 1, nblyr+1 tmp = iphin(k)*trcrn(nt_fbri)*vicen*zspace(k)*secday PP_net = PP_net + grow_alg(k,mm)*tmp & @@ -678,7 +730,7 @@ end subroutine merge_bgc_fluxes ! ! author: Elizabeth C. Hunke and William H. Lipscomb, LANL - subroutine merge_bgc_fluxes_skl (nbtrcr, n_algae, & + subroutine merge_bgc_fluxes_skl ( & aicen, trcrn, & flux_bion, flux_bio, & PP_net, upNOn, & @@ -686,10 +738,6 @@ subroutine merge_bgc_fluxes_skl (nbtrcr, n_algae, & upNH, grow_net, & grow_alg) - integer (kind=int_kind), intent(in) :: & - nbtrcr , & ! number of bgc tracers - n_algae ! number of autotrophs - ! single category fluxes real (kind=dbl_kind), intent(in):: & aicen ! category ice area fraction diff --git a/configuration/driver/icedrv_InitMod.F90 b/configuration/driver/icedrv_InitMod.F90 index 107ffdc7f..c077a9203 100644 --- a/configuration/driver/icedrv_InitMod.F90 +++ b/configuration/driver/icedrv_InitMod.F90 @@ -13,7 +13,7 @@ module icedrv_InitMod use icepack_intfc, only: icepack_query_parameters, icepack_query_tracer_flags use icepack_intfc, only: icepack_write_tracer_flags, icepack_write_tracer_indices use icepack_intfc, only: icepack_write_tracer_sizes, icepack_write_parameters - use icedrv_system, only: icedrv_system_abort + use icedrv_system, only: icedrv_system_abort, icedrv_system_flush implicit none private @@ -81,14 +81,14 @@ subroutine icedrv_initialize call init_calendar ! initialize some calendar stuff call init_coupler_flux ! initialize fluxes exchanged with coupler call init_thermo_vertical ! initialize vertical thermodynamics - call icepack_init_itd(ncat=ncat, hin_max=hin_max) + call icepack_init_itd(hin_max=hin_max) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted(subname)) then call icedrv_system_abort(file=__FILE__,line=__LINE__) endif - call icepack_init_itd_hist(ncat=ncat, c_hi_range=c_hi_range, hin_max=hin_max) ! output + call icepack_init_itd_hist(c_hi_range=c_hi_range, hin_max=hin_max) ! output call icepack_query_tracer_flags(tr_fsd_out=tr_fsd) call icepack_warnings_flush(nu_diag) @@ -98,7 +98,6 @@ subroutine icedrv_initialize if (tr_fsd) then call icepack_init_fsd_bounds( & - nfsd=nfsd, & ! floe size distribution floe_rad_l=floe_rad_l, & ! fsd size lower bound in m (radius) floe_rad_c=floe_rad_c, & ! fsd size bin centre in m (radius) floe_binwidth=floe_binwidth, & ! fsd size bin width in m (radius) @@ -166,6 +165,8 @@ subroutine icedrv_initialize call init_flux_atm_ocn ! initialize atmosphere, ocean fluxes + call icedrv_system_flush(nu_diag) + end subroutine icedrv_initialize !======================================================================= @@ -234,8 +235,7 @@ subroutine init_restart !----------------------------------------------------------------- do i = 1, nx if (tmask(i)) & - call icepack_aggregate(ncat=ncat, & - aicen=aicen(i,:), & + call icepack_aggregate(aicen=aicen(i,:), & vicen=vicen(i,:), & vsnon=vsnon(i,:), & trcrn=trcrn(i,:,:), & @@ -244,7 +244,6 @@ subroutine init_restart vsno=vsno (i), & trcr=trcr (i,:), & aice0=aice0(i), & - ntrcr=max_ntrcr, & trcr_depend=trcr_depend, & trcr_base=trcr_base, & n_trcr_strata=n_trcr_strata, & diff --git a/configuration/driver/icedrv_MAIN.F90 b/configuration/driver/icedrv_MAIN.F90 index 8d76f63ca..c8564d4e8 100644 --- a/configuration/driver/icedrv_MAIN.F90 +++ b/configuration/driver/icedrv_MAIN.F90 @@ -30,11 +30,12 @@ program icedrv use icedrv_constants, only: ice_stdout, nu_diag, nu_diag_out use icedrv_domain_size, only: nx use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted - use icedrv_system, only: icedrv_system_abort + use icedrv_system, only: icedrv_system_abort, icedrv_system_flush implicit none integer n + logical openflag character(len=*), parameter :: subname='(icedrv)' !----------------------------------------------------------------- @@ -55,10 +56,24 @@ program icedrv write(ice_stdout, *) "ICEPACK COMPLETED SUCCESSFULLY " - close (ice_stdout) - close (nu_diag) + inquire(unit=ice_stdout,opened=openflag) + if (openflag) then + call icedrv_system_flush(ice_stdout) + close (ice_stdout) + endif + + inquire(unit=nu_diag,opened=openflag) + if (openflag) then + call icedrv_system_flush(nu_diag) + close (nu_diag) + endif + do n = 1, nx - close (nu_diag_out+n-1) + inquire(unit=nu_diag_out+n-1,opened=openflag) + if (openflag) then + call icedrv_system_flush(nu_diag_out+n-1) + close (nu_diag_out+n-1) + endif enddo end program icedrv diff --git a/configuration/driver/icedrv_RunMod.F90 b/configuration/driver/icedrv_RunMod.F90 index e20ebf87b..a7bc82bde 100644 --- a/configuration/driver/icedrv_RunMod.F90 +++ b/configuration/driver/icedrv_RunMod.F90 @@ -13,7 +13,7 @@ module icedrv_RunMod use icepack_intfc, only: icepack_query_parameters use icepack_intfc, only: icepack_query_tracer_flags use icepack_intfc, only: icepack_query_tracer_sizes - use icedrv_system, only: icedrv_system_abort + use icedrv_system, only: icedrv_system_abort, icedrv_system_flush implicit none private @@ -83,6 +83,8 @@ subroutine icedrv_run call init_flux_atm_ocn ! initialize atmosphere, ocean fluxes + call icedrv_system_flush(nu_diag) + enddo timeLoop end subroutine icedrv_run diff --git a/configuration/driver/icedrv_arrays_column.F90 b/configuration/driver/icedrv_arrays_column.F90 index 61017c6b8..b55f129f4 100644 --- a/configuration/driver/icedrv_arrays_column.F90 +++ b/configuration/driver/icedrv_arrays_column.F90 @@ -122,17 +122,6 @@ module icedrv_arrays_column ! biogeochemistry components - real (kind=dbl_kind), dimension (nblyr+2), public :: & - bgrid ! biology nondimensional vertical grid points - - real (kind=dbl_kind), dimension (nblyr+1), public :: & - igrid ! biology vertical interface points - - real (kind=dbl_kind), dimension (nilyr+1), public :: & - cgrid , & ! CICE vertical coordinate - icgrid , & ! interface grid for CICE (shortwave variable) - swgrid ! grid for ice tracers used in dEdd scheme - real (kind=dbl_kind), dimension (nx,ncat), public :: & first_ice_real ! .true. = c1, .false. = c0 @@ -209,10 +198,6 @@ module icedrv_arrays_column chl_net , & ! Total chla (mg chla/m^2) per grid cell NO_net ! Total nitrate per grid cell - real (kind=dbl_kind), & - dimension (nx,ncat), public :: & - sice_rho ! avg sea ice density (kg/m^3) ! ech: diagnostic only? - real (kind=dbl_kind), dimension (nx,nblyr+1,ncat), public :: & zfswin ! Shortwave flux into layers interpolated on bio grid (W/m^2) diff --git a/configuration/driver/icedrv_diagnostics.F90 b/configuration/driver/icedrv_diagnostics.F90 index eaa44d5e1..4ca0cb825 100644 --- a/configuration/driver/icedrv_diagnostics.F90 +++ b/configuration/driver/icedrv_diagnostics.F90 @@ -14,7 +14,7 @@ module icedrv_diagnostics use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted use icepack_intfc, only: icepack_query_parameters use icepack_intfc, only: icepack_query_tracer_flags, icepack_query_tracer_indices - use icedrv_system, only: icedrv_system_abort + use icedrv_system, only: icedrv_system_abort, icedrv_system_flush implicit none private @@ -267,6 +267,7 @@ subroutine runtime_diags (dt) write(nu_diag_out+n-1,901) 'isotopic conc chg = ',pdiso(n,k),k enddo endif + call icedrv_system_flush(nu_diag_out+n-1) end do 899 format (43x,a24) 900 format (a25,2x,f24.17) @@ -612,6 +613,7 @@ subroutine print_state(plabel,i) write(nu_diag,*) ' ' call icepack_warnings_flush(nu_diag) + call icedrv_system_flush(nu_diag) end subroutine print_state diff --git a/configuration/driver/icedrv_domain_size.F90 b/configuration/driver/icedrv_domain_size.F90 index 75bb4d28e..514045558 100644 --- a/configuration/driver/icedrv_domain_size.F90 +++ b/configuration/driver/icedrv_domain_size.F90 @@ -34,7 +34,6 @@ module icedrv_domain_size ! *** add to kscavz in icepack_zbgc_shared.F90 n_bgc = (n_algae*2 + n_doc + n_dic + n_don + n_fed + n_fep + n_zaero & + 8) , & ! nit, am, sil, dmspp, dmspd, dms, pon, humic - nltrcr = (n_bgc*TRBGCZ)*TRBRI, & ! number of zbgc (includes zaero) max_nsw = (nilyr+nslyr+2) & ! total chlorophyll plus aerosols * (1+TRZAERO),& ! number of tracers active in shortwave calculation max_ntrcr = 1 & ! 1 = surface temperature diff --git a/configuration/driver/icedrv_init.F90 b/configuration/driver/icedrv_init.F90 index b64284104..ac1873498 100644 --- a/configuration/driver/icedrv_init.F90 +++ b/configuration/driver/icedrv_init.F90 @@ -21,7 +21,7 @@ module icedrv_init use icepack_intfc, only: icepack_query_tracer_sizes use icepack_intfc, only: icepack_query_tracer_indices use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted - use icedrv_system, only: icedrv_system_abort + use icedrv_system, only: icedrv_system_abort, icedrv_system_flush implicit none private @@ -925,6 +925,8 @@ subroutine input_data write(nu_diag,1020) 'nx = ', nx write(nu_diag,*)' ' + call icedrv_system_flush(nu_diag) + 1000 format (a30,2x,f9.2) ! a30 to align formatted, unformatted statements 1005 format (a30,2x,f10.6) ! float 1010 format (a30,2x,l6) ! logical @@ -1253,8 +1255,7 @@ subroutine init_state enddo if (tmask(i)) & - call icepack_aggregate(ncat=ncat, & - trcrn=trcrn(i,1:ntrcr,:), & + call icepack_aggregate(trcrn=trcrn(i,1:ntrcr,:), & aicen=aicen(i,:), & vicen=vicen(i,:), & vsnon=vsnon(i,:), & @@ -1263,7 +1264,6 @@ subroutine init_state vice=vice (i), & vsno=vsno (i), & aice0=aice0(i), & - ntrcr=ntrcr, & trcr_depend=trcr_depend(1:ntrcr), & trcr_base=trcr_base (1:ntrcr,:), & n_trcr_strata=n_trcr_strata(1:ntrcr), & @@ -1436,11 +1436,10 @@ subroutine set_state_var (nx, & Sprofile = salinz(i,:), & Tprofile = Tmltz(i,:), & Tsfc = Tsfc, & - nilyr=nilyr, nslyr=nslyr, & qin=qin(:), qsn=qsn(:)) ! floe size distribution - if (tr_fsd) call icepack_init_fsd(nfsd=nfsd, ice_ic=ice_ic, & + if (tr_fsd) call icepack_init_fsd(ice_ic=ice_ic, & floe_rad_c=floe_rad_c, & floe_binwidth=floe_binwidth, & afsd=trcrn(i,nt_fsd:nt_fsd+nfsd-1,n)) @@ -1508,10 +1507,9 @@ subroutine set_state_var (nx, & Sprofile = salinz(i,:), & Tprofile = Tmltz(i,:), & Tsfc = Tsfc, & - nilyr=nilyr, nslyr=nslyr, & qin=qin(:), qsn=qsn(:)) ! floe size distribution - if (tr_fsd) call icepack_init_fsd(nfsd=nfsd, ice_ic=ice_ic, & + if (tr_fsd) call icepack_init_fsd(ice_ic=ice_ic, & floe_rad_c=floe_rad_c, & floe_binwidth=floe_binwidth, & afsd=trcrn(i,nt_fsd:nt_fsd+nfsd-1,n)) diff --git a/configuration/driver/icedrv_init_column.F90 b/configuration/driver/icedrv_init_column.F90 index 9a22a5ff3..ef2754b81 100644 --- a/configuration/driver/icedrv_init_column.F90 +++ b/configuration/driver/icedrv_init_column.F90 @@ -29,7 +29,7 @@ module icedrv_init_column use icepack_intfc, only: icepack_init_bgc use icepack_intfc, only: icepack_init_ocean_bio, icepack_load_ocean_bio_array use icepack_intfc, only: icepack_init_hbrine - use icedrv_system, only: icedrv_system_abort + use icedrv_system, only: icedrv_system_abort, icedrv_system_flush implicit none @@ -69,7 +69,7 @@ subroutine init_thermo_vertical !----------------------------------------------------------------- call icepack_query_parameters(depressT_out=depressT) - call icepack_init_thermo(nilyr=nilyr, sprofile=sprofile) + call icepack_init_thermo(sprofile=sprofile) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & file=__FILE__, line=__LINE__) @@ -99,7 +99,6 @@ subroutine init_shortwave use icedrv_arrays_column, only: fswsfcn, ffracn, snowfracn use icedrv_arrays_column, only: fswthrun, fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf use icedrv_arrays_column, only: fswintn, albpndn, apeffn, trcrn_sw, dhsn - use icedrv_arrays_column, only: swgrid, igrid use icedrv_calendar, only: istep1, dt, yday, sec use icedrv_system, only: icedrv_system_abort use icedrv_forcing, only: snw_ssp_table @@ -247,8 +246,6 @@ subroutine init_shortwave if (tmask(i)) then call icepack_step_radiation ( & dt=dt, & - swgrid=swgrid(:), & - igrid=igrid(:), & fbri=fbri(:), & aicen=aicen(i,:), & vicen=vicen(i,:), & @@ -368,7 +365,7 @@ subroutine init_bgc() use icedrv_arrays_column, only: zfswin, trcrn_sw use icedrv_arrays_column, only: ocean_bio_all, ice_bio_net, snow_bio_net - use icedrv_arrays_column, only: cgrid, igrid, bphi, iDi, bTiz, iki + use icedrv_arrays_column, only: bphi, iDi, bTiz, iki use icedrv_calendar, only: istep1 use icedrv_system, only: icedrv_system_abort use icedrv_flux, only: sss, nit, amm, sil, dmsp, dms, algalN, & @@ -439,9 +436,7 @@ subroutine init_bgc() fed=fed(i,:), fep =fep(i,:), hum=hum(i), & nit=nit(i), sil =sil(i), & zaeros=zaeros(i,:), & - algalN=algalN(i,:), & - max_dic=max_dic, max_don =max_don, & - max_fe =max_fe, max_aero=max_aero) + algalN=algalN(i,:)) enddo ! i call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & @@ -451,9 +446,7 @@ subroutine init_bgc() do i = 1, nx - call icepack_load_ocean_bio_array(max_nbtrcr=max_nbtrcr, & - max_algae=max_algae, max_don=max_don, max_doc=max_doc, & - max_aero =max_aero, max_dic=max_dic, max_fe =max_fe, & + call icepack_load_ocean_bio_array( & nit =nit(i), amm=amm(i), sil =sil(i), & dmsp=dmsp(i), dms=dms(i), algalN=algalN(i,:), & doc =doc(i,:), don=don(i,:), dic =dic(i,:), & @@ -476,10 +469,10 @@ subroutine init_bgc() enddo enddo - call icepack_init_bgc(ncat=ncat, nblyr=nblyr, nilyr=nilyr, ntrcr_o=ntrcr_o, & - cgrid=cgrid, igrid=igrid, ntrcr=ntrcr, nbtrcr=nbtrcr, & - sicen=sicen(:,:), trcrn=trcrn_bgc(:,:), & + call icepack_init_bgc( & + sicen=sicen(:,:), trcrn=trcrn_bgc(:,:), & sss=sss(i), ocean_bio_all=ocean_bio_all(i,:)) +! optional DOCPoolFractions=DOCPoolFractions) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call icedrv_system_abort(i, istep1, subname, & __FILE__, __LINE__) @@ -493,8 +486,7 @@ end subroutine init_bgc subroutine init_hbrine() - use icedrv_arrays_column, only: first_ice, bgrid, igrid, cgrid - use icedrv_arrays_column, only: icgrid, swgrid + use icedrv_arrays_column, only: first_ice use icedrv_state, only: trcrn real (kind=dbl_kind) :: phi_snow @@ -515,8 +507,7 @@ subroutine init_hbrine() !----------------------------------------------------------------- - call icepack_init_hbrine(bgrid=bgrid, igrid=igrid, cgrid=cgrid, icgrid=icgrid, & - swgrid=swgrid, nblyr=nblyr, nilyr=nilyr, phi_snow=phi_snow) + call icepack_init_hbrine(phi_snow=phi_snow) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & file=__FILE__, line=__LINE__) @@ -618,9 +609,6 @@ subroutine init_zbgc tr_bgc_DON, tr_bgc_Fe, tr_zaero, & tr_bgc_hum, tr_aero - integer (kind=int_kind) :: & - ktherm - logical (kind=log_kind) :: & solve_zsal, skl_bgc, z_tracers, scale_bgc, solve_zbgc, dEdd_algae, & modal_aero, restore_bgc @@ -629,7 +617,7 @@ subroutine init_zbgc bgc_flux_type real (kind=dbl_kind) :: & - grid_o, l_sk, initbio_frac, & + grid_o, grid_o_t, l_sk, initbio_frac, & frazil_scav, grid_oS, l_skS, & phi_snow, & ratio_Si2N_diatoms , ratio_Si2N_sp , ratio_Si2N_phaeo , & @@ -663,6 +651,7 @@ subroutine init_zbgc algaltype_diatoms , algaltype_sp , algaltype_phaeo , & nitratetype , ammoniumtype , silicatetype , & dmspptype , dmspdtype , humtype , & + dictype_1 , & doctype_s , doctype_l , dontype_protein , & fedtype_1 , feptype_1 , zaerotype_bc1 , & zaerotype_bc2 , zaerotype_dust1 , zaerotype_dust2 , & @@ -779,10 +768,10 @@ subroutine init_zbgc namelist /zbgc_nml/ & tr_brine, tr_zaero, modal_aero, skl_bgc, & z_tracers, dEdd_algae, solve_zbgc, bgc_flux_type, & - restore_bgc, scale_bgc, solve_zsal, bgc_data_type, & + restore_bgc, scale_bgc, solve_zsal, & tr_bgc_Nit, tr_bgc_C, tr_bgc_chl, tr_bgc_Am, tr_bgc_Sil, & tr_bgc_DMS, tr_bgc_PON, tr_bgc_hum, tr_bgc_DON, tr_bgc_Fe, & - grid_o, l_sk, grid_oS, & + grid_o, grid_o_t, l_sk, grid_oS, & l_skS, phi_snow, initbio_frac, frazil_scav, & ratio_Si2N_diatoms , ratio_Si2N_sp , ratio_Si2N_phaeo , & ratio_S2N_diatoms , ratio_S2N_sp , ratio_S2N_phaeo , & @@ -815,6 +804,7 @@ subroutine init_zbgc algaltype_diatoms , algaltype_sp , algaltype_phaeo , & nitratetype , ammoniumtype , silicatetype , & dmspptype , dmspdtype , humtype , & + dictype_1 , & doctype_s , doctype_l , dontype_protein , & fedtype_1 , feptype_1 , zaerotype_bc1 , & zaerotype_bc2 , zaerotype_dust1 , zaerotype_dust2 , & @@ -828,20 +818,138 @@ subroutine init_zbgc !----------------------------------------------------------------- call icepack_query_tracer_sizes(ntrcr_out=ntrcr) - call icepack_query_tracer_flags(tr_aero_out=tr_aero) - call icepack_query_parameters(ktherm_out=ktherm, shortwave_out=shortwave, & + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & + file=__FILE__, line=__LINE__) + + call icepack_query_parameters(shortwave_out=shortwave, & scale_bgc_out=scale_bgc, skl_bgc_out=skl_bgc, z_tracers_out=z_tracers, & - dEdd_algae_out=dEdd_algae, solve_zbgc_out=solve_zbgc, phi_snow_out=phi_snow, & + dEdd_algae_out=dEdd_algae, solve_zbgc_out=solve_zbgc, grid_o_t_out=grid_o_t, & bgc_flux_type_out=bgc_flux_type, grid_o_out=grid_o, l_sk_out=l_sk, & initbio_frac_out=initbio_frac, frazil_scav_out=frazil_scav, & + grid_oS_out=grid_oS, l_skS_out=l_skS, phi_snow_out=phi_snow, & algal_vel_out=algal_vel, R_dFe2dust_out=R_dFe2dust, & dustFe_sol_out=dustFe_sol, T_max_out=T_max, fsal_out=fsal, & op_dep_min_out=op_dep_min, fr_graze_s_out=fr_graze_s, & fr_graze_e_out=fr_graze_e, fr_mort2min_out=fr_mort2min, & fr_dFe_out=fr_dFe, k_nitrif_out=k_nitrif, t_iron_conv_out=t_iron_conv, & - max_loss_out=max_loss, max_dfe_doc1_out=max_dfe_doc1, & + max_loss_out=max_loss, max_dfe_doc1_out=max_dfe_doc1, fr_resp_out=fr_resp, & fr_resp_s_out=fr_resp_s, y_sk_DMS_out=y_sk_DMS, t_sk_conv_out=t_sk_conv, & - t_sk_ox_out=t_sk_ox) + t_sk_ox_out=t_sk_ox, modal_aero_out=modal_aero, solve_zsal_out = solve_zsal) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & + file=__FILE__, line=__LINE__) + + call icepack_query_parameters ( & + ratio_Si2N_diatoms_out = ratio_Si2N_diatoms, & + ratio_Si2N_sp_out = ratio_Si2N_sp , & + ratio_Si2N_phaeo_out = ratio_Si2N_phaeo , & + ratio_S2N_diatoms_out = ratio_S2N_diatoms , & + ratio_S2N_sp_out = ratio_S2N_sp , & + ratio_S2N_phaeo_out = ratio_S2N_phaeo , & + ratio_Fe2C_diatoms_out = ratio_Fe2C_diatoms, & + ratio_Fe2C_sp_out = ratio_Fe2C_sp , & + ratio_Fe2C_phaeo_out = ratio_Fe2C_phaeo , & + ratio_Fe2N_diatoms_out = ratio_Fe2N_diatoms, & + ratio_Fe2N_sp_out = ratio_Fe2N_sp , & + ratio_Fe2N_phaeo_out = ratio_Fe2N_phaeo , & + ratio_C2N_diatoms_out = ratio_C2N_diatoms , & + ratio_C2N_sp_out = ratio_C2N_sp , & + ratio_C2N_phaeo_out = ratio_C2N_phaeo , & + ratio_C2N_proteins_out = ratio_C2N_proteins, & + ratio_chl2N_diatoms_out = ratio_chl2N_diatoms, & + ratio_chl2N_sp_out = ratio_chl2N_sp , & + ratio_chl2N_phaeo_out = ratio_chl2N_phaeo , & + ratio_Fe2DON_out = ratio_Fe2DON , & + ratio_Fe2DOC_s_out = ratio_Fe2DOC_s , & + ratio_Fe2DOC_l_out = ratio_Fe2DOC_l , & + F_abs_chl_diatoms_out = F_abs_chl_diatoms , & + F_abs_chl_sp_out = F_abs_chl_sp , & + F_abs_chl_phaeo_out = F_abs_chl_phaeo , & + tau_min_out = tau_min , & + tau_max_out = tau_max , & + chlabs_diatoms_out = chlabs_diatoms , & + chlabs_sp_out = chlabs_sp , & + chlabs_phaeo_out = chlabs_phaeo , & + alpha2max_low_diatoms_out = alpha2max_low_diatoms, & + alpha2max_low_sp_out = alpha2max_low_sp , & + alpha2max_low_phaeo_out = alpha2max_low_phaeo, & + beta2max_diatoms_out = beta2max_diatoms , & + beta2max_sp_out = beta2max_sp , & + beta2max_phaeo_out = beta2max_phaeo , & + mu_max_diatoms_out = mu_max_diatoms , & + mu_max_sp_out = mu_max_sp , & + mu_max_phaeo_out = mu_max_phaeo , & + grow_Tdep_diatoms_out = grow_Tdep_diatoms , & + grow_Tdep_sp_out = grow_Tdep_sp , & + grow_Tdep_phaeo_out = grow_Tdep_phaeo , & + fr_graze_diatoms_out = fr_graze_diatoms , & + fr_graze_sp_out = fr_graze_sp , & + fr_graze_phaeo_out = fr_graze_phaeo , & + mort_pre_diatoms_out = mort_pre_diatoms , & + mort_pre_sp_out = mort_pre_sp , & + mort_pre_phaeo_out = mort_pre_phaeo , & + mort_Tdep_diatoms_out = mort_Tdep_diatoms , & + mort_Tdep_sp_out = mort_Tdep_sp , & + mort_Tdep_phaeo_out = mort_Tdep_phaeo , & + k_exude_diatoms_out = k_exude_diatoms , & + k_exude_sp_out = k_exude_sp , & + k_exude_phaeo_out = k_exude_phaeo , & + K_Nit_diatoms_out = K_Nit_diatoms , & + K_Nit_sp_out = K_Nit_sp , & + K_Nit_phaeo_out = K_Nit_phaeo , & + K_Am_diatoms_out = K_Am_diatoms , & + K_Am_sp_out = K_Am_sp , & + K_Am_phaeo_out = K_Am_phaeo , & + K_Sil_diatoms_out = K_Sil_diatoms , & + K_Sil_sp_out = K_Sil_sp , & + K_Sil_phaeo_out = K_Sil_phaeo , & + K_Fe_diatoms_out = K_Fe_diatoms , & + K_Fe_sp_out = K_Fe_sp , & + K_Fe_phaeo_out = K_Fe_phaeo , & + f_doc_s_out = f_doc_s , & + f_doc_l_out = f_doc_l , & + f_don_protein_out = f_don_protein , & + kn_bac_protein_out = kn_bac_protein , & + f_don_Am_protein_out = f_don_Am_protein , & + f_exude_s_out = f_exude_s , & + f_exude_l_out = f_exude_l , & + k_bac_s_out = k_bac_s , & + k_bac_l_out = k_bac_l , & + algaltype_diatoms_out = algaltype_diatoms , & + algaltype_sp_out = algaltype_sp , & + algaltype_phaeo_out = algaltype_phaeo , & + dictype_1_out = dictype_1 , & + doctype_s_out = doctype_s , & + doctype_l_out = doctype_l , & + dontype_protein_out = dontype_protein , & + fedtype_1_out = fedtype_1 , & + feptype_1_out = feptype_1 , & + nitratetype_out = nitratetype , & + ammoniumtype_out = ammoniumtype , & + silicatetype_out = silicatetype , & + dmspptype_out = dmspptype , & + dmspdtype_out = dmspdtype , & + humtype_out = humtype , & + zaerotype_bc1_out = zaerotype_bc1 , & + zaerotype_bc2_out = zaerotype_bc2 , & + zaerotype_dust1_out = zaerotype_dust1 , & + zaerotype_dust2_out = zaerotype_dust2 , & + zaerotype_dust3_out = zaerotype_dust3 , & + zaerotype_dust4_out = zaerotype_dust4) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & + file=__FILE__, line=__LINE__) + + call icepack_query_tracer_flags(tr_aero_out = tr_aero, & + tr_zaero_out = tr_zaero, & + tr_brine_out = tr_brine , tr_bgc_Nit_out = tr_bgc_Nit, & + tr_bgc_Am_out = tr_bgc_Am , tr_bgc_Sil_out = tr_bgc_Sil, & + tr_bgc_DMS_out = tr_bgc_DMS, tr_bgc_PON_out = tr_bgc_PON, & + tr_bgc_N_out = tr_bgc_N , tr_bgc_C_out = tr_bgc_C , & + tr_bgc_chl_out = tr_bgc_chl, & + tr_bgc_DON_out = tr_bgc_DON, tr_bgc_Fe_out = tr_bgc_Fe , & + tr_bgc_hum_out = tr_bgc_hum) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & file=__FILE__, line=__LINE__) @@ -849,120 +957,8 @@ subroutine init_zbgc !----------------------------------------------------------------- ! default values !----------------------------------------------------------------- - tr_brine = .false. ! brine height differs from ice height - tr_zaero = .false. ! z aerosol tracers - modal_aero = .false. ! use modal aerosol treatment of aerosols - restore_bgc = .false. ! restore bgc if true - solve_zsal = .false. ! update salinity tracer profile from solve_S_dt - bgc_data_type = 'default'! source of bgc data - tr_bgc_PON = .false. !--------------------------------------------- - tr_bgc_Nit = .false. ! biogeochemistry (skl or zbgc) - tr_bgc_C = .false. ! if skl_bgc = .true. then skl - tr_bgc_chl = .false. ! if z_tracers = .true. then vertically resolved - tr_bgc_Sil = .false. ! if z_tracers + solve_zbgc = .true. then - tr_bgc_Am = .false. ! vertically resolved with reactions - tr_bgc_DMS = .false. !------------------------------------------------ - tr_bgc_DON = .false. ! - tr_bgc_hum = .false. ! - tr_bgc_Fe = .false. ! - tr_bgc_N = .true. ! - - ! z biology parameters - ratio_Si2N_diatoms = 1.8_dbl_kind ! algal Si to N (mol/mol) - ratio_Si2N_sp = c0 ! diatoms, small plankton, phaeocystis - ratio_Si2N_phaeo = c0 - ratio_S2N_diatoms = 0.03_dbl_kind ! algal S to N (mol/mol) - ratio_S2N_sp = 0.03_dbl_kind - ratio_S2N_phaeo = 0.03_dbl_kind - ratio_Fe2C_diatoms = 0.0033_dbl_kind ! algal Fe to C (umol/mol) - ratio_Fe2C_sp = 0.0033_dbl_kind - ratio_Fe2C_phaeo = p1 - ratio_Fe2N_diatoms = 0.023_dbl_kind ! algal Fe to N (umol/mol) - ratio_Fe2N_sp = 0.023_dbl_kind - ratio_Fe2N_phaeo = 0.7_dbl_kind - ratio_Fe2DON = 0.023_dbl_kind ! Fe to N of DON (nmol/umol) - ratio_Fe2DOC_s = p1 ! Fe to C of DOC (nmol/umol) saccharids - ratio_Fe2DOC_l = 0.033_dbl_kind ! Fe to C of DOC (nmol/umol) lipids - tau_min = 5200.0_dbl_kind ! rapid mobile to stationary exchanges (s) - tau_max = 1.73e5_dbl_kind ! long time mobile to stationary exchanges (s) - chlabs_diatoms = 0.03_dbl_kind ! chl absorption (1/m/(mg/m^3)) - chlabs_sp = 0.01_dbl_kind - chlabs_phaeo = 0.05_dbl_kind - alpha2max_low_diatoms = 0.8_dbl_kind ! light limitation (1/(W/m^2)) - alpha2max_low_sp = 0.67_dbl_kind - alpha2max_low_phaeo = 0.67_dbl_kind - beta2max_diatoms = 0.018_dbl_kind ! light inhibition (1/(W/m^2)) - beta2max_sp = 0.0025_dbl_kind - beta2max_phaeo = 0.01_dbl_kind - mu_max_diatoms = 1.2_dbl_kind ! maximum growth rate (1/day) - mu_max_sp = 0.851_dbl_kind - mu_max_phaeo = 0.851_dbl_kind - grow_Tdep_diatoms = 0.06_dbl_kind ! Temperature dependence of growth (1/C) - grow_Tdep_sp = 0.06_dbl_kind - grow_Tdep_phaeo = 0.06_dbl_kind - fr_graze_diatoms = 0.01_dbl_kind ! Fraction grazed - fr_graze_sp = p1 - fr_graze_phaeo = p1 - mort_pre_diatoms = 0.007_dbl_kind! Mortality (1/day) - mort_pre_sp = 0.007_dbl_kind - mort_pre_phaeo = 0.007_dbl_kind - mort_Tdep_diatoms = 0.03_dbl_kind ! T dependence of mortality (1/C) - mort_Tdep_sp = 0.03_dbl_kind - mort_Tdep_phaeo = 0.03_dbl_kind - k_exude_diatoms = c0 ! algal exudation (1/d) - k_exude_sp = c0 - k_exude_phaeo = c0 - K_Nit_diatoms = c1 ! nitrate half saturation (mmol/m^3) - K_Nit_sp = c1 - K_Nit_phaeo = c1 - K_Am_diatoms = 0.3_dbl_kind ! ammonium half saturation (mmol/m^3) - K_Am_sp = 0.3_dbl_kind - K_Am_phaeo = 0.3_dbl_kind - K_Sil_diatoms = 4.0_dbl_kind ! silicate half saturation (mmol/m^3) - K_Sil_sp = c0 - K_Sil_phaeo = c0 - K_Fe_diatoms = c1 ! iron half saturation (nM) - K_Fe_sp = 0.2_dbl_kind - K_Fe_phaeo = p1 - f_don_protein = 0.6_dbl_kind ! fraction of spilled grazing to proteins - kn_bac_protein = 0.03_dbl_kind ! Bacterial degredation of DON (1/d) - f_don_Am_protein = 0.25_dbl_kind ! fraction of remineralized DON to ammonium - f_doc_s = 0.4_dbl_kind ! fraction of mortality to DOC - f_doc_l = 0.4_dbl_kind - f_exude_s = c1 ! fraction of exudation to DOC - f_exude_l = c1 - k_bac_s = 0.03_dbl_kind ! Bacterial degredation of DOC (1/d) - k_bac_l = 0.03_dbl_kind - algaltype_diatoms = c0 ! ------------------ - algaltype_sp = p5 ! - algaltype_phaeo = p5 ! - nitratetype = -c1 ! mobility type between - ammoniumtype = c1 ! stationary <--> mobile - silicatetype = -c1 ! - dmspptype = p5 ! - dmspdtype = -c1 ! - humtype = c1 ! - doctype_s = p5 ! - doctype_l = p5 ! - dontype_protein = p5 ! - fedtype_1 = p5 ! - feptype_1 = p5 ! - zaerotype_bc1 = c1 ! - zaerotype_bc2 = c1 ! - zaerotype_dust1 = c1 ! - zaerotype_dust2 = c1 ! - zaerotype_dust3 = c1 ! - zaerotype_dust4 = c1 !-------------------- - ratio_C2N_diatoms = 7.0_dbl_kind ! algal C to N ratio (mol/mol) - ratio_C2N_sp = 7.0_dbl_kind - ratio_C2N_phaeo = 7.0_dbl_kind - ratio_chl2N_diatoms= 2.1_dbl_kind ! algal chlorophyll to N ratio (mg/mmol) - ratio_chl2N_sp = 1.1_dbl_kind - ratio_chl2N_phaeo = 0.84_dbl_kind - F_abs_chl_diatoms = 2.0_dbl_kind ! scales absorbed radiation for dEdd - F_abs_chl_sp = 4.0_dbl_kind - F_abs_chl_phaeo = 5.0_dbl_kind - ratio_C2N_proteins = 7.0_dbl_kind ! ratio of C to N in proteins (mol/mol) + + tr_bgc_N = .true. ! not a namelist?? !----------------------------------------------------------------- ! read from input file @@ -1022,6 +1018,14 @@ subroutine init_zbgc ! biogeochemistry !----------------------------------------------------------------- + ! deprecate skl bgc (Aug 2024) + ! no skl code removed yet + if (skl_bgc) then + write(nu_diag,*) 'ERROR: skl_bgc is not validate and temporarily DEPRECATED' + write(nu_diag,*) 'ERROR: if you would like to use skl_bgc, please contact the Consortium' + call icedrv_system_abort(file=__FILE__,line=__LINE__) + endif + if (.not. tr_brine) then if (solve_zbgc) then write(nu_diag,*) 'WARNING: tr_brine = F and solve_zbgc = T' @@ -1041,7 +1045,7 @@ subroutine init_zbgc endif if ((skl_bgc .AND. solve_zbgc) .or. (skl_bgc .AND. z_tracers)) then - print*, 'ERROR: skl_bgc and (solve_zbgc or z_tracers) are both true' + write(nu_diag,*) 'ERROR: skl_bgc and (solve_zbgc or z_tracers) are both true' call icedrv_system_abort(file=__FILE__,line=__LINE__) endif @@ -1073,27 +1077,27 @@ subroutine init_zbgc modal_aero = .false. endif if (n_algae > icepack_max_algae) then - print*, 'error:number of algal types exceeds icepack_max_algae' + write(nu_diag,*) 'error:number of algal types exceeds icepack_max_algae' call icedrv_system_abort(file=__FILE__,line=__LINE__) endif if (n_doc > icepack_max_doc) then - print*, 'error:number of algal types exceeds icepack_max_doc' + write(nu_diag,*) 'error:number of algal types exceeds icepack_max_doc' call icedrv_system_abort(file=__FILE__,line=__LINE__) endif if (n_dic > icepack_max_dic) then - print*, 'error:number of dic types exceeds icepack_max_dic' + write(nu_diag,*) 'error:number of dic types exceeds icepack_max_dic' call icedrv_system_abort(file=__FILE__,line=__LINE__) endif if (n_don > icepack_max_don) then - print*, 'error:number of don types exceeds icepack_max_don' + write(nu_diag,*) 'error:number of don types exceeds icepack_max_don' call icedrv_system_abort(file=__FILE__,line=__LINE__) endif if (n_fed > icepack_max_fe) then - print*, 'error:number of dissolved fe types exceeds icepack_max_fe' + write(nu_diag,*) 'error:number of dissolved fe types exceeds icepack_max_fe' call icedrv_system_abort(file=__FILE__,line=__LINE__) endif if (n_fep > icepack_max_fe) then - print*, 'error:number of particulate fe types exceeds icepack_max_fe' + write(nu_diag,*) 'error:number of particulate fe types exceeds icepack_max_fe' call icedrv_system_abort(file=__FILE__,line=__LINE__) endif @@ -1137,7 +1141,7 @@ subroutine init_zbgc if (tr_zaero .and. .not. z_tracers) z_tracers = .true. if (n_zaero > icepack_max_aero) then - print*, 'error:number of z aerosols exceeds icepack_max_aero' + write(nu_diag,*) 'error:number of z aerosols exceeds icepack_max_aero' call icedrv_system_abort(file=__FILE__,line=__LINE__) endif @@ -1169,9 +1173,9 @@ subroutine init_zbgc ! set Icepack values !----------------------------------------------------------------- - call icepack_init_parameters(ktherm_in=ktherm, shortwave_in=shortwave, & + call icepack_init_parameters( & scale_bgc_in=scale_bgc, skl_bgc_in=skl_bgc, z_tracers_in=z_tracers, & - dEdd_algae_in=dEdd_algae, solve_zbgc_in=solve_zbgc, & + dEdd_algae_in=dEdd_algae, solve_zbgc_in=solve_zbgc, grid_o_t_in=grid_o_t, & bgc_flux_type_in=bgc_flux_type, grid_o_in=grid_o, l_sk_in=l_sk, & initbio_frac_in=initbio_frac, frazil_scav_in=frazil_scav, & grid_oS_in=grid_oS, l_skS_in=l_skS, phi_snow_in=phi_snow, & @@ -1182,7 +1186,108 @@ subroutine init_zbgc fr_dFe_in=fr_dFe, k_nitrif_in=k_nitrif, t_iron_conv_in=t_iron_conv, & max_loss_in=max_loss, max_dfe_doc1_in=max_dfe_doc1, fr_resp_in=fr_resp, & fr_resp_s_in=fr_resp_s, y_sk_DMS_in=y_sk_DMS, t_sk_conv_in=t_sk_conv, & - t_sk_ox_in=t_sk_ox, modal_aero_in=modal_aero) + t_sk_ox_in=t_sk_ox, modal_aero_in=modal_aero, solve_zsal_in = solve_zsal) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & + file=__FILE__, line=__LINE__) + + call icepack_init_parameters ( & + ratio_Si2N_diatoms_in = ratio_Si2N_diatoms, & + ratio_Si2N_sp_in = ratio_Si2N_sp , & + ratio_Si2N_phaeo_in = ratio_Si2N_phaeo , & + ratio_S2N_diatoms_in = ratio_S2N_diatoms , & + ratio_S2N_sp_in = ratio_S2N_sp , & + ratio_S2N_phaeo_in = ratio_S2N_phaeo , & + ratio_Fe2C_diatoms_in = ratio_Fe2C_diatoms, & + ratio_Fe2C_sp_in = ratio_Fe2C_sp , & + ratio_Fe2C_phaeo_in = ratio_Fe2C_phaeo , & + ratio_Fe2N_diatoms_in = ratio_Fe2N_diatoms, & + ratio_Fe2N_sp_in = ratio_Fe2N_sp , & + ratio_Fe2N_phaeo_in = ratio_Fe2N_phaeo , & + ratio_C2N_diatoms_in = ratio_C2N_diatoms , & + ratio_C2N_sp_in = ratio_C2N_sp , & + ratio_C2N_phaeo_in = ratio_C2N_phaeo , & + ratio_C2N_proteins_in = ratio_C2N_proteins, & + ratio_chl2N_diatoms_in = ratio_chl2N_diatoms, & + ratio_chl2N_sp_in = ratio_chl2N_sp , & + ratio_chl2N_phaeo_in = ratio_chl2N_phaeo , & + ratio_Fe2DON_in = ratio_Fe2DON , & + ratio_Fe2DOC_s_in = ratio_Fe2DOC_s , & + ratio_Fe2DOC_l_in = ratio_Fe2DOC_l , & + F_abs_chl_diatoms_in = F_abs_chl_diatoms , & + F_abs_chl_sp_in = F_abs_chl_sp , & + F_abs_chl_phaeo_in = F_abs_chl_phaeo , & + tau_min_in = tau_min , & + tau_max_in = tau_max , & + chlabs_diatoms_in = chlabs_diatoms , & + chlabs_sp_in = chlabs_sp , & + chlabs_phaeo_in = chlabs_phaeo , & + alpha2max_low_diatoms_in = alpha2max_low_diatoms, & + alpha2max_low_sp_in = alpha2max_low_sp , & + alpha2max_low_phaeo_in = alpha2max_low_phaeo, & + beta2max_diatoms_in = beta2max_diatoms , & + beta2max_sp_in = beta2max_sp , & + beta2max_phaeo_in = beta2max_phaeo , & + mu_max_diatoms_in = mu_max_diatoms , & + mu_max_sp_in = mu_max_sp , & + mu_max_phaeo_in = mu_max_phaeo , & + grow_Tdep_diatoms_in = grow_Tdep_diatoms , & + grow_Tdep_sp_in = grow_Tdep_sp , & + grow_Tdep_phaeo_in = grow_Tdep_phaeo , & + fr_graze_diatoms_in = fr_graze_diatoms , & + fr_graze_sp_in = fr_graze_sp , & + fr_graze_phaeo_in = fr_graze_phaeo , & + mort_pre_diatoms_in = mort_pre_diatoms , & + mort_pre_sp_in = mort_pre_sp , & + mort_pre_phaeo_in = mort_pre_phaeo , & + mort_Tdep_diatoms_in = mort_Tdep_diatoms , & + mort_Tdep_sp_in = mort_Tdep_sp , & + mort_Tdep_phaeo_in = mort_Tdep_phaeo , & + k_exude_diatoms_in = k_exude_diatoms , & + k_exude_sp_in = k_exude_sp , & + k_exude_phaeo_in = k_exude_phaeo , & + K_Nit_diatoms_in = K_Nit_diatoms , & + K_Nit_sp_in = K_Nit_sp , & + K_Nit_phaeo_in = K_Nit_phaeo , & + K_Am_diatoms_in = K_Am_diatoms , & + K_Am_sp_in = K_Am_sp , & + K_Am_phaeo_in = K_Am_phaeo , & + K_Sil_diatoms_in = K_Sil_diatoms , & + K_Sil_sp_in = K_Sil_sp , & + K_Sil_phaeo_in = K_Sil_phaeo , & + K_Fe_diatoms_in = K_Fe_diatoms , & + K_Fe_sp_in = K_Fe_sp , & + K_Fe_phaeo_in = K_Fe_phaeo , & + f_doc_s_in = f_doc_s , & + f_doc_l_in = f_doc_l , & + f_don_protein_in = f_don_protein , & + kn_bac_protein_in = kn_bac_protein , & + f_don_Am_protein_in = f_don_Am_protein , & + f_exude_s_in = f_exude_s , & + f_exude_l_in = f_exude_l , & + k_bac_s_in = k_bac_s , & + k_bac_l_in = k_bac_l , & + algaltype_diatoms_in = algaltype_diatoms , & + algaltype_sp_in = algaltype_sp , & + algaltype_phaeo_in = algaltype_phaeo , & + dictype_1_in = dictype_1 , & + doctype_s_in = doctype_s , & + doctype_l_in = doctype_l , & + dontype_protein_in = dontype_protein , & + fedtype_1_in = fedtype_1 , & + feptype_1_in = feptype_1 , & + nitratetype_in = nitratetype , & + ammoniumtype_in = ammoniumtype , & + silicatetype_in = silicatetype , & + dmspptype_in = dmspptype , & + dmspdtype_in = dmspdtype , & + humtype_in = humtype , & + zaerotype_bc1_in = zaerotype_bc1 , & + zaerotype_bc2_in = zaerotype_bc2 , & + zaerotype_dust1_in = zaerotype_dust1 , & + zaerotype_dust2_in = zaerotype_dust2 , & + zaerotype_dust3_in = zaerotype_dust3 , & + zaerotype_dust4_in = zaerotype_dust4) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & file=__FILE__, line=__LINE__) @@ -1219,7 +1324,8 @@ subroutine init_zbgc nlt_bgc_N(:) = 0 nlt_bgc_C(:) = 0 nlt_bgc_chl(:) = 0 - nt_bgc_N(:) = 0 + ! need some valid array indices if unset + nt_bgc_N(:) = max_ntrcr - n_algae*(nblyr+3) nt_bgc_C(:) = 0 nt_bgc_chl(:) = 0 @@ -1244,7 +1350,8 @@ subroutine init_zbgc ! vectors of size icepack_max_aero nlt_zaero(:) = 0 nlt_zaero_sw(:) = 0 - nt_zaero(:) = 0 + ! need some valid array indices if unset + nt_zaero(:) = max_ntrcr - n_zaero*(nblyr+3) nt_zaero_sw(:) = 0 nlt_bgc_Nit = 0 @@ -1269,106 +1376,6 @@ subroutine init_zbgc nt_bgc_hum = 0 nt_zbgc_frac = 0 - !----------------------------------------------------------------- - ! Define array parameters - !----------------------------------------------------------------- - - R_Si2N(1) = ratio_Si2N_diatoms - R_Si2N(2) = ratio_Si2N_sp - R_Si2N(3) = ratio_Si2N_phaeo - - R_S2N(1) = ratio_S2N_diatoms - R_S2N(2) = ratio_S2N_sp - R_S2N(3) = ratio_S2N_phaeo - - R_Fe2C(1) = ratio_Fe2C_diatoms - R_Fe2C(2) = ratio_Fe2C_sp - R_Fe2C(3) = ratio_Fe2C_phaeo - - R_Fe2N(1) = ratio_Fe2N_diatoms - R_Fe2N(2) = ratio_Fe2N_sp - R_Fe2N(3) = ratio_Fe2N_phaeo - - R_C2N(1) = ratio_C2N_diatoms - R_C2N(2) = ratio_C2N_sp - R_C2N(3) = ratio_C2N_phaeo - - R_chl2N(1) = ratio_chl2N_diatoms - R_chl2N(2) = ratio_chl2N_sp - R_chl2N(3) = ratio_chl2N_phaeo - - F_abs_chl(1) = F_abs_chl_diatoms - F_abs_chl(2) = F_abs_chl_sp - F_abs_chl(3) = F_abs_chl_phaeo - - R_Fe2DON(1) = ratio_Fe2DON - R_C2N_DON(1) = ratio_C2N_proteins - - R_Fe2DOC(1) = ratio_Fe2DOC_s - R_Fe2DOC(2) = ratio_Fe2DOC_l - R_Fe2DOC(3) = c0 - - chlabs(1) = chlabs_diatoms - chlabs(2) = chlabs_sp - chlabs(3) = chlabs_phaeo - - alpha2max_low(1) = alpha2max_low_diatoms - alpha2max_low(2) = alpha2max_low_sp - alpha2max_low(3) = alpha2max_low_phaeo - - beta2max(1) = beta2max_diatoms - beta2max(2) = beta2max_sp - beta2max(3) = beta2max_phaeo - - mu_max(1) = mu_max_diatoms - mu_max(2) = mu_max_sp - mu_max(3) = mu_max_phaeo - - grow_Tdep(1) = grow_Tdep_diatoms - grow_Tdep(2) = grow_Tdep_sp - grow_Tdep(3) = grow_Tdep_phaeo - - fr_graze(1) = fr_graze_diatoms - fr_graze(2) = fr_graze_sp - fr_graze(3) = fr_graze_phaeo - - mort_pre(1) = mort_pre_diatoms - mort_pre(2) = mort_pre_sp - mort_pre(3) = mort_pre_phaeo - - mort_Tdep(1) = mort_Tdep_diatoms - mort_Tdep(2) = mort_Tdep_sp - mort_Tdep(3) = mort_Tdep_phaeo - - k_exude(1) = k_exude_diatoms - k_exude(2) = k_exude_sp - k_exude(3) = k_exude_phaeo - - K_Nit(1) = K_Nit_diatoms - K_Nit(2) = K_Nit_sp - K_Nit(3) = K_Nit_phaeo - - K_Am(1) = K_Am_diatoms - K_Am(2) = K_Am_sp - K_Am(3) = K_Am_phaeo - - K_Sil(1) = K_Sil_diatoms - K_Sil(2) = K_Sil_sp - K_Sil(3) = K_Sil_phaeo - - K_Fe(1) = K_Fe_diatoms - K_Fe(2) = K_Fe_sp - K_Fe(3) = K_Fe_phaeo - - f_don(1) = f_don_protein - kn_bac(1) = kn_bac_protein - f_don_Am(1) = f_don_Am_protein - - f_exude(1) = f_exude_s - f_exude(2) = f_exude_l - k_bac(1) = k_bac_s - k_bac(2) = k_bac_l - dictype(:) = -c1 algaltype(1) = algaltype_diatoms @@ -1381,6 +1388,7 @@ subroutine init_zbgc dontype(1) = dontype_protein fedtype(1) = fedtype_1 + feptype(1) = feptype_1 zaerotype(1) = zaerotype_bc1 @@ -1390,31 +1398,6 @@ subroutine init_zbgc zaerotype(5) = zaerotype_dust3 zaerotype(6) = zaerotype_dust4 - call icepack_init_zbgc ( & - R_Si2N_in=R_Si2N, & - R_S2N_in=R_S2N, R_Fe2C_in=R_Fe2C, R_Fe2N_in=R_Fe2N, R_C2N_in=R_C2N, & - R_chl2N_in=R_chl2N, F_abs_chl_in=F_abs_chl, R_Fe2DON_in=R_Fe2DON, & - R_C2N_DON_in=R_C2N_DON, & - R_Fe2DOC_in=R_Fe2DOC, & - chlabs_in=chlabs, alpha2max_low_in=alpha2max_low, beta2max_in=beta2max, & - mu_max_in=mu_max, grow_Tdep_in=grow_Tdep, fr_graze_in=fr_graze, & - mort_pre_in=mort_pre, & - mort_Tdep_in=mort_Tdep, k_exude_in=k_exude, & - K_Nit_in=K_Nit, K_Am_in=K_Am, K_sil_in=K_Sil, K_Fe_in=K_Fe, & - f_don_in=f_don, kn_bac_in=kn_bac, f_don_Am_in=f_don_Am, f_exude_in=f_exude, & - k_bac_in=k_bac, & - fr_resp_in=fr_resp, algal_vel_in=algal_vel, R_dFe2dust_in=R_dFe2dust, & - dustFe_sol_in=dustFe_sol, T_max_in=T_max, fr_mort2min_in=fr_mort2min, & - fr_dFe_in=fr_dFe, op_dep_min_in=op_dep_min, & - fr_graze_s_in=fr_graze_s, fr_graze_e_in=fr_graze_e, & - k_nitrif_in=k_nitrif, t_iron_conv_in=t_iron_conv, & - max_loss_in=max_loss, max_dfe_doc1_in=max_dfe_doc1, & - fr_resp_s_in=fr_resp_s, y_sk_DMS_in=y_sk_DMS, & - t_sk_conv_in=t_sk_conv, t_sk_ox_in=t_sk_ox, fsal_in=fsal) - call icepack_warnings_flush(nu_diag) - if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & - file=__FILE__, line=__LINE__) - if (skl_bgc) then nk = 1 @@ -1780,7 +1763,6 @@ subroutine init_zbgc write(nu_diag,1010) ' skl_bgc = ', skl_bgc write(nu_diag,1030) ' bgc_flux_type = ', bgc_flux_type - write(nu_diag,1010) ' restore_bgc = ', restore_bgc write(nu_diag,*) ' bgc_data_type = ', & trim(bgc_data_type) write(nu_diag,1020) ' number of bio tracers = ', nbtrcr @@ -1832,11 +1814,14 @@ subroutine init_zbgc write(nu_diag,1010) ' tr_bgc_DON = ', tr_bgc_DON write(nu_diag,1010) ' tr_bgc_Fe = ', tr_bgc_Fe write(nu_diag,1000) ' grid_o = ', grid_o + write(nu_diag,1000) ' grid_o_t = ', grid_o_t write(nu_diag,1005) ' l_sk = ', l_sk write(nu_diag,1000) ' initbio_frac = ', initbio_frac write(nu_diag,1000) ' frazil_scav = ', frazil_scav - endif ! skl_bgc or solve_bgc + endif ! skl_bgc or z_tracers + + call icedrv_system_flush(nu_diag) 1000 format (a30,2x,f9.2) ! a30 to align formatted, unformatted statements 1005 format (a30,2x,f9.6) ! float diff --git a/configuration/driver/icedrv_restart.F90 b/configuration/driver/icedrv_restart.F90 index 762d1b388..4cedb5073 100644 --- a/configuration/driver/icedrv_restart.F90 +++ b/configuration/driver/icedrv_restart.F90 @@ -415,8 +415,7 @@ subroutine restartfile (ice_ic) do i = 1, nx if (tmask(i)) & - call icepack_aggregate (ncat=ncat, & - aicen=aicen(i,:), & + call icepack_aggregate (aicen=aicen(i,:), & trcrn=trcrn(i,:,:), & vicen=vicen(i,:), & vsnon=vsnon(i,:), & @@ -425,7 +424,6 @@ subroutine restartfile (ice_ic) vice=vice (i), & vsno=vsno (i), & aice0=aice0(i), & - ntrcr=max_ntrcr, & trcr_depend=trcr_depend, & trcr_base=trcr_base, & n_trcr_strata=n_trcr_strata, & diff --git a/configuration/driver/icedrv_step.F90 b/configuration/driver/icedrv_step.F90 index 0f25b5656..0c4538c4d 100644 --- a/configuration/driver/icedrv_step.F90 +++ b/configuration/driver/icedrv_step.F90 @@ -271,7 +271,7 @@ subroutine step_therm1 (dt) enddo endif ! snwgrain - call icepack_step_therm1(dt=dt, ncat=ncat, nilyr=nilyr, nslyr=nslyr, & + call icepack_step_therm1(dt=dt, & aicen_init = aicen_init(i,:), & vicen_init = vicen_init(i,:), & vsnon_init = vsnon_init(i,:), & @@ -431,10 +431,10 @@ subroutine step_therm2 (dt) wavefreq, dwavefreq, & floe_rad_c, floe_binwidth, & d_afsd_latg, d_afsd_newi, d_afsd_latm, d_afsd_weld - use icedrv_arrays_column, only: first_ice, bgrid, cgrid, igrid + use icedrv_arrays_column, only: first_ice use icedrv_calendar, only: yday use icedrv_domain_size, only: ncat, nilyr, nslyr, n_aero, nblyr, & - nltrcr, nx, nfsd + nx, nfsd use icedrv_flux, only: fresh, frain, fpond, frzmlt, frazil, frz_onset use icedrv_flux, only: fsalt, Tf, sss, salinz, fhocn, rside, fside, wlat use icedrv_flux, only: meltl, frazil_diag, flux_bio, faero_ocn, fiso_ocn @@ -482,9 +482,8 @@ subroutine step_therm2 (dt) if (tr_fsd) & wave_sig_ht(i) = c4*SQRT(SUM(wave_spectrum(i,:)*dwavefreq(:))) - call icepack_step_therm2(dt=dt, ncat=ncat, & - nltrcr=nltrcr, nilyr=nilyr, nslyr=nslyr, & - hin_max=hin_max(:), nblyr=nblyr, & + call icepack_step_therm2(dt=dt, & + hin_max=hin_max(:), & aicen=aicen(i,:), & vicen=vicen(i,:), & vsnon=vsnon(i,:), & @@ -505,8 +504,7 @@ subroutine step_therm2 (dt) frain=frain(i), fpond=fpond(i), & fresh=fresh(i), fsalt=fsalt(i), & fhocn=fhocn(i), & - bgrid=bgrid, cgrid=cgrid, & - igrid=igrid, faero_ocn=faero_ocn(i,:), & + faero_ocn=faero_ocn(i,:), & first_ice=first_ice(i,:), & flux_bio=flux_bio(i,1:nbtrcr), & ocean_bio=ocean_bio(i,1:nbtrcr), & @@ -517,7 +515,7 @@ subroutine step_therm2 (dt) HDO_ocn=HDO_ocn(i), & H2_16O_ocn=H2_16O_ocn(i), & H2_18O_ocn=H2_18O_ocn(i), & - nfsd=nfsd, wave_sig_ht=wave_sig_ht(i), & + wave_sig_ht=wave_sig_ht(i), & wave_spectrum=wave_spectrum(i,:), & wavefreq=wavefreq(:), & dwavefreq=dwavefreq(:), & @@ -603,13 +601,12 @@ subroutine update_state (dt, daidt, dvidt, dagedt, offset) !----------------------------------------------------------------- if (tmask(i)) then - call icepack_aggregate (ncat=ncat, & + call icepack_aggregate ( & aicen=aicen(i,:), trcrn=trcrn(i,1:ntrcr,:), & vicen=vicen(i,:), vsnon=vsnon(i,:), & aice =aice (i), trcr =trcr (i,1:ntrcr), & vice =vice (i), vsno =vsno (i), & aice0=aice0(i), & - ntrcr=ntrcr, & trcr_depend=trcr_depend (1:ntrcr), & trcr_base=trcr_base (1:ntrcr,:), & n_trcr_strata=n_trcr_strata(1:ntrcr), & @@ -682,7 +679,7 @@ subroutine step_dyn_wave (dt) do i = 1, nx d_afsd_wave(i,:) = c0 call icepack_step_wavefracture (wave_spec_type=wave_spec_type, & - dt=dt, ncat=ncat, nfsd=nfsd, nfreq=nfreq, & + dt=dt, nfreq=nfreq, & aice = aice (i), & vice = vice (i), & aicen = aicen (i,:), & @@ -867,9 +864,7 @@ subroutine step_dyn_ridge (dt, ndtd) if (tmask(i)) then call icepack_step_ridge(dt=dt, ndtd=ndtd, & - nilyr=nilyr, nslyr=nslyr, & - nblyr=nblyr, & - ncat=ncat, hin_max=hin_max(:), & + hin_max=hin_max(:), & rdg_conv=rdg_conv(i), rdg_shear=rdg_shear(i), & aicen=aicen(i,:), & trcrn=trcrn(i,1:ntrcr,:), & @@ -883,7 +878,6 @@ subroutine step_dyn_ridge (dt, ndtd) dvirdgdt=dvirdgdt(i), opening=opening(i), & fpond=fpond(i), & fresh=fresh(i), fhocn=fhocn(i), & - n_aero=n_aero, & faero_ocn=faero_ocn(i,:), fiso_ocn=fiso_ocn(i,:), & aparticn=aparticn(i,:), krdgn=krdgn(i,:), & aredistn=aredistn(i,:), vredistn=vredistn(i,:), & @@ -910,9 +904,7 @@ subroutine step_dyn_ridge (dt, ndtd) if (tmask(i)) then call icepack_step_ridge (dt=dt, ndtd=ndtd, & - nilyr=nilyr, nslyr=nslyr, & - nblyr=nblyr, & - ncat=ncat, hin_max=hin_max(:), & + hin_max=hin_max(:), & rdg_conv=rdg_conv(i), rdg_shear=rdg_shear(i), & aicen=aicen(i,:), & trcrn=trcrn(i,1:ntrcr,:), & @@ -926,7 +918,6 @@ subroutine step_dyn_ridge (dt, ndtd) dvirdgdt=dvirdgdt(i), opening=opening(i), & fpond=fpond(i), & fresh=fresh(i), fhocn=fhocn(i), & - n_aero=n_aero, & faero_ocn=faero_ocn(i,:), fiso_ocn=fiso_ocn(i,:), & aparticn=aparticn(i,:), krdgn=krdgn(i,:), & aredistn=aredistn(i,:), vredistn=vredistn(i,:), & @@ -997,8 +988,7 @@ subroutine step_snow (dt) do i = 1, nx - call icepack_step_snow (dt, nilyr, & - nslyr, ncat, & + call icepack_step_snow (dt, & wind (i), aice (i), & aicen(i,:), vicen (i,:), & vsnon(i,:), trcrn(i,nt_Tsfc,:), & @@ -1031,7 +1021,6 @@ subroutine step_radiation (dt) use icedrv_arrays_column, only: fswthrun, fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf use icedrv_arrays_column, only: albicen, albsnon, albpndn use icedrv_arrays_column, only: alvdrn, alidrn, alvdfn, alidfn, apeffn, trcrn_sw, snowfracn - use icedrv_arrays_column, only: swgrid, igrid use icedrv_calendar, only: yday, sec use icedrv_domain_size, only: ncat, n_aero, nilyr, nslyr, n_zaero, n_algae, nblyr, nx use icedrv_flux, only: swvdr, swvdf, swidr, swidf, coszen, fsnow @@ -1131,7 +1120,6 @@ subroutine step_radiation (dt) if (tmask(i)) then call icepack_step_radiation(dt=dt, & - swgrid=swgrid(:), igrid=igrid(:), & fbri=fbri(:), & aicen=aicen(i,:), vicen=vicen(i,:), & vsnon=vsnon(i,:), & @@ -1332,13 +1320,12 @@ subroutine biogeochemistry (dt) use icedrv_arrays_column, only: fbio_snoice, fbio_atmice, ocean_bio use icedrv_arrays_column, only: first_ice, fswpenln, bphi, bTiz, ice_bio_net use icedrv_arrays_column, only: snow_bio_net, fswthrun - use icedrv_arrays_column, only: ocean_bio_all, sice_rho - use icedrv_arrays_column, only: bgrid, igrid, icgrid, cgrid + use icedrv_arrays_column, only: ocean_bio_all use icepack_intfc, only: icepack_biogeochemistry, icepack_load_ocean_bio_array use icedrv_domain_size, only: nblyr, nilyr, nslyr, n_algae, n_zaero, ncat use icedrv_domain_size, only: n_doc, n_dic, n_don, n_fed, n_fep, nx use icedrv_flux, only: meltbn, melttn, congeln, snoicen - use icedrv_flux, only: sst, sss, fsnow, meltsn + use icedrv_flux, only: sst, sss, Tf, fsnow, meltsn use icedrv_flux, only: hin_old, flux_bio, flux_bio_atm, faero_atm use icedrv_flux, only: nit, amm, sil, dmsp, dms, algalN, doc, don, dic, fed, fep, zaeros, hum use icedrv_state, only: aicen_init, vicen_init, aicen, vicen, vsnon @@ -1416,10 +1403,7 @@ subroutine biogeochemistry (dt) ! Define ocean concentrations for tracers used in simulation do i = 1, nx - call icepack_load_ocean_bio_array(max_nbtrcr=max_nbtrcr,& - max_algae = max_algae, max_don = max_don, & - max_doc = max_doc, max_dic = max_dic, & - max_aero = max_aero, max_fe = max_fe, & + call icepack_load_ocean_bio_array( & nit = nit(i), amm = amm(i), & sil = sil(i), dmsp = dmsp(i), & dms = dms(i), algalN = algalN(i,:), & @@ -1428,6 +1412,7 @@ subroutine biogeochemistry (dt) fep = fep(i,:), zaeros = zaeros(i,:), & ocean_bio_all=ocean_bio_all(i,:), & hum=hum(i)) +! handled below ! call icepack_warnings_flush(nu_diag) ! if (icepack_warnings_aborted()) call icedrv_system_abort(i, istep1, subname, & ! file=__FILE__,line= __LINE__) @@ -1441,12 +1426,7 @@ subroutine biogeochemistry (dt) enddo ! mm endif - call icepack_biogeochemistry(dt=dt, ntrcr=ntrcr, nbtrcr=nbtrcr, & - ncat=ncat, nblyr=nblyr, nilyr=nilyr, nslyr=nslyr, & - n_algae=n_algae, n_zaero=n_zaero, & - n_doc=n_doc, n_dic=n_dic, n_don=n_don, & - n_fed=n_fed, n_fep=n_fep, & - bgrid=bgrid, igrid=igrid, icgrid=icgrid, cgrid=cgrid, & + call icepack_biogeochemistry(dt=dt, & upNO = upNO(i), & upNH = upNH(i), & iDi = iDi(i,:,:), & @@ -1469,13 +1449,13 @@ subroutine biogeochemistry (dt) ice_bio_net = ice_bio_net(i,1:nbtrcr), & snow_bio_net = snow_bio_net(i,1:nbtrcr), & fswthrun = fswthrun(i,:), & - sice_rho = sice_rho(i,:), & meltbn = meltbn(i,:), & melttn = melttn(i,:), & congeln = congeln(i,:), & snoicen = snoicen(i,:), & sst = sst(i), & sss = sss(i), & + Tf = Tf(i), & fsnow = fsnow(i), & meltsn = meltsn(i,:), & hin_old = hin_old(i,:), & @@ -1488,9 +1468,8 @@ subroutine biogeochemistry (dt) vsnon = vsnon(i,:), & aice0 = aice0(i), & trcrn = trcrn(i,1:ntrcr,:), & - vsnon_init = vsnon_init(i,:), & - skl_bgc = skl_bgc) - + vsnon_init = vsnon_init(i,:)) +! handled below ! call icepack_warnings_flush(nu_diag) ! if (icepack_warnings_aborted()) call icedrv_system_abort(i, istep1, subname, & ! __FILE__, __LINE__) diff --git a/configuration/driver/icedrv_system.F90 b/configuration/driver/icedrv_system.F90 index 46203735f..ddd293d08 100644 --- a/configuration/driver/icedrv_system.F90 +++ b/configuration/driver/icedrv_system.F90 @@ -13,7 +13,8 @@ module icedrv_system implicit none private - public :: icedrv_system_abort + public :: icedrv_system_abort, & + icedrv_system_flush !======================================================================= @@ -46,10 +47,29 @@ subroutine icedrv_system_abort(icell, istep, string, file, line) if (present(istep)) write (nu_diag,*) subname,' istep =', istep if (present(icell)) write (nu_diag,*) subname,' i, aice =', icell, aice(icell) if (present(string)) write (nu_diag,*) subname,' string = ',trim(string) + call icedrv_system_flush(nu_diag) stop end subroutine icedrv_system_abort +!======================================================================= +! flushes iunit IO buffer + + subroutine icedrv_system_flush(iunit) + + integer (kind=int_kind), intent(in) :: & + iunit ! unit number to flush + + ! local variables + + character(len=*), parameter :: subname='(icedrv_system_flush)' + +#ifndef NO_F2003 + flush(iunit) +#endif + + end subroutine icedrv_system_flush + !======================================================================= end module icedrv_system diff --git a/configuration/scripts/icepack_in b/configuration/scripts/icepack_in index 4ac97ad81..d831c2d53 100644 --- a/configuration/scripts/icepack_in +++ b/configuration/scripts/icepack_in @@ -156,7 +156,6 @@ dEdd_algae = .false. solve_zbgc = .false. bgc_flux_type = 'Jin2006' - restore_bgc = .false. scale_bgc = .false. solve_zsal = .false. tr_bgc_Nit = .false. @@ -170,11 +169,12 @@ tr_bgc_DON = .false. tr_bgc_Fe = .false. grid_o = 0.006 - l_sk = 0.024 + grid_o_t = 0.006 + l_sk = 2.0 grid_oS = 0.0 l_skS = 0.028 - phi_snow = -0.3 - initbio_frac = 0.8 + phi_snow = -1.0 + initbio_frac = 1.0 frazil_scav = 0.8 ratio_Si2N_diatoms = 1.8 ratio_Si2N_sp = 0.0 @@ -192,29 +192,29 @@ ratio_Fe2DOC_s = 0.1 ratio_Fe2DOC_l = 0.033 fr_resp = 0.05 - tau_min = 5200.0 - tau_max = 173000.0 - algal_vel = 0.0000000111 + tau_min = 3600.0 + tau_max = 604800.0 + algal_vel = 0.0000001 R_dFe2dust = 0.035 dustFe_sol = 0.005 chlabs_diatoms = 0.03 chlabs_sp = 0.01 chlabs_phaeo = 0.05 - alpha2max_low_diatoms = 0.8 - alpha2max_low_sp = 0.67 - alpha2max_low_phaeo = 0.67 - beta2max_diatoms = 0.018 - beta2max_sp = 0.0025 - beta2max_phaeo = 0.01 + alpha2max_low_diatoms = 0.3 + alpha2max_low_sp = 0.2 + alpha2max_low_phaeo = 0.17 + beta2max_diatoms = 0.001 + beta2max_sp = 0.001 + beta2max_phaeo = 0.04 mu_max_diatoms = 1.44 - mu_max_sp = 0.851 - mu_max_phaeo = 0.851 - grow_Tdep_diatoms = 0.06 - grow_Tdep_sp = 0.06 - grow_Tdep_phaeo = 0.06 - fr_graze_diatoms = 0.0 - fr_graze_sp = 0.1 - fr_graze_phaeo = 0.1 + mu_max_sp = 0.41 + mu_max_phaeo = 0.63 + grow_Tdep_diatoms = 0.063 + grow_Tdep_sp = 0.063 + grow_Tdep_phaeo = 0.063 + fr_graze_diatoms = 0.19 + fr_graze_sp = 0.19 + fr_graze_phaeo = 0.19 mort_pre_diatoms = 0.007 mort_pre_sp = 0.007 mort_pre_phaeo = 0.007 @@ -237,10 +237,10 @@ K_Fe_sp = 0.2 K_Fe_phaeo = 0.1 f_don_protein = 0.6 - kn_bac_protein = 0.03 - f_don_Am_protein = 0.25 - f_doc_s = 0.4 - f_doc_l = 0.4 + kn_bac_protein = 0.2 + f_don_Am_protein = 1.0 + f_doc_s = 0.5 + f_doc_l = 0.5 f_exude_s = 1.0 f_exude_l = 1.0 k_bac_s = 0.03 @@ -250,36 +250,36 @@ op_dep_min = 0.1 fr_graze_s = 0.5 fr_graze_e = 0.5 - fr_mort2min = 0.5 - fr_dFe = 0.3 - k_nitrif = 0.0 + fr_mort2min = 0.9 + fr_dFe = 1.0 + k_nitrif = 0.046 t_iron_conv = 3065.0 max_loss = 0.9 max_dfe_doc1 = 0.2 - fr_resp_s = 0.75 - y_sk_DMS = 0.5 - t_sk_conv = 3.0 - t_sk_ox = 10.0 + fr_resp_s = 0.9 + y_sk_DMS = 0.7 + t_sk_conv = 5.0 + t_sk_ox = 12.0 algaltype_diatoms = 0.0 - algaltype_sp = 0.5 - algaltype_phaeo = 0.5 + algaltype_sp = 0.0 + algaltype_phaeo = 0.0 nitratetype = -1.0 - ammoniumtype = 1.0 + ammoniumtype = 0.0 silicatetype = -1.0 dmspptype = 0.5 - dmspdtype = -1.0 - humtype = 1.0 - doctype_s = 0.5 - doctype_l = 0.5 - dontype_protein = 0.5 - fedtype_1 = 0.5 + dmspdtype = 0.0 + humtype = 0.0 + doctype_s = 0.0 + doctype_l = 0.0 + dontype_protein = 0.0 + fedtype_1 = 0.0 feptype_1 = 0.5 - zaerotype_bc1 = 1.0 - zaerotype_bc2 = 1.0 - zaerotype_dust1 = 1.0 - zaerotype_dust2 = 1.0 - zaerotype_dust3 = 1.0 - zaerotype_dust4 = 1.0 + zaerotype_bc1 = -1.0 + zaerotype_bc2 = -1.0 + zaerotype_dust1 = -1.0 + zaerotype_dust2 = -1.0 + zaerotype_dust3 = -1.0 + zaerotype_dust4 = -1.0 ratio_C2N_diatoms = 7.0 ratio_C2N_sp = 7.0 ratio_C2N_phaeo = 7.0 @@ -289,6 +289,6 @@ F_abs_chl_diatoms = 2.0 F_abs_chl_sp = 4.0 F_abs_chl_phaeo = 5.0 - ratio_C2N_proteins = 7.0 + ratio_C2N_proteins = 5.0 / diff --git a/configuration/scripts/options/set_env.bgcispol b/configuration/scripts/options/set_env.bgcispol index c38635a70..1ab2fa2e6 100644 --- a/configuration/scripts/options/set_env.bgcispol +++ b/configuration/scripts/options/set_env.bgcispol @@ -1,6 +1,6 @@ ### Layers setenv NICELYR 7 # number of vertical layers in the ice -setenv NSNWLYR 1 # number of vertical layers in the snow +setenv NSNWLYR 5 # number of vertical layers in the snow setenv NICECAT 5 # number of ice thickness categories ### Tracers # match icepack_in tracer_nml to conserve memory @@ -8,7 +8,8 @@ setenv TRAGE 1 # set to 1 for ice age tracer setenv TRFY 1 # set to 1 for first-year ice area tracer setenv TRLVL 1 # set to 1 for level and deformed ice tracers setenv TRPND 1 # set to 1 for melt pond tracers -setenv NTRAERO 0 # number of aerosol tracers +setenv TRSNOW 1 # set to 1 for snow metamorphism tracers +setenv NTRAERO 1 # number of aerosol tracers # (up to max_aero in ice_domain_size.F90) # CESM uses 3 aerosol tracers setenv TRBRI 1 # set to 1 for brine height tracer @@ -23,7 +24,7 @@ setenv TRALG 3 # number of algal tracers # (up to max_algae = 3) setenv TRDOC 2 # number of dissolve organic carbon # (up to max_doc = 3) -setenv TRDIC 0 # number of dissolve inorganic carbon +setenv TRDIC 1 # number of dissolve inorganic carbon # (up to max_dic = 1) setenv TRDON 1 # number of dissolve organic nitrogen # (up to max_don = 1) diff --git a/configuration/scripts/options/set_env.bgcnice b/configuration/scripts/options/set_env.bgcnice index 1d6efc405..8d51abaaa 100644 --- a/configuration/scripts/options/set_env.bgcnice +++ b/configuration/scripts/options/set_env.bgcnice @@ -1,6 +1,6 @@ ### Layers setenv NICELYR 7 # number of vertical layers in the ice -setenv NSNWLYR 1 # number of vertical layers in the snow +setenv NSNWLYR 5 # number of vertical layers in the snow setenv NICECAT 5 # number of ice thickness categories ### Tracers # match icepack_in tracer_nml to conserve memory @@ -8,7 +8,7 @@ setenv TRAGE 1 # set to 1 for ice age tracer setenv TRFY 1 # set to 1 for first-year ice area tracer setenv TRLVL 1 # set to 1 for level and deformed ice tracers setenv TRPND 1 # set to 1 for melt pond tracers -setenv NTRAERO 0 # number of aerosol tracers +setenv NTRAERO 1 # number of aerosol tracers # (up to max_aero in ice_domain_size.F90) # CESM uses 3 aerosol tracers setenv TRBRI 1 # set to 1 for brine height tracer @@ -17,13 +17,13 @@ setenv TRBGCS 0 # set to 1 for skeletal layer tracers setenv TRBGCZ 1 # set to 1 for zbgc tracers # (needs TRBGCS = 0 and TRBRI = 1) setenv NBGCLYR 7 # number of zbgc layers -setenv TRZAERO 0 # number of z aerosol tracers +setenv TRZAERO 3 # number of z aerosol tracers # (up to max_aero = 6) setenv TRALG 3 # number of algal tracers # (up to max_algae = 3) setenv TRDOC 2 # number of dissolve organic carbon # (up to max_doc = 3) -setenv TRDIC 0 # number of dissolve inorganic carbon +setenv TRDIC 1 # number of dissolve inorganic carbon # (up to max_dic = 1) setenv TRDON 1 # number of dissolve organic nitrogen # (up to max_don = 1) diff --git a/configuration/scripts/options/set_env.bgcsklnice b/configuration/scripts/options/set_env.bgcsklnice index 985bacbf4..f51e75ab4 100644 --- a/configuration/scripts/options/set_env.bgcsklnice +++ b/configuration/scripts/options/set_env.bgcsklnice @@ -23,7 +23,7 @@ setenv TRALG 3 # number of algal tracers # (up to max_algae = 3) setenv TRDOC 2 # number of dissolve organic carbon # (up to max_doc = 3) -setenv TRDIC 0 # number of dissolve inorganic carbon +setenv TRDIC 1 # number of dissolve inorganic carbon # (up to max_dic = 1) setenv TRDON 1 # number of dissolve organic nitrogen # (up to max_don = 1) diff --git a/configuration/scripts/options/set_env.zaero b/configuration/scripts/options/set_env.zaero new file mode 100644 index 000000000..d434f092d --- /dev/null +++ b/configuration/scripts/options/set_env.zaero @@ -0,0 +1,6 @@ +### Tracers # match icepack_in tracer_nml to conserve memory +setenv NBGCLYR 7 # number of zbgc layers +setenv NTRAERO 0 # number of aerosol tracers +setenv TRBRI 1 # set to 1 for brine height tracer +setenv TRBGCZ 1 # set to 1 for zbgc tracers +setenv TRZAERO 3 # number of z aerosol tracers diff --git a/configuration/scripts/options/set_nml.bgcispol b/configuration/scripts/options/set_nml.bgcispol index 9f3eab1f6..0c1cad4e5 100644 --- a/configuration/scripts/options/set_nml.bgcispol +++ b/configuration/scripts/options/set_nml.bgcispol @@ -23,5 +23,13 @@ tr_bgc_PON = .true. tr_bgc_hum = .true. tr_bgc_DON = .true. - tr_bgc_Fe = .false. + tr_bgc_Fe = .true. tfrz_option = 'mushy' + tr_FY = .true. + kcatbound = 0 + tr_snow = .true. + use_smliq_pnd = .true. + snwgrain = .true. + snwredist = 'ITDrdg' + rsnw_fall = 54.526 + rsnw_tmax = 2800.0 diff --git a/configuration/scripts/options/set_nml.bgcnice b/configuration/scripts/options/set_nml.bgcnice index 286b76161..11ca8e1c0 100644 --- a/configuration/scripts/options/set_nml.bgcnice +++ b/configuration/scripts/options/set_nml.bgcnice @@ -11,7 +11,7 @@ ocn_data_file = 'oceanmixed_daily_3.txt' bgc_data_file = 'nutrients_daily_ISPOL_WOA_field3.txt' tr_brine = .true. - tr_zaero = .false. + tr_zaero = .true. z_tracers = .true. solve_zbgc = .true. bgc_flux_type = 'Jin2006' @@ -25,3 +25,11 @@ tr_bgc_DON = .true. tr_bgc_Fe = .true. tfrz_option = 'mushy' + tr_FY = .true. + kcatbound = 0 + tr_snow = .true. + use_smliq_pnd = .true. + snwgrain = .true. + snwredist = 'ITDrdg' + rsnw_fall = 54.526 + rsnw_tmax = 2800.0 diff --git a/configuration/scripts/options/set_nml.zaero b/configuration/scripts/options/set_nml.zaero new file mode 100644 index 000000000..6d81ae9bb --- /dev/null +++ b/configuration/scripts/options/set_nml.zaero @@ -0,0 +1,3 @@ + tr_brine = .true. + tr_zaero = .true. + z_tracers = .true. diff --git a/configuration/scripts/tests/base_suite.ts b/configuration/scripts/tests/base_suite.ts index 3a68d7dd7..9ca134097 100644 --- a/configuration/scripts/tests/base_suite.ts +++ b/configuration/scripts/tests/base_suite.ts @@ -3,7 +3,8 @@ smoke col 1x1 diag1,run1year smoke col 1x1 debug,run1year smoke col 1x1 debug,bgcispol smoke col 1x1 debug,bgcnice -smoke col 1x1 debug,bgcsklnice +smoke col 1x1 debug,zaero +#smoke col 1x1 debug,bgcsklnice smoke col 1x1 debug,run1year,thermo1 smoke col 1x1 debug,run1year,swredist smoke col 1x1 debug,run1year,swccsm3 @@ -29,6 +30,9 @@ restart col 1x1 diag1 restart col 1x1 pondlvl restart col 1x1 pondtopo restart col 1x1 bgcispol +restart col 1x1 bgcnice +restart col 1x1 zaero,snwitdrdg,snwgrain +#restart col 1x1 bgcsklnice restart col 1x1 thermo1 restart col 1x1 swccsm3 restart col 1x1 isotope diff --git a/configuration/scripts/tests/travis_suite.ts b/configuration/scripts/tests/travis_suite.ts index 8c22ba46c..31d749487 100644 --- a/configuration/scripts/tests/travis_suite.ts +++ b/configuration/scripts/tests/travis_suite.ts @@ -3,7 +3,8 @@ smoke col 1x1 diag1,run1year smoke col 1x1 debug,run1year smoke col 1x1 debug,bgcispol smoke col 1x1 debug,bgcnice -smoke col 1x1 debug,bgcsklnice +smoke col 1x1 debug,zaero +#smoke col 1x1 debug,bgcsklnice smoke col 1x1 debug,run1year,thermo1 smoke col 1x1 debug,run1year,swccsm3 smoke col 1x1 debug,run1year,alt01 diff --git a/doc/source/conf.py b/doc/source/conf.py index e9d2e3ef7..49c6e2c42 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -38,6 +38,7 @@ 'sphinxcontrib.bibtex', ] +bibtex_bibfiles=['master_list.bib'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -71,7 +72,7 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = 'en' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: diff --git a/doc/source/master_list.bib b/doc/source/master_list.bib index 445bf758c..2296cbd98 100644 --- a/doc/source/master_list.bib +++ b/doc/source/master_list.bib @@ -56,6 +56,8 @@ @string{BGC @string{EFM = {Eng. Fract. Mech.}} @string{ANG = {Ann. Glaciol.}} @string{NOAA = {Natl. Ocn. and Atm. Admin}} +@string{WRR = {Water Resour. Res.}} +@string{LO = {L&O}} % ********************************************** % List of individual sources and their meta data @@ -819,9 +821,28 @@ @article{Plante24 volume = 18, pages = {1685--1708}, doi = {10.5194/tc-18-1685-2024}, -year = {20124} +year = {2024} } +@article{Johnson95, +author = {Johnson, {William P.} and Blue, {Karen A.} and Logan, {Bruce E.} and Arnold, {Robert G.}}, +title = {Modeling Bacterial Detachment During Transport Through Porous Media as a Residence‐Time‐Dependent Process}, +year = {1995}, +doi = {10.1029/95WR02311}, +volume = 31, +pages = {2649--2658}, +journal = {WWR} +} +@article{Edwards2012, +author = {Edwards, Kyle F. and Thomas, Mridul K. and Klausmeier, Christopher A. and Litchman, Elena}, +title = {Allometric scaling and taxonomic variation in nutrient utilization traits and maximum growth rate of phytoplankton}, +journal = {LO}, +volume = {57}, +number = {2}, +pages = {554-566}, +doi = {https://doi.org/10.4319/lo.2012.57.2.0554}, +year = {2012} +} % ********************************************** % For new entries, see example entry in BIB_TEMPLATE.txt % ********************************************** diff --git a/doc/source/science_guide/sg_bgc.rst b/doc/source/science_guide/sg_bgc.rst index 90f93f620..b38b27135 100755 --- a/doc/source/science_guide/sg_bgc.rst +++ b/doc/source/science_guide/sg_bgc.rst @@ -13,7 +13,7 @@ Basic Aerosols Aerosols may be deposited on the ice and gradually work their way through it until the ice melts and they are passed into the ocean. They -are defined as ice and snow volume tracers (Eq. 15 and 16 in CICE.v5 +are defined as ice and snow volume tracers (see CICE "Tracers" documentation), with the snow and ice each having two tracers for each aerosol species, one in the surface scattering layer (delta-Eddington SSL) and one in the snow or ice interior below the SSL. @@ -50,7 +50,7 @@ An alternate scheme for aerosols in sea ice is available using the brine motion based transport scheme of the biogeochemical tracers. All vertically resolved biogeochemical tracers (z-tracers), including aerosols, have the potential to be atmospherically deposited onto the -snow or ice, scavenged during snow melt, and passed into the brine. The +snow or ice, scavenged during snow melt, and passed into the brine. They can also be picked up from the ocean if there is an ocean source. The mobile fraction (discussed in :ref:`mobile-and-stationary`) is then transported via brine drainage processes (Eq. :eq:`mobile-transport`) while a @@ -63,7 +63,7 @@ the scavenging parameter ``kscavz`` for z-tracers defined in **icepack\_zbgc\_shared.F90**. Within the snow, z-tracers are defined as concentrations in the snow -surface layer (:math:`h_{ssl}`) and the snow interior +surface layer (:math:`h_{ssl}`), equal to half the snow layer thickness, and the snow interior (:math:`h_s-h_{ssl}`). The total snow content of z-tracers per ice area per grid cell area, :math:`C_{snow}` is @@ -73,13 +73,13 @@ per grid cell area, :math:`C_{snow}` is One major difference in how the two schemes model snow aerosol transport is that the fraction scavenged from snow melt in the z-tracer scheme is not immediately fluxed into the ocean, but rather, enters the ice as a -source of low salinity but potentially tracer-rich brine. The snow melt +source of potentially tracer-rich brine. The snow melt source is included as a surface flux condition in **icepack\_algae.F90**. All the z-aerosols are nonreactive with the exception of the dust -aerosols. We assume that a small fraction of the dust flux into the ice -has soluble iron (``dustFe_sol`` in **icepack\_in**) and so is -passed to the dissolved iron tracer. The remaining dust passes through +aerosols. If biogeochemistry is active, we assume that a small fraction of the dust flux into the ice +is iron ((``R_dFe2dust`` in **icepack\_in**) and a fraction of that has soluble iron (``dustFe_sol`` in **icepack\_in**). This is +passed to the dissolved iron tracer if active. The remaining dust passes through the ice without reactions. To use z-aerosols, ``tr_zaero`` must be set to true in **icepack\_in**, and the @@ -87,7 +87,7 @@ number of z-aerosol species is set in **icepack.settings**, ``TRZAERO``. Note, t basic tracers ``tr_aero`` must be false and ``NTRAERO`` in **icepack.settings** should be 0. In addition, z-tracers and the brine height tracer must also be active. These are set in **icepack\_in** with ``tr_brine`` and -``z_tracer`` set to true. In addition, to turn on the radiative coupling +``z_tracer`` set to true. To turn on the radiative coupling between the aerosols and the Delta-Eddington radiative scheme, ``shortwave`` must equal ’dEdd’ and ``dEdd_algae`` must be true in **icepack\_in**. @@ -98,7 +98,7 @@ Water Isotope Water isotopes may be deposited on the ice from above or below, and gradually work their way through it until the ice melts and they are passed into the ocean. They -are defined as ice and snow volume tracers (Eq. 15 and 16 in CICE.v5 +are defined as ice and snow volume tracers (see CICE "Tracers" documentation), with the snow and ice each having one tracer for each water isotope species. @@ -264,6 +264,10 @@ where the sums are taken over thickness categories. Sea ice ecosystem ----------------- +**The skeletal layer implementation has been deprecated but not removed as of +September, 2024. If users are interested in this feature, please contact +the CICE Consortium. The documentation below has not yet been removed.** + There are two options for modeling biogeochemistry in sea ice: 1) a skeletal layer or bottom layer model that assumes biology and biological molecules are restricted to a single layer at the base of @@ -299,8 +303,7 @@ There are also environmental variables in **icepack.settings** that, in part, specify the complexity of the ecosystem and are used for both zbgc and the skeletal-layer model. These are 1) ``TRALG``, the number of algal species; 2) ``TRDOC``, the number of dissolved organic carbon groups, 3) ``TRDIC``, the -number of dissolved inorganic carbon groups (this is currently not yet -implemented and should be set to 0); 4) ``TRDON``, the number of dissolved +number of dissolved inorganic carbon groups (this is set to 1 if conservation of carbon is desired); 4) ``TRDON``, the number of dissolved organic nitrogen groups, 5) ``TRFEP``, the number of particulate iron groups; and 6) ``TRFED``, the number of dissolved iron groups. The current version of **algal\_dyn** biochemistry has parameters for up to 3 algal @@ -329,6 +332,10 @@ namelist, ``bgc_data_file``. Skeletal Layer BGC ~~~~~~~~~~~~~~~~~~ +**The skeletal layer implementation has been deprecated but not removed as of +September, 2024. If users are interested in this feature, please contact +the CICE Consortium. The documentation below has not yet been removed.** + In the skeletal layer model, biogeochemical processing is modelled as a single layer of reactive tracers attached to the sea ice bottom. Optional settings are available via the *zbgc\_nml* namelist in @@ -426,7 +433,7 @@ section :ref:`reactions`. .. _zbgc: -Vertical BGC (''zbgc'') +Vertical BGC ("zbgc") ~~~~~~~~~~~~~~~~~~~~~~~ In order to solve for the vertically resolved biogeochemistry, several @@ -439,7 +446,7 @@ flags in **icepack\_in** must be true: a) ``tr_brine``, b) ``z_tracers``, and c) volume\ :math:`\times`\ brine height fraction. - ``z_tracers`` = true indicates use of vertically resolved - biogeochemical and z-aerosol tracers. This flag alone turns on the + biogeochemical tracers, z-aerosol tracers, or both. This flag alone turns on the vertical transport scheme but not the biochemistry. - ``solve_zbgc`` = true turns on the biochemistry for the vertically @@ -455,17 +462,17 @@ flags in **icepack\_in** must be true: a) ``tr_brine``, b) ``z_tracers``, and c) .. the Bitz and Lipscomb thermodynamics ``ktherm`` set to 1 and ``solve_zsal`` .. true (referred to as "zsalinity"). -With the above flags, the default biochemistry is a simple -algal-nitrate system: ``tr_bgc_N`` and ``tr_bgc_Nit`` are true. Options +With the above flags and ``tr_bgc_Nit`` set to true, the default biochemistry is a simple +algal-nitrate system: ``tr_bgc_N`` (turned on by default) and ``tr_bgc_Nit`` (required). Options exist in **icepack\_in** to use a more complicated ecosystem which includes up -to three algal classes, two DOC groups, one DON pool, limitation by -nitrate, silicate and dissolved iron, sulfur chemistry plus refractory +to three algal classes, two DOC groups, one DON pool, one DIC, limitation by +silicate and dissolved iron, sulfur chemistry plus refractory humic material. The **icepack\_in** namelist options are described in the :ref:`tabnamelist`. -Vertically resolved z-tracers are brine- volume conserved and thus depend +Vertically resolved z-tracers are brine volume conserved and thus depend on both the ice volume and the brine height fraction tracer (:math:`v_{in}f_b`). These tracers follow the conservation equations for multiply dependent tracers (see, for example Equation :eq:`transport-apnd-lvl` where :math:`a_{pnd}` is a tracer on :math:`a_{lvl}a_{i}`) @@ -482,12 +489,12 @@ The vertical bio-grid is described in the :ref:`grids` section. Purely mobile tracers are tracers which move with the brine and thus, in the absence of biochemical reactions, evolve like salinity. For vertical tracer transport of purely mobile tracers, the flux conserved quantity -is the bulk tracer concentration multiplied by the ice thickness, i.e. -:math:`C = h\phi -[c]`, where :math:`h` is the ice thickness, :math:`\phi` is the +is the bulk tracer concentration multiplied by the brine thickness, i.e. +:math:`C = h_{b}\phi +[c]`, where :math:`h_{b}` is the brine thickness, :math:`\phi` is the porosity, and :math:`[c]` is the tracer concentration in the brine. :math:`\phi`, :math:`[c]` and :math:`C` are defined on the interface bio -grid (igrid): +grid (igrid) with ``NBGCLYR`` equal to :math:`n_{b}` in what follows: .. math:: \mbox{igrid}(k) = \Delta (k-1) \ \ \ \mbox{for }k = 1:n_b+1 \ \ \mbox{and }\Delta = 1/n_b. @@ -497,13 +504,13 @@ The biogeochemical module solves the following equation: .. math:: \begin{aligned} \frac{\partial C}{\partial t} & =& \frac{\partial }{\partial x}\left\{ - \left( \frac{v}{h} + \frac{w_f}{h\phi} - - \frac{\tilde{D}}{h^2\phi^2}\frac{\partial \phi}{\partial x} \right) C - + \frac{\tilde{D}}{h^2\phi}\frac{\partial C}{\partial x} - \right\} + h\phi R([c])\end{aligned} + \left( \frac{v}{h_{b}} + \frac{w_f}{h_{b}\phi} - + \frac{\tilde{D}}{h_{b}^2\phi^2}\frac{\partial \phi}{\partial x} \right) C + + \frac{\tilde{D}}{h_{b}^2\phi}\frac{\partial C}{\partial x} + \right\} + h_{b}\phi R([c])\end{aligned} :label: mobile-transport -where :math:`D_{in} = \tilde{D}/h^2 = (D + \phi D_m)/h^2` and +where :math:`D_{in} = \tilde{D}/h_{b}^2 = (D + \phi D_m)/h_{b}^2` and :math:`R([c])` is the nonlinear biogeochemical interaction term (see :cite:`Jeffery11`). @@ -516,12 +523,7 @@ otherwise adhere to the ice crystals. These tracers exist in both the mobile and stationary phases. In this case, their total brine concentration is a sum :math:`c_m + c_s` where :math:`c_m` is the mobile fraction transported by equation :eq:`mobile-transport` and :math:`c_s` -is fixed vertically in the ice matrix. The algae are an exception, -however. We assume that algae in the stationary phase resist brine -motion, but rather than being fixed vertically, these tracers maintain -their relative position in the ice. Algae that adhere to the ice -interior (bottom, surface), remain in the ice interior (bottom, surface) -until release to the mobile phase. +is fixed vertically in the ice matrix. Nitrate and Diatoms are special cases discussed below. In order to model the transfer between these fractions, we assume that tracers adhere (are retained) to the crystals with a time-constant of @@ -545,8 +547,8 @@ We use the exponential form of these equations: c_s^{t+dt} & = & c_s^t\exp\left(-\frac{dt}{\tau_{rel}}\right) + c_m^t\left(1-\exp\left[-\frac{dt}{\tau_{ret}}\right]\right) \end{aligned} -The time constants are functions of the ice growth and melt rates -(:math:`dh/dt`). All tracers except algal nitrogen diatoms follow the +The time constants are step-functions of the ice growth and melt rates +(:math:`dh/dt`). All tracers except algal nitrogen diatoms and nitrate follow the simple case: when :math:`dh/dt \geq 0`, then :math:`\tau_{rel} \rightarrow \infty` and :math:`\tau_{ret}` is finite. For :math:`dh/dt < 0`, then :math:`\tau_{ret} \rightarrow \infty` and @@ -554,7 +556,9 @@ For :math:`dh/dt < 0`, then :math:`\tau_{ret} \rightarrow \infty` and transitions to the stationary phase and ice melt enables transitions to the mobile phase. -The exception is the diatom pool. We assume that diatoms, the first +Nitrate is a special case. This tracer is generally treated as purely mobile. However this is not the case if nitrate arises from in situ nitrification (i.e. ammonium to nitrate). In this case, we model the nitrate as associated with a implicit biofilm which adheres to the ice matrix. This ice in situ production is assigned to the stationary phase. + +As with nitrate, diatoms are a special case. We assume that diatoms, the first algal nitrogen group, can actively maintain their relative position within the ice, i.e. bottom (interior, upper) algae remain in the bottom (interior, upper) ice, unless melt rates exceed a threshold. The @@ -562,18 +566,19 @@ namelist parameter ``algal_vel`` sets this threshold. The variable ``bgc_tracer_type`` determines the mobile to stationary transition timescales for each z-tracer. It is multi-dimensional with a -value for each z-tracer. For ``bgc_tracer_type``(k) equal to -1, the kth +value for each z-tracer. For ``bgc_tracer_type`` equal to -1, the tracer remains solely in the mobile phase. For ``bgc_tracer_type`` equal to 1, the tracer has maximal rates in the retention phase and minimal in the release. For ``bgc_tracer_type`` equal to 0, the tracer has maximal rates in the release phase and minimal in the retention. -Finally for ``bgc_tracer_type`` equal to 0.5, minimum timescales are +Finally, for ``bgc_tracer_type`` equal to 0.5, minimum timescales are used for both transitions. Table :ref:`tab-phases` summarizes the -transition types. The tracer types are: ``algaltype_diatoms``, +transition types. The distinct tracer types are specified by the parameters: ``algaltype_diatoms``, ``algaltype_sp`` (small plankton), ``algaltype_phaeo`` (*phaeocystis*), ``nitratetype``, ``ammoniumtype``, ``silicatetype``, ``dmspptype``, ``dmspdtype``, ``humtype``, ``doctype_s`` (saccharids), ``doctype_l`` (lipids), ``dontype_protein``, +``dictype`` ``fedtype_1``, ``feptype_1``, ``zaerotype_bc1`` (black carbon class 1), ``zaerotype_bc2`` (black carbon class 2), and four dust classes, ``zaerotype_dustj``, where j takes values 1 to 4. These may be modified to @@ -606,13 +611,20 @@ dependent on two tracers: brine height fraction (:math:`f_b`) and ice volume (:math:`v_{in}`). The conservation equations are given by .. math:: - {\partial\over\partial t} (f_{b}v_{in}) + \nabla \cdot (f_{b}v_{in} {\bf u}) = 0. + {\partial\over\partial t} (f_{b}v_{in}) + \nabla \cdot (f_{b}v_{in} {\bf u}) = 0 . The tracer, ``zbgc_frac``, is initialized to 1 during new ice formation, because all z-tracers are initially in the purely mobile phase. -Similarly, as the ice melts, z-tracers return to the mobile phase. Very -large release timescales will prevent this transition and could result -in an unphysically large accumulation during the melt season. +Similarly, as the ice melts, z-tracers gradually return to the mobile phase. + +Maximum accumulation of tracers (based on diatoms) on ice crystals (i.e. collectors) is ultimately limited by their saturation concentration based on :cite:`Johnson95`'s model of bacterial detachment in porous media. This is modeled simply using a single saturation concentration for all tracers. This could be modified to be tracer dependent in future versions if warranted. Several local parameters defined in **z\_biogeochemistry** are used in the calculation: 1) mean ice crystal radius :math:`r_c` ; 2) large diatom radius :math:`r_{bac}` ; 3) small diatom radius :math:`r_{alg}` ; 4) two parameters in a conversion from algal nitrogen quota to cell volume :math:`Nquota_{A}` and :math:`Nquota_I` :cite:`Edwards2012` ; 5) fraction of sites available for saturation :math:`f_s` ; 6) fraction of the collector (ice crystal) available for attachment :math:`f_a` ; 6) fraction of algal coverage by area available for attachment :math:`f_v`. These are used to compute the volume and surface area of a diatom cell (assumed to be a prolate spheriod) :math:`V_alg = \frac{\pi}{6} r_{bac}r_{alg}^{2}` and :math:`P_b = \pi r_{bac}^{2}`, respectively; and the volume and surface area of the collector (assumed to be spherical) :math:`V_c = \frac{4 \pi}{3} r_{c}^{3}` and :math:`S_{col} = 4 \pi r_{c}^{2}`, respectively. + +The saturation concentration ``Sat_conc`` is approximated as: + +.. math:: + Sat_{conc} = \frac{f_{s}f_{a}f_{v} S_{col}Nquota_{I}}{V_{c} P_{b}}(c1-phi_{max})V_{alg}^{Nquota_{A}} + +where :math:`phi_{max}` is the maximum porosity in the ice column. .. _tracer-numerics: @@ -997,9 +1009,10 @@ are true). "N (3)", "Nin(3)", "`tr_bgc_N`", "*Phaeocystis sp*", ":math:`mmol` :math:`N/m^3`" "DOC (1)", "DOCin(1)", "`tr_bgc_DOC`", "polysaccharids", ":math:`mmol` :math:`C/m^3`" "DOC (2)", "DOCin(2)", "`tr_bgc_DOC`", "lipids", ":math:`mmol` :math:`C/m^3`" - "DON", "DONin(1)", "`tr_bgc_DON`", "proteins", ":math:`mmol` :math:`C/m^3`" - "fed", "Fedin(1)", "`tr_bgc_Fe`", "dissolved iron", ":math:`\mu` :math:`Fe/m^3`" - "fep", "Fepin(1)", "`tr_bgc_Fe`", "particulate iron", ":math:`\mu` :math:`Fe/m^3`" + "DIC", "DICin(1)", "`tr_bgc_DIC`", "dissolved inorganic carbon", ":math:`mmol` :math:`C/m^3`" + "DON", "DONin(1)", "`tr_bgc_DON`", "proteins", ":math:`mmol` :math:`N/m^3`" + "fed", "Fedin(1)", "`tr_bgc_Fe`", "dissolved iron", ":math:`\mu mol` :math:`Fe/m^3`" + "fep", "Fepin(1)", "`tr_bgc_Fe`", "particulate iron", ":math:`\mu mol` :math:`Fe/m^3`" ":math:`{\mbox{NO$_3$}}`", "Nitin", "`tr_bgc_Nit`", ":math:`{\mbox{NO$_3$}}`", ":math:`mmol` :math:`N/m^3`" ":math:`{\mbox{NH$_4$}}`", "Amin", "`tr_bgc_Am`", ":math:`{\mbox{NH$_4$}}`", ":math:`mmol` :math:`N/m^3`" ":math:`{\mbox{SiO$_3$}}`", "Silin", "`tr_bgc_Sil`", ":math:`{\mbox{SiO$_2$}}`", ":math:`mmol` :math:`Si/m^3`" @@ -1007,7 +1020,7 @@ are true). "DMSPd", "DMSPdin", "`tr_bgc_DMS`", "dissolved DMSP", ":math:`mmol` :math:`S/m^3`" "DMS", "DMSin", "`tr_bgc_DMS`", "DMS", ":math:`mmol` :math:`S/m^3`" "PON", "PON :math:`^a`", "`tr_bgc_PON`", "passive mobile tracer", ":math:`mmol` :math:`N/m^3`" - "hum", "hum :math:`^{ab}`", "`tr_bgc_hum`", "passive sticky tracer", ":math:`mmol` :math:`/m^3`" + "hum", "hum :math:`^{a}`", "`tr_bgc_hum`", "refractory dissolved organic carbon", ":math:`mmol C` :math:`/m^3`" "BC (1)", "zaero(1) :math:`^a`", "`tr_zaero`", "black carbon species 1", ":math:`kg` :math:`/m^3`" "BC (2)", "zaero(2) :math:`^a`", "`tr_zaero`", "black carbon species 2", ":math:`kg` :math:`/m^3`" "dust (1)", "zaero(3) :math:`^a`", "`tr_zaero`", "dust species 1", ":math:`kg` :math:`/m^3`" @@ -1017,33 +1030,31 @@ are true). :math:`^a` not modified in *algal_dyn* -:math:`^b` may be in C or N units depending on the ocean concentration - The biochemical reaction term for each algal species has the form: .. math:: - \Delta {\mbox{N}}/dt = R_{{\mbox{N}}} = \mu (1- f_{graze} - f_{res}) - M_{ort} + \Delta {\mbox{N}}/dt = R_{{\mbox{N}}} = \mu (1 - f_{res}) - M_{ort} - G_{raze} where :math:`\mu` is the algal growth rate, :math:`M_{ort}` is a -mortality loss, :math:`f_{graze}` is the fraction of algal growth that -is lost to predatory grazing, and :math:`f_{res}` is the fraction of -algal growth lost to respiration. Algal mortality is temperature -dependent and limited by a maximum loss rate fraction (:math:`l_{max}`): +mortality loss, :math:`G_{raze}` is a loss term from implicit predatory grazing, and :math:`f_{res}` is the fraction of algal growth lost to respiration. Algal mortality is temperature +dependent. Both are limited by a maximum loss rate fraction (:math:`l_{max}`). For each algal type, we have: .. math:: - M_{ort} = \min( l_{max}[{\mbox{N}}], m_{pre} \exp\{m_{T}(T-T_{max})\}[{\mbox{N}}]) + G_{raze} = \min( l_{max} * {\mbox{N}}/dt, \mu * fr_{graze}(k) * ({\mbox{N}}/graze_{conc})^{graze_{exponent}}) Note, :math:`[\cdot]` denotes brine concentration. +.. math:: + M_{ort} = \min( l_{max}[{\mbox{N}}], m_{pre} \exp\{m_{T}(T-T_{max})\}[{\mbox{N}}]) + Nitrate and ammonium reaction terms are given by .. math:: \begin{aligned} - \Delta{\mbox{NO$_3$}}/dt & = & R_{{\mbox{NO$_3$}}} = [{\mbox{NH$_4$}}] k_{nitr}- U^{tot}_{{\mbox{NO$_3$}}} \nonumber \\ - \Delta{\mbox{NH$_4$}}/dt & = & R_{{\mbox{NH$_4$}}} = -[{\mbox{NH$_4$}}] k_{nitr} -U^{tot}_{{\mbox{NH$_4$}}} + - (f_{ng}f_{graze}(1-f_{gs})+f_{res})\mu^{tot} \nonumber \\ - & + & f_{nm} M_{ort} + \frac{\Delta{\mbox{NO$_3$}}}{dt} = R_{{\mbox{NO$_3$}}} & = & [{\mbox{NH$_4$}}] k_{nitr}- U^{tot}_{{\mbox{NO$_3$}}} \nonumber \\ + \frac{\Delta{\mbox{NH$_4$}}}{dt} = R_{{\mbox{NH$_4$}}} & = & -[{\mbox{NH$_4$}}] k_{nitr} -U^{tot}_{{\mbox{NH$_4$}}} + + (f_{ng}f_{graze}(1-f_{gs})+f_{res})\mu^{tot} + f_{nm} M_{ort} \nonumber \\ & = & -[{\mbox{NH$_4$}}]k_{nitr} -U^{tot}_{{\mbox{NH$_4$}}} + N_{remin}\end{aligned} @@ -1055,15 +1066,19 @@ ammonium and :math:`f_{gs}` is the fraction of grazing spilled or lost. Algal growth and nutrient uptake terms are described in more detail in :ref:`growth-uptake`. -Dissolved organic nitrogen satisfies the equation + +Dissolved organic nitrogen depends on the sum of all grazing :math:`graze^{tot}` and mortality :math:`M_{ort}^{tot}` and satisfies the equation .. math:: \begin{aligned} - \Delta {\mbox{DON}}/dt & = & R_{{\mbox{DON}}} = f_{dg}f_{gs}f_{graze}\mu^{tot} - [{\mbox{DON}}]k_{nb}\end{aligned} + \frac{\Delta {\mbox{DON}}}{dt} & = & R_{{\mbox{DON}}} \nonumber \\ + & = & graze^{tot} - graze^{tot}(1-fr_{graze_s})*fr_{graze_e} + M_{ort}^{tot}(1 - fr_{mort2min}) - [{\mbox{DON}}]k_{nb} \\ + & = & DON_{source} - [{\mbox{DON}}]k_{nb} + \end{aligned} With a loss from bacterial degration (rate :math:`k_{nb}`) and a gain -from spilled grazing that does not enter the :math:`{\mbox{NH$_4$}}` +from spilled grazing and mortality that does not enter the :math:`{\mbox{NH$_4$}}` pool. A term Z\ :math:`_{oo}` closes the nitrogen cycle by summing all the @@ -1077,8 +1092,8 @@ cycle at each timestep. .. math:: \begin{aligned} - \mbox{Z}_{oo} & = & [(1-f_{ng}(1-f_{gs}) - f_{dg}f_{gs}]f_{graze}\mu^{tot}dt + (1-f_{nm})M_{ort}dt + - [{\mbox{DON}}]k_{nb}dt \nonumber\end{aligned} + \mbox{Z}_{oo} & = & (1-fr_{graze_e})(1-fr_{graze_s})graze^{tot} + fr_{graze_s} graze^{tot} + M_{ort}^{tot}(1 - fr_{mort2min}) + \nonumber\end{aligned} Dissolved organic carbon may be divided into polysaccharids and lipids. Parameters are two dimensional (indicated by superscript :math:`i`) with @@ -1088,15 +1103,16 @@ lipids. The :math:`{\mbox{DOC}}^i` equation is: .. math:: \begin{aligned} - \Delta {\mbox{DOC}}^i/dt & = & R_{{\mbox{DOC}}} = f^i_{cg}f_{ng}\mu^{tot} + R^i_{c:n}M_{ort}-[{\mbox{DOC}}]k^i_{cb}\end{aligned} - + \frac{\Delta {\mbox{DOC}}^i}{dt} & = & R_{{\mbox{DOC}}} = f^i_{cg}(graze^{tot} + M_{ort}^{tot} - f_{ng}\mu^{tot} - \frac{DON_{source}}{dt}) R^i_{c:n}-[{\mbox{DOC}}]k^i_{cb} \\ + & = & R_{{\mbox{DOC}}} = f^i_{cg}(graze^{tot} + M_{ort}^{tot} - f_{ng}\mu^{tot} - \frac{DON_{source}}{dt}) R^i_{c:n} - \frac{DOC_{loss}}{dt}\end{aligned} + Silicate has no biochemical source terms within the ice and is lost only through algal uptake: .. math:: \begin{aligned} - \Delta {\mbox{SiO$_3$}}/dt & = & R_{{\mbox{SiO$_3$}}} = -U_{{\mbox{SiO$_3$}}}^{tot}\end{aligned} + \frac{\Delta {\mbox{SiO$_3$}}}{dt} & = & R_{{\mbox{SiO$_3$}}} = -U_{{\mbox{SiO$_3$}}}^{tot}\end{aligned} Dissolved iron has algal uptake and remineralization pathways. In addition, :math:`{\mbox{fed}}` may be converted to or released from the @@ -1109,16 +1125,16 @@ and particulate iron is .. math:: \begin{aligned} - \Delta_{fe}{\mbox{fed}}/dt & = & -[{\mbox{fed}}]/\tau_{fe} \nonumber \\ - \Delta_{fe}{\mbox{fep}}/dt & = & [{\mbox{fed}}]/\tau_{fe}\end{aligned} + \frac{\tilde{\Delta} {\mbox{fed}}}{dt} & = & -\frac{[{\mbox{fed}}]}{\tau_{fe}} \nonumber \\ + \frac{\tilde{\Delta} {\mbox{fep}}}{dt} & = & \frac{[{\mbox{fed}}]}{\tau_{fe}}\end{aligned} -For values less than :math:`r^{max}_{fed:doc}` +for values less than :math:`r^{max}_{fed:doc}`. .. math:: \begin{aligned} - \Delta_{fe}{\mbox{fed}}/dt & = & [{\mbox{fep}}]/\tau_{fe} \nonumber \\ - \Delta_{fe}{\mbox{fep}}/dt & = & -[{\mbox{fep}}]/\tau_{fe}\end{aligned} + \frac{\tilde{\Delta} {\mbox{fed}}}{dt} & = & \frac{[{\mbox{fep}}]}{\tau_{fe}} \nonumber \\ + \frac{\tilde{\Delta} {\mbox{fep}}}{dt} & = & -\frac{[{\mbox{fep}}]}{\tau_{fe}}\end{aligned} Very long timescales :math:`\tau_{fe}` will remove this source/sink term. The default value is currently set at 3065 days to turn off this @@ -1131,8 +1147,8 @@ remineralization is .. math:: \begin{aligned} - \Delta {\mbox{fed}}/dt & = & R_{{\mbox{fed}}} = -U^{tot}_{{\mbox{fed}}} + f_{fa}R_{fe:n}N_{remin} - + \Delta_{fe}{\mbox{fed}}/dt\end{aligned} + \frac{\Delta {\mbox{fed}}}{dt} & = & R_{{\mbox{fed}}} = -U^{tot}_{{\mbox{fed}}} + f_{fa}R_{fe:n}N_{remin} + + \frac{\tilde{\Delta}{\mbox{fed}}}{dt}\end{aligned} Particulate iron also includes a source term from algal mortality and grazing that is not immediately bioavailable. The full equation for @@ -1141,8 +1157,8 @@ grazing that is not immediately bioavailable. The full equation for .. math:: \begin{aligned} - \Delta {\mbox{fep}}/dt & = & R_{{\mbox{fep}}} = R_{fe:n}[\mbox{Z}_{oo}/dt + (1-f_{fa})]N_{remin} - + \Delta_{fe}{\mbox{fep}}/dt\end{aligned} + \frac{\Delta {\mbox{fep}}}{dt} & = & R_{{\mbox{fep}}} = R_{fe:n}[\frac{\mbox{Z}_{oo}}{dt} + (1-f_{fa})]N_{remin} + + \frac{\tilde{\Delta}{\mbox{fep}}}{dt}\end{aligned} The sulfur cycle includes :math:`{\mbox{DMS}}` and dissolved DMSP (:math:`{\mbox{DMSPd}}`). Particulate DMSP is assumed to be proportional @@ -1153,9 +1169,21 @@ to the algal concentration, i.e. .. math:: \begin{aligned} - \Delta {\mbox{DMSPd}}/dt & = & R_{{\mbox{DMSPd}}} = R_{s:n}[ f_{sr}f_{res}\mu^{tot} - +f_{nm}M_{ort} ] - [{\mbox{DMSPd}}]/\tau_{dmsp} \nonumber \\ - \Delta {\mbox{DMS}}/dt & = & R_{{\mbox{DMS}}} = y_{dms}[{\mbox{DMSPd}}]/\tau_{dmsp} - [{\mbox{DMS}}]/\tau_{dms}\end{aligned} + \frac{\Delta {\mbox{DMSPd}}}{dt} & = & R_{{\mbox{DMSPd}}} = R_{s:n}[ f_{sr}f_{res}\mu^{tot} + +f_{nm}M_{ort} ] - \frac{[{\mbox{DMSPd}}]}{\tau_{dmsp}} \nonumber \\ + \frac{\Delta {\mbox{DMS}}}{dt} & = & R_{{\mbox{DMS}}} = y_{dms}\frac{[{\mbox{DMSPd}}]}{\tau_{dmsp}} - \frac{[{\mbox{DMS}}]}{\tau_{dms}}\end{aligned} + +The dissolved inorganic carbon tracer, :math:`{\mbox{DIC}}`, currently serves to conserve carbon in sea ice. There is no alkalinity tracer nor precipitated forms of carbonate that would be needed for solving the carbonate chemistry. In addition, :math:`{\mbox{DIC}}` never limits photosynthesis in this formulation and carbon to nitrogen ratios for each algal species are fixed at run-time. In the event that :math:`{\mbox{DIC}}` algal requirements exceed the available in situ concentration at a given timestep, the demand is met by an assumed ocean flux into the sea ice. :math:`{\mbox{DIC}}` reactive sources are equivalent to the remineralized losses of :math:`{\mbox{DON}}_{loss} = [{\mbox{DON}}] k_{nb}` and :math:`{\mbox{DOC}}^{tot}_{loss} = \sum^{i} [{\mbox{DOC}}]_i (k_{bac})_i` + +The :math:`{\mbox{DIC}}` reaction equation is + +.. math:: + + \begin{aligned} + \frac{\Delta {\mbox{DIC}}}{dt} & = & R_{{\mbox{DIC}}} = {\mbox{DON}}_{loss} * R_{C2N:DON} + {\mbox{DOC}}^{tot}_{loss}-\sum^{algae} [(1-fr_{resp})*grow_{N} * R_{C:N}]\end{aligned} + +where the summation is over all algal groups, :math:`R_{C:N}` is the carbon to nitrogen ratio of each algal group :math:`{\mbox{N}}`, and :math:`R_{C2N:DON}` is the carbon to nitrogen ratio of :math:`{\mbox{DON}}`. + See :ref:`tuning` for a more complete list and description of biogeochemical parameters. @@ -1180,13 +1208,12 @@ limitation terms may also be found for :math:`{\mbox{NH$_4$}}`, Light limitation :math:`L_{lim}` is defined in the following way: :math:`I _{sw}(z)` (in :math:`W/m^2`) is the shortwave radiation at the ice level -and the optical depth is proportional to the chlorophyll concentration, -:math:`op_{dep} =` ``chlabs`` [Chl*a*]. If ( :math:`op_{dep} > op_{min}`) then +and the optical depth :math:`op_{dep}` is proportional to the chlorophyll concentration. If ( :math:`op_{dep} > op_{min}`) then .. math:: - I_{avg} = I_{sw}(1- \exp(-op_{dep}))/op_{dep} + I_{avg} = I_{sw}\frac{(1- \exp(-op_{dep}))}{op_{dep}} -otherwise :math:`I_{avg} = I_{sw}`. +otherwise :math:`I_{avg} = I_{sw}`. Then, .. math:: L_{lim} = (1 - \exp(-\alpha I_{avg}))\exp(-\beta I_{avg}) @@ -1196,7 +1223,7 @@ The maximal algal growth rate before limitation is .. math:: \begin{aligned} \mu_o & = & \mu_{max}\exp(\mu_T\Delta T)f_{sal}[{\mbox{N}}] \\ - \mu' & = & min(L_{lim},N_{lim},{\mbox{SiO$_3$}}_{lim},{\mbox{fed}}_{lim}) \mu_o\end{aligned} + \mu' & = & min(L_{lim},\ N_{lim},\ {\mbox{SiO$_3$}}_{lim},\ {\mbox{fed}}_{lim}) \mu_o\end{aligned} where :math:`\mu'` is the initial estimate of algal growth rate for a given algal species and :math:`\Delta T` is the difference between the @@ -1241,8 +1268,13 @@ uptake is .. math:: \begin{aligned} - fU^i_{{\mbox{NO$_3$}}} & = & \frac{\tilde{U}^i_{{\mbox{NO$_3$}}}}{\tilde{U}^{tot}_{{\mbox{NO$_3$}}}} \nonumber \\ - U^{tot}_{{\mbox{NO$_3$}}} & = & \min(\tilde{U}^{tot}_{{\mbox{NO$_3$}}}, l_{max}[{\mbox{NO$_3$}}]/dt)\end{aligned} + fU^i_{{\mbox{NO$_3$}}} & = & \frac{\tilde{U}^i_{{\mbox{NO$_3$}}}}{\tilde{U}^{tot}_{{\mbox{NO$_3$}}}},\end{aligned} + +and the true total update is + +.. math:: + \begin{aligned} + U^{tot}_{{\mbox{NO$_3$}}} & = & \min(\tilde{U}^{tot}_{{\mbox{NO$_3$}}}, l_{max}[{\mbox{NO$_3$}}]/dt) .\end{aligned} Now, for each algal species the nitrate uptake is @@ -1254,7 +1286,7 @@ Then the true growth rate for each algal species :math:`i` is .. math:: \begin{aligned} - \mu^i & = & \min(U^i_{{\mbox{SiO$_3$}}}/R_{si:n}, U^i_{{\mbox{NO$_3$}}} + U^i_{{\mbox{NH$_4$}}}, U^i_{{\mbox{fed}}}/R_{fe:n})\end{aligned} + \mu^i & = & \min(R_{si:n}^{-1}U^i_{{\mbox{SiO$_3$}}}, U^i_{{\mbox{NO$_3$}}} + U^i_{{\mbox{NH$_4$}}}, R_{fe:n}^{-1}U^i_{{\mbox{fed}}})\end{aligned} Preferential ammonium uptake is assumed once again and the remaining nitrogen is taken from the nitrate pool. diff --git a/doc/source/user_guide/ug_case_settings.rst b/doc/source/user_guide/ug_case_settings.rst index cb5e5cb67..3dea32fb6 100644 --- a/doc/source/user_guide/ug_case_settings.rst +++ b/doc/source/user_guide/ug_case_settings.rst @@ -103,11 +103,11 @@ can be modified as needed. "NBGCLYR", "integer", "number of zbgc layers", "1" "TRZAERO", "0-6", "number of z aerosol tracers", "0" "TRALG", "0,1,2,3", "number of algal tracers", "0" - "TRDOC", "0,1,2,3", "number of dissolved organic carbon", "0" + "TRDOC", "0,1,2", "number of dissolved organic carbon", "0" "TRDIC", "0,1", "number of dissolved inorganic carbon", "0" "TRDON", "0,1", "number of dissolved organic nitrogen", "0" - "TRFEP", "0,1,2", "number of particulate iron tracers", "0" - "TRFED", "0,1,2", "number of dissolved iron tracers", "0" + "TRFEP", "0,1", "number of particulate iron tracers", "0" + "TRFED", "0,1", "number of dissolved iron tracers", "0" "ICE_SNICARHC", "true,false", "include hardcoded (HC) snicar tables", "false" "ICE_BLDDEBUG", "true,false", "turn on compile debug flags", "false" "ICE_COVERAGE", "true,false", "turn on code coverage flags", "false" @@ -265,7 +265,7 @@ shortwave_nml "``shortwave``", "``ccsm3``", "NCAR CCSM3 shortwave distribution method", "``dEdd``" "", "``dEdd``", "Delta-Eddington method (3-band)", "" "", "``dEdd_snicar_ad``", "Delta-Eddington method with 5-band snow", "" - "``snw_ssp_table``", "``snicar``", "lookup table for `dEdd_snicar_ad`", "" + "``snw_ssp_table``", "``snicar``", "lookup table for `dEdd_snicar_ad`", "test" "", "``test``", "reduced lookup table for `dEdd_snicar_ad` testing", "" "``sw_dtemp``", "real", "temperature from melt for sw_redist", "0.02" "``sw_frac``", "real", "fraction of shortwave redistribution", "0.9" @@ -284,7 +284,7 @@ ponds_nml "``frzpnd``", "``cesm``", "CESM pond refreezing forumulation", "``cesm``" "", "``hlid``", "Stefan refreezing with pond ice thickness", "" "``hp1``", "real", "critical ice lid thickness for topo ponds in m", "0.01" - "``hs0``", "real", "snow depth of transition to bare sea ice in m", "" + "``hs0``", "real", "snow depth of transition to bare sea ice in m", "0.03" "``hs1``", "real", "snow depth of transition to pond ice in m", "0.03" "``pndaspect``", "real", "aspect ratio of pond changes (depth:area)", "0.8" "``rfracmax``", ":math:`0 \le r_{max} \le 1`", "maximum melt water added to ponds", "0.85" @@ -307,12 +307,12 @@ snow_nml "``rsnw_tmax``", "real", "maximum snow radius (um)", "1500.0" "``snw_aging_table``", "test", "snow aging lookup table", "test" "", "snicar", "(not available in Icepack)", "" - "``snwgrain``", "logical", "snow grain metamorphosis", ".true." + "``snwgrain``", "logical", "snow grain metamorphosis", ".false." "``snwlvlfac``", "real", "fraction increase in bulk snow redistribution", "0.3" - "``snwredist``", "``snwITDrdg``", "snow redistribution using ITD/ridges", "snwITDrdg" + "``snwredist``", "``snwITDrdg``", "snow redistribution using ITD/ridges", "none" "", "``bulk``", "bulk snow redistribution", "" "", "``none``", "no snow redistribution", "" - "``use_smliq_pnd``", "logical", "use liquid in snow for ponds", ".true." + "``use_smliq_pnd``", "logical", "use liquid in snow for ponds", ".false." "``windmin``", "real", "minimum wind speed to compact snow", "10.0" "", "", "", "" @@ -392,69 +392,70 @@ forcing_nml "", "``random``", "wave data file is provided, sea surface height generated using random number (multiple iterations of wave fracture)", "" "``ycycle``", "integer", "number of years in forcing data cycle", "1" "", "", "", "" + +* = If Icepack is run stand-alone and wave_spec_type is not set to none, then a fixed wave spectrum is defined in the code to use for testing. As with other input data, this spectrum should not be used for production runs or publications. zbgc_nml ~~~~~~~~~~~~~~~~~~~~~~~~~ +.. _tab-bio-tracers-namelist2: + .. csv-table:: **zbgc_nml namelist options** :header: "variable", "options/format", "description", "default value" - :widths: 15, 15, 30, 15 + :widths: 15, 15, 30, 15 "", "", "", "" "``algaltype_diatoms``", "real", "mobility type between stationary and mobile algal diatoms", "0.0" - "``algaltype_phaeo``", "real", "mobility type between stationary and mobile algal phaeocystis", "0.5" - "``algaltype_sp``", "real", "mobility type between stationary and mobile small plankton", "0.5" - "``algal_vel``", "real", ":cite:`Lavoie05`", "1.11e-8" - "``alpha2max_low_diatoms``", "real", "light limitation diatoms 1/(W/m^2)", "0.8" - "``alpha2max_low_phaeo``", "real", "light limitation phaeocystis 1/(W/m^2)", "0.67" - "``alpha2max_low_sp``", "real", "light limitation small plankton 1/(W/m^2)", "0.67" - "``ammoniumtype``", "real", "mobility type between stationary and mobile ammonium", "1.0" - "``beta2max_diatoms``", "real", "light inhibition diatoms 1/(W/m^2)", "0.18" - "``beta2max_phaeo``", "real", "light inhibition phaeocystis 1/(W/m^2)", "0.01" - "``beta2max_sp``", "real", "light inhibition small plankton 1/(W/m^2)", "0.0025" - "``bgc_data_type``", "``clim``", "bgc climatological data", "``default``" - "", "``default``", "constant values defined in the code", "" - "", "``ncar``", "POP ocean forcing data", "" + "``algaltype_phaeo``", "real", "mobility type between stationary and mobile algal phaeocystis", "0.0" + "``algaltype_sp``", "real", "mobility type between stationary and mobile small plankton", "0.0" + "``algal_vel``", "real", "maximum speed of algae (m/s) :cite:`Lavoie05`", "1.0e-7" + "``alpha2max_low_diatoms``", "real", "light limitation diatoms 1/(W/m^2)", "0.3" + "``alpha2max_low_phaeo``", "real", "light limitation phaeocystis 1/(W/m^2)", "0.17" + "``alpha2max_low_sp``", "real", "light limitation small plankton 1/(W/m^2)", "0.2" + "``ammoniumtype``", "real", "mobility type between stationary and mobile ammonium", "0.0" + "``beta2max_diatoms``", "real", "light inhibition diatoms 1/(W/m^2)", "0.001" + "``beta2max_phaeo``", "real", "light inhibition phaeocystis 1/(W/m^2)", "0.04" + "``beta2max_sp``", "real", "light inhibition small plankton 1/(W/m^2)", "0.001" "``bgc_flux_type``", "``constant``", "constant ice–ocean flux velocity", "``Jin2006``" "", "``Jin2006``", "ice–ocean flux velocity of :cite:`Jin06`", "" "``chlabs_diatoms``", "real", "chl absorbtion diatoms 1/m/(mg/m^3)", "0.03" "``chlabs_phaeo``", "real", "chl absorbtion phaeocystis 1/m/(mg/m^3)", "0.05" "``chlabs_sp``", "real", "chl absorbtion small plankton 1/m/(mg/m^3)", "0.01" - "``dEdd_algae``", "logical", "", "``.false.``" - "``dmspdtype``", "real", "mobility type between stationary and mobile dmspd", "-1.0" + "``dEdd_algae``", "logical", "include ice bgc and/or aerosols in radiative transfer", "``.false.``" + "``dmspdtype``", "real", "mobility type between stationary and mobile dmspd", "0.0" "``dmspptype``", "real", "mobility type between stationary and mobile dmspp", "0.5" - "``doctype_l``", "real", "mobility type between stationary and mobile doc lipids", "0.5" - "``doctype_s``", "real", "mobility type between stationary and mobile doc saccharids", "0.5" - "``dontype_protein``", "real", "mobility type between stationary and mobile don proteins", "0.5" + "``doctype_l``", "real", "mobility type between stationary and mobile doc lipids", "0.0" + "``doctype_s``", "real", "mobility type between stationary and mobile doc saccharids", "0.0" + "``dontype_protein``", "real", "mobility type between stationary and mobile don proteins", "0.0" "``dustFe_sol``", "real", "solubility fraction", "0.005" - "``fedtype_1``", "real", "mobility type between stationary and mobile fed lipids", "0.5" + "``fedtype_1``", "real", "mobility type between stationary and mobile fed lipids", "0.0" "``feptype_1``", "real", "mobility type between stationary and mobile fep lipids", "0.5" - "``frazil_scav``", "real", "increase in initial bio bracer from ocean scavenging", "1.0" - "``fr_dFe``", "real", "fraction of remineralized nitrogen in units of algal iron", "0.3" - "``fr_graze_diatoms``", "real", "fraction grazed diatoms", "0.01" + "``frazil_scav``", "real", "increase in initial bio bracer from ocean scavenging", "0.8" + "``fr_dFe``", "real", "fraction of remineralized iron from algae", "1.0" + "``fr_graze_diatoms``", "real", "fraction grazed diatoms", "0.19" "``fr_graze_e``", "real", "fraction of assimilation excreted", "0.5" - "``fr_graze_phaeo``", "real", "fraction grazed phaeocystis", "0.1" + "``fr_graze_phaeo``", "real", "fraction grazed phaeocystis", "0.19" "``fr_graze_s``", "real", "fraction of grazing spilled or slopped", "0.5" - "``fr_graze_sp``", "real", "fraction grazed small plankton", "0.1" - "``fr_mort2min``", "real", "fractionation of mortality to Am", "0.5" - "``fr_resp``", "real", "frac of algal growth lost due to respiration", "0.05" - "``fr_resp_s``", "real", "DMSPd fraction of respiration loss as DMSPd", "0.75" + "``fr_graze_sp``", "real", "fraction grazed small plankton", "0.19" + "``fr_mort2min``", "real", "fractionation of mortality to Am", "0.9" + "``fr_resp``", "real", "fraction of algal growth lost due to respiration", "0.05" + "``fr_resp_s``", "real", "DMSPd fraction of respiration loss as DMSPd", "0.9" "``fsal``", "real", "salinity limitation ppt", "1.0" "``F_abs_chl_diatoms``", "real", "scales absorbed radiation for dEdd chl diatoms", "2.0" "``F_abs_chl_phaeo``", "real", "scales absorbed radiation for dEdd chl phaeocystis", "5.0" "``F_abs_chl_sp``", "real", "scales absorbed radiation for dEdd small plankton", "4.0" - "``f_doc_l``", "real", "fraction of mortality to DOC lipids", "0.4" - "``f_doc_s``", "real", "fraction of mortality to DOC saccharides", "0.4" - "``f_don_Am_protein``", "real", "fraction of remineralized DON to ammonium", "0.25" + "``f_doc_l``", "real", "fraction of mortality to DOC lipids", "0.5" + "``f_doc_s``", "real", "fraction of mortality to DOC saccharides", "0.5" + "``f_don_Am_protein``", "real", "fraction of remineralized DON to ammonium", "1.0" "``f_don_protein``", "real", "fraction of spilled grazing to proteins", "0.6" "``f_exude_l``", "real", "fraction of exudation to DOC lipids", "1.0" "``f_exude_s``", "real", "fraction of exudation to DOC saccharids", "1.0" - "``grid_o``", "real", "z biology for bottom flux", "5.0" + "``grid_o``", "real", "z biology length scale for bottom flux (m)", "0.006" "``grid_oS``", "real", "DEPRECATED", "" - "``grow_Tdep_diatoms``", "real", "temperature dependence growth diatoms per degC", "0.06" - "``grow_Tdep_phaeo``", "real", "temperature dependence growth phaeocystis per degC", "0.06" - "``grow_Tdep_sp``", "real", "temperature dependence growth small plankton per degC", "0.06" - "``humtype``", "real", "mobility type between stationary and mobile hum", "1.0" + "``grow_Tdep_diatoms``", "real", "temperature dependence growth diatoms per degC", "0.063" + "``grow_Tdep_phaeo``", "real", "temperature dependence growth phaeocystis per degC", "0.063" + "``grow_Tdep_sp``", "real", "temperature dependence growth small plankton per degC", "0.063" + "``humtype``", "real", "mobility type between stationary and mobile hum", "0.0" "``initbio_frac``", "real", "fraction of ocean trcr concentration in bio tracers", "1.0" "``K_Am_diatoms``", "real", "ammonium half saturation diatoms mmol/m^3", "0.3" "``K_Am_phaeo``", "real", "ammonium half saturation phaeocystis mmol/m^3", "0.3" @@ -467,45 +468,45 @@ zbgc_nml "``K_Fe_diatoms``", "real", "iron half saturation diatoms nM", "1.0" "``K_Fe_phaeo``", "real", "iron half saturation phaeocystis nM", "0.1" "``K_Fe_sp``", "real", "iron half saturation small plankton nM", "0.2" - "``k_nitrif``", "real", "nitrification rate per day", "0.0" + "``k_nitrif``", "real", "nitrification rate per day", "0.046" "``K_Nit_diatoms``", "real", "nitrate half saturation diatoms mmol/m^3", "1.0" "``K_Nit_phaeo``", "real", "nitrate half saturation phaeocystis mmol/m^3", "1.0" "``K_Nit_sp``", "real", "nitrate half saturation small plankton mmol/m^3", "1.0" "``K_Sil_diatoms``", "real", "silicate half saturation diatoms mmol/m^3", "4.0" "``K_Sil_phaeo``", "real", "silicate half saturation phaeocystis mmol/m^3", "0.0" "``K_Sil_sp``", "real", "silicate half saturation small plankton mmol/m^3", "0.0" - "``kn_bac_protein``", "real", "bacterial degradation of DON per day", "0.03" - "``l_sk``", "real", "characteristic diffusive scale in m", "7.0" + "``kn_bac_protein``", "real", "bacterial degradation of DON per day", "0.2" + "``l_sk``", "real", "characteristic diffusive scale in m", "2.0" "``l_skS``", "real", "DEPRECATED", "" "``max_dfe_doc1``", "real", "max ratio of dFe to saccharides in the ice in nm Fe / muM C", "0.2" "``max_loss``", "real", "restrict uptake to percent of remaining value", "0.9" - "``modal_aero``", "logical", "modal aersols", "``.false.``" - "``mort_pre_diatoms``", "real", "mortality diatoms", "0.007" - "``mort_pre_phaeo``", "real", "mortality phaeocystis", "0.007" - "``mort_pre_sp``", "real", "mortality small plankton", "0.007" + "``modal_aero``", "logical", "modal aerosols", "``.false.``" + "``mort_pre_diatoms``", "real", "mortality diatoms per day", "0.007" + "``mort_pre_phaeo``", "real", "mortality phaeocystis per day", "0.007" + "``mort_pre_sp``", "real", "mortality small plankton per day", "0.007" "``mort_Tdep_diatoms``", "real", "temperature dependence of mortality diatoms per degC", "0.03" "``mort_Tdep_phaeo``", "real", "temperature dependence of mortality phaeocystis per degC", "0.03" "``mort_Tdep_sp``", "real", "temperature dependence of mortality small plankton per degC", "0.03" - "``mu_max_diatoms``", "real", "maximum growth rate diatoms per day", "1.2" - "``mu_max_phaeo``", "real", "maximum growth rate phaeocystis per day", "0.851" - "``mu_max_sp``", "real", "maximum growth rate small plankton per day", "0.851" + "``mu_max_diatoms``", "real", "maximum growth rate diatoms per day", "1.44" + "``mu_max_phaeo``", "real", "maximum growth rate phaeocystis per day", "0.63" + "``mu_max_sp``", "real", "maximum growth rate small plankton per day", "0.41" "``nitratetype``", "real", "mobility type between stationary and mobile nitrate", "-1.0" "``op_dep_min``", "real", "light attenuates for optical depths exceeding min", "0.1" - "``phi_snow``", "real", "snow porosity for brine height tracer", "0.5" + "``phi_snow``", "real", "snow porosity for brine height tracer (compute from snow density if negative)", "-1.0" "``ratio_chl2N_diatoms``", "real", "algal chl to N in mg/mmol diatoms", "2.1" "``ratio_chl2N_phaeo``", "real", "algal chl to N in mg/mmol phaeocystis", "0.84" "``ratio_chl2N_sp``", "real", "algal chl to N in mg/mmol small plankton", "1.1" "``ratio_C2N_diatoms``", "real", "algal C to N in mol/mol diatoms", "7.0" "``ratio_C2N_phaeo``", "real", "algal C to N in mol/mol phaeocystis", "7.0" - "``ratio_C2N_proteins``", "real", "algal C to N in mol/mol proteins", "7.0" + "``ratio_C2N_proteins``", "real", "algal C to N in mol/mol proteins", "5.0" "``ratio_C2N_sp``", "real", "algal C to N in mol/mol small plankton", "7.0" - "``ratio_Fe2C_diatoms``", "real", "algal Fe to C in umol/mol diatoms", "0.0033" - "``ratio_Fe2C_phaeo``", "real", "algal Fe to C in umol/mol phaeocystis", "1.0" - "``ratio_Fe2C_sp``", "real", "algal Fe to C in umol/mol small plankton", "0.0033" - "``ratio_Fe2N_diatoms``", "real", "algal Fe to N in umol/mol diatoms", "0.23" - "``ratio_Fe2N_phaeo``", "real", "algal Fe to N in umol/mol phaeocystis", "0.7" - "``ratio_Fe2N_sp``", "real", "algal Fe to N in umol/mol small plankton", "0.23" - "``ratio_Fe2DOC_s``", "real", "Fe to C of DON saccharids nmol/umol", "1.0" + "``ratio_Fe2C_diatoms``", "real", "algal Fe to C in mmol/mol diatoms", "0.0033" + "``ratio_Fe2C_phaeo``", "real", "algal Fe to C in mmol/mol phaeocystis", "0.1" + "``ratio_Fe2C_sp``", "real", "algal Fe to C in mmol/mol small plankton", "0.0033" + "``ratio_Fe2N_diatoms``", "real", "algal Fe to N in mmol/mol diatoms", "0.023" + "``ratio_Fe2N_phaeo``", "real", "algal Fe to N in mmol/mol phaeocystis", "0.7" + "``ratio_Fe2N_sp``", "real", "algal Fe to N in mmol/mol small plankton", "0.023" + "``ratio_Fe2DOC_s``", "real", "Fe to C of DON saccharids nmol/umol", "0.1" "``ratio_Fe2DOC_l``", "real", "Fe to C of DOC lipids nmol/umol", "0.033" "``ratio_Fe2DON``", "real", "Fe to C of DON nmol/umol", "0.023" "``ratio_Si2N_diatoms``", "real", "algal Si to N in mol/mol diatoms", "1.8" @@ -514,39 +515,39 @@ zbgc_nml "``ratio_S2N_diatoms``", "real", "algal S to N in mol/mol diatoms", "0.03" "``ratio_S2N_phaeo``", "real", "algal S to N in mol/mol phaeocystis", "0.03" "``ratio_S2N_sp``", "real", "algal S to N in mol/mol small plankton", "0.03" - "``restore_bgc``", "logical", "restore bgc to data", "``.false.``" + "``restore_bgc``", "logical", "DEPRECATED", "``.false.``" "``R_dFe2dust``", "real", "g/g :cite:`Tagliabue09`", "0.035" - "``scale_bgc``", "logical", "", "``.false.``" + "``scale_bgc``", "logical", "initialize bgc by scaling with salinity", "``.false.``" "``silicatetype``", "real", "mobility type between stationary and mobile silicate", "-1.0" - "``skl_bgc``", "logical", "biogeochemistry", "``.false.``" - "``solve_zbgc``", "logical", "", "``.false.``" + "``skl_bgc``", "logical", "DEPRECATED: skeletal layer biogeochemistry", "``.false.``" + "``solve_zbgc``", "logical", "solve z-biogeochemistry reactions", "``.false.``" "``solve_zsal``", "logical", "DEPRECATED", "``.false.``" - "``tau_max``", "real", "long time mobile to stationary exchanges", "1.73e-5" - "``tau_min``", "real", "rapid module to stationary exchanges", "5200." + "``tau_max``", "real", "long time mobile to stationary exchanges (s)", "604800.0" + "``tau_min``", "real", "rapid module to stationary exchanges (s)", "3600.0" "``tr_bgc_Am``", "logical", "ammonium tracer", "``.false.``" "``tr_bgc_C``", "logical", "algal carbon tracer", "``.false.``" "``tr_bgc_chl``", "logical", "algal chlorophyll tracer", "``.false.``" "``tr_bgc_DMS``", "logical", "DMS tracer", "``.false.``" "``tr_bgc_DON``", "logical", "DON tracer", "``.false.``" "``tr_bgc_Fe``", "logical", "iron tracer", "``.false.``" - "``tr_bgc_hum``", "logical", "", "``.false.``" - "``tr_bgc_Nit``", "logical", "", "``.false.``" - "``tr_bgc_PON``", "logical", "PON tracer", "``.false.``" + "``tr_bgc_hum``", "logical", "refractory DOC", "``.false.``" + "``tr_bgc_Nit``", "logical", "nitrate tracer", "``.false.``" + "``tr_bgc_PON``", "logical", "Non-reactive nitrate tracer", "``.false.``" "``tr_bgc_Sil``", "logical", "silicate tracer", "``.false.``" "``tr_brine``", "logical", "brine height tracer", "``.false.``" "``tr_zaero``", "logical", "vertical aerosol tracers", "``.false.``" "``t_iron_conv``", "real", "desorption loss pFe to dFe in days", "3065." - "``t_sk_conv``", "real", "Stefels conversion time in days", "3.0" - "``t_sk_ox``", "real", "DMS oxidation time in days", "10.0" - "``T_max``", "real", "maximum temperature degC", "0.0" - "``y_sk_DMS``", "real", "fraction conversion given high yield", "0.5" - "``zaerotype_bc1``", "real", "mobility type between stationary and mobile zaero bc1", "1.0" - "``zaerotype_bc2``", "real", "mobility type between stationary and mobile zaero bc2", "1.0" - "``zaerotype_dust1``", "real", "mobility type between stationary and mobile zaero dust1", "1.0" - "``zaerotype_dust2``", "real", "mobility type between stationary and mobile zaero dust2", "1.0" - "``zaerotype_dust3``", "real", "mobility type between stationary and mobile zaero dust3", "1.0" - "``zaerotype_dust4``", "real", "mobility type between stationary and mobile zaero dust4", "1.0" - "``z_tracers``", "logical", "", "``.false.``" + "``t_sk_conv``", "real", "Stefels conversion time in days", "5.0" + "``t_sk_ox``", "real", "DMS oxidation time in days", "12.0" + "``T_max``", "real", "maximum brine temperature degC", "0.0" + "``y_sk_DMS``", "real", "fraction conversion given high yield", "0.7" + "``zaerotype_bc1``", "real", "mobility type between stationary and mobile zaero bc1", "-1.0" + "``zaerotype_bc2``", "real", "mobility type between stationary and mobile zaero bc2", "-1.0" + "``zaerotype_dust1``", "real", "mobility type between stationary and mobile zaero dust1", "-1.0" + "``zaerotype_dust2``", "real", "mobility type between stationary and mobile zaero dust2", "-1.0" + "``zaerotype_dust3``", "real", "mobility type between stationary and mobile zaero dust3", "-1.0" + "``zaerotype_dust4``", "real", "mobility type between stationary and mobile zaero dust4", "-1.0" + "``z_tracers``", "logical", "allows vertically resolved bgc and/or z-aerosol tracers", "``.false.``" "", "", "", "" @@ -562,19 +563,18 @@ zbgc_nml .. "``restart_hbrine``", "logical", "", "``.false.``" .. "``solve_zsal``", "logical", "update salinity tracer profile", "``.false.``" .. "TRZS", "0,1", "zsalinity tracer, needs TRBRI=1", "0" - -* = If Icepack is run stand-alone and wave_spec_type is not set to none, then a fixed wave spectrum is defined in the code to use for testing. As with other input data, this spectrum should not be used for production runs or publications. .. _tuning: -BGC Tuning Parameters +BGC Parameter Arrays ------------------------ -Biogeochemical tuning parameters are specified as namelist options in -**icepack\_in**. Table :ref:`tab-bio-tracers2` provides a list of parameters + +Biogeochemical parameter arrays are specified in the code from namelist options in +**icepack\_in**. Table :ref:`tab-bio-tracers2` provides a list of parameter arrays used in the reaction equations, their representation in the code, a -short description of each and the default values. Please keep in mind -that there has only been minimal tuning of the model. +short description of each and the namelist parameters (Table :ref:`tab-bio-tracers-namelist2`) +used in their definition. .. _tab-bio-tracers2: @@ -582,41 +582,22 @@ that there has only been minimal tuning of the model. :header: "Text Variable", "Variable in code", "Description", "Value", "units" :widths: 7, 20, 15, 15, 15 - ":math:`f_{graze}`", "fr\_graze(1:3)", "fraction of growth grazed", "0, 0.1, 0.1", "1" - ":math:`f_{res}`", "fr\_resp", "fraction of growth respired", "0.05", "1" - ":math:`l_{max}`", "max\_loss", "maximum tracer loss fraction", "0.9", "1" - ":math:`m_{pre}`", "mort\_pre(1:3)", "maximum mortality rate", "0.007, 0.007, 0.007", "day\ :math:`^{-1}`" - ":math:`m_{T}`", "mort\_Tdep(1:3)", "mortality temperature decay", "0.03, 0.03, 0.03", ":math:`^o`\ C\ :math:`^{-1}`" - ":math:`T_{max}`", "T\_max", "maximum brine temperature", "0", ":math:`^o`\ C" - ":math:`k_{nitr}`", "k\_nitrif", "nitrification rate", "0", "day\ :math:`^{-1}`" - ":math:`f_{ng}`", "fr\_graze\_e", "fraction of grazing excreted", "0.5", "1" - ":math:`f_{gs}`", "fr\_graze\_s", "fraction of grazing spilled", "0.5", "1" - ":math:`f_{nm}`", "fr\_mort2min", "fraction of mortality to :math:`{\mbox{NH$_4$}}`", "0.5", "1" - ":math:`f_{dg}`", "f\_don", "frac. spilled grazing to :math:`{\mbox{DON}}`", "0.6", "1" - ":math:`k_{nb}`", "kn\_bac :math:`^a`", "bacterial degradation of :math:`{\mbox{DON}}`", "0.03", "day\ :math:`^{-1}`" - ":math:`f_{cg}`", "f\_doc(1:3)", "fraction of mortality to :math:`{\mbox{DOC}}`", "0.4, 0.4, 0.2 ", "1" - ":math:`R_{c:n}^c`", "R\_C2N(1:3)", "algal carbon to nitrogen ratio", "7.0, 7.0, 7.0", "mol/mol" - ":math:`k_{cb}`", "k\_bac1:3\ :math:`^a`", "bacterial degradation of DOC", "0.03, 0.03, 0.03", "day\ :math:`^{-1}`" - ":math:`\tau_{fe}`", "t\_iron\_conv", "conversion time pFe :math:`\leftrightarrow` dFe", "3065.0 ", "day" - ":math:`r^{max}_{fed:doc}`", "max\_dfe\_doc1", "max ratio of dFe to saccharids", "0.1852", "nM Fe\ :math:`/\mu`\ M C" - ":math:`f_{fa}`", "fr\_dFe ", "fraction of remin. N to dFe", "0.3", "1" - ":math:`R_{fe:n}`", "R\_Fe2N(1:3)", "algal Fe to N ratio", "0.023, 0.023, 0.7", "mmol/mol" - ":math:`R_{s:n}`", "R\_S2N(1:3)", "algal S to N ratio", "0.03, 0.03, 0.03", "mol/mol" - ":math:`f_{sr}`", "fr\_resp\_s", "resp. loss as DMSPd", "0.75", "1" - ":math:`\tau_{dmsp}`", "t\_sk\_conv", "Stefels rate", "3.0", "day" - ":math:`\tau_{dms}`", "t\_sk\_ox", "DMS oxidation rate", "10.0", "day" - ":math:`y_{dms}`", "y\_sk\_DMS", "yield for DMS conversion", "0.5", "1" - ":math:`K_{{\mbox{NO$_3$}}}`", "K\_Nit(1:3)", ":math:`{\mbox{NO$_3$}}` half saturation constant", "1,1,1", "mmol/m\ :math:`^{3}`" - ":math:`K_{{\mbox{NH$_4$}}}`", "K\_Am(1:3)", ":math:`{\mbox{NH$_4$}}` half saturation constant", "0.3, 0.3, 0.3", "mmol/m\ :math:`^{-3}`" - ":math:`K_{{\mbox{SiO$_3$}}}`", "K\_Sil(1:3)", "silicate half saturation constant", "4.0, 0, 0", "mmol/m\ :math:`^{-3}`" - ":math:`K_{{\mbox{fed}}}`", "K\_Fe(1:3)", "iron half saturation constant", "1.0, 0.2, 0.1", ":math:`\mu`\ mol/m\ :math:`^{-3}`" - ":math:`op_{min}`", "op\_dep\_min", "boundary for light attenuation", "0.1", "1" - ":math:`chlabs`", "chlabs(1:3)", "light absorption length per chla conc.", "0.03, 0.01, 0.05", "1\ :math:`/`\ m\ :math:`/`\ (mg\ :math:`/`\ m\ :math:`^{3}`)" - ":math:`\alpha`", "alpha2max\_low(1:3)", "light limitation factor", "0.25, 0.25, 0.25", "m\ :math:`^2`/W" - ":math:`\beta`", "beta2max(1:3)", "light inhibition factor", "0.018, 0.0025, 0.01", "m\ :math:`^2`/W" - ":math:`\mu_{max}`", "mu\_max(1:3)", "maximum algal growth rate", "1.44, 0.851, 0.851", "day\ :math:`^{-1}`" - ":math:`\mu_T`", "grow\_Tdep(1:3)", "temperature growth factor", "0.06, 0.06, 0.06", "day\ :math:`^{-1}`" - ":math:`f_{sal}`", "fsal", "salinity growth factor", "1", "1" - ":math:`R_{si:n}`", "R\_Si2N(1:3)", "algal silicate to nitrogen", "1.8, 0, 0", "mol/mol" - -:math:`^a` only (1:2) of DOC and DOC parameters have physical meaning + ":math:`f_{graze}`", "fr\_graze(1:3)", "fraction of growth grazed", "(``fr_graze_diatoms``, ``fr_graze_sp``, ``fr_graze_phaeo``)", "1" + ":math:`m_{pre}`", "mort\_pre(1:3)", "maximum mortality rate", "(``mort_pre_diatoms``, ``mort_pre_sp``, ``mort_pre_phaeo``)", "day\ :math:`^{-1}`" + ":math:`m_{T}`", "mort\_Tdep(1:3)", "mortality temperature decay", "(``mort_Tdep_diatoms``, ``mort_Tdep_sp``, ``mort_Tdep_phaeo``)", ":math:`^o`\ C\ :math:`^{-1}`" + ":math:`f_{cg}`", "f\_doc(1:2)", "fraction of mortality to :math:`{\mbox{DOC}}`", "(``f_doc_s``, ``f_doc_l``)", "1" + ":math:`R_{c:n}`", "R\_C2N(1:3)", "algal carbon to nitrogen ratio", "(``ratio_C2N_diatoms``, ``ratio_C2N_sp``, ``ratio_C2N_phaeo``)", "mol/mol" + ":math:`k_{cb}`", "k\_bac(1:2)", "bacterial degradation of DOC", "(``k_bac_s``, ``k_bac_l``)", "day\ :math:`^{-1}`" + ":math:`R_{fe:n}`", "R\_Fe2N(1:3)", "algal Fe to N ratio", "(``ratio_Fe2N_diatoms``, ``ratio_Fe2N_sp``, ``ratio_Fe2N_phaeo``)", "mmol/mol" + ":math:`R_{s:n}`", "R\_S2N(1:3)", "algal S to N ratio", "(``ratio_S2N_diatoms``, ``ratio_S2N_sp``, ``ratio_S2N_phaeo``)", "mol/mol" + ":math:`K_{{\mbox{NO$_3$}}}`", "K\_Nit(1:3)", ":math:`{\mbox{NO$_3$}}` half saturation constant", "(``K_Nit_diatoms``, ``K_Nit_sp``, ``K_Nit_phaeo``)", "mmol/m\ :math:`^{3}`" + ":math:`K_{{\mbox{NH$_4$}}}`", "K\_Am(1:3)", ":math:`{\mbox{NH$_4$}}` half saturation constant", "(``K_Am_diatoms``, ``K_Am_sp``, ``K_Am_phaeo``)", "mmol/m\ :math:`^{-3}`" + ":math:`K_{{\mbox{SiO$_3$}}}`", "K\_Sil(1:3)", "silicate half saturation constant", "(``K_Sil_diatoms``, ``K_Sil_sp``, ``K_Sil_phaeo``)", "mmol/m\ :math:`^{-3}`" + ":math:`K_{{\mbox{fed}}}`", "K\_Fe(1:3)", "iron half saturation constant", "(``K_Fe_diatoms``, ``K_Fe_sp``, ``K_Fe_phaeo``)", ":math:`\mu`\ mol/m\ :math:`^{-3}`" + ":math:`chlabs`", "chlabs(1:3)", "light absorption length per chla conc.", "(``chlabs_diatoms``, ``chlabs_sp``, ``chlabs_phaeo``)", "1\ :math:`/`\ m\ :math:`/`\ (mg\ :math:`/`\ m\ :math:`^{3}`)" + + ":math:`\alpha`", "alpha2max\_low(1:3)", "light limitation factor", "(``alpha2max_low_diatoms``, ``alpha2max_low_sp``, ``alpha2max_low_phaeo``)", "m\ :math:`^2`/W" + ":math:`\beta`", "beta2max(1:3)", "light inhibition factor", "(``beta2max_diatoms``, ``beta2max_sp``, ``beta2max_phaeo``)", "m\ :math:`^2`/W" + ":math:`\mu_{max}`", "mu\_max(1:3)", "maximum algal growth rate", "(``mu_max_diatoms``, ``mu_max_sp``, ``mu_max_phaeo``)", "day\ :math:`^{-1}`" + ":math:`\mu_T`", "grow\_Tdep(1:3)", "temperature growth factor", "(``grow_Tdep_diatoms``, ``grow_Tdep_sp``, ``grow_Tdep_phaeo``)", "day\ :math:`^{-1}`" + ":math:`R_{si:n}`", "R\_Si2N(1:3)", "algal silicate to nitrogen", "(``ratio_Si2N_diatoms``, ``ratio_Si2N_sp``, ``ratio_Si2N_phaeo``)", "mol/mol" From ba0bc0b8f76d965aa4186bc3e4ffc7255a91e7fb Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Fri, 27 Sep 2024 10:43:13 -0700 Subject: [PATCH 25/30] Update Derecho Port (#501) Update inteloneapi, cray, intel, nvhpc modules/compiler. Changes answers for inteloneapi and cray. Switch default Derecho queue from main to develop to support quicker turn around and lower costs. Develop is a shared queue. Error in the snow physics with the cray compiler needs further assessment, but suggest we merge this now as is. That error does not present itself in CICE with snow physics with the same cray compiler. --- configuration/scripts/icepack.batch.csh | 2 +- .../scripts/machines/Macros.derecho_inteloneapi | 5 +++-- configuration/scripts/machines/env.derecho_cray | 10 +++++----- configuration/scripts/machines/env.derecho_gnu | 2 +- configuration/scripts/machines/env.derecho_intel | 10 +++++----- .../scripts/machines/env.derecho_intelclassic | 2 +- configuration/scripts/machines/env.derecho_inteloneapi | 10 +++++----- configuration/scripts/machines/env.derecho_nvhpc | 10 +++++----- 8 files changed, 26 insertions(+), 25 deletions(-) diff --git a/configuration/scripts/icepack.batch.csh b/configuration/scripts/icepack.batch.csh index ae49998c4..8a077969d 100755 --- a/configuration/scripts/icepack.batch.csh +++ b/configuration/scripts/icepack.batch.csh @@ -55,7 +55,7 @@ cat >> ${jobfile} << EOFB #PBS -l job_priority=regular #PBS -N ${ICE_CASENAME} #PBS -A ${acct} -#PBS -l select=${nnodes}:ncpus=${corespernode}:mpiprocs=${taskpernodelimit}:ompthreads=${nthrds} +#PBS -l select=${nnodes}:ncpus=${corespernode}:mpiprocs=${taskpernodelimit}:ompthreads=${nthrds}:mem=5GB #PBS -l walltime=${ICE_RUNLENGTH} #PBS -j oe #PBS -W umask=022 diff --git a/configuration/scripts/machines/Macros.derecho_inteloneapi b/configuration/scripts/machines/Macros.derecho_inteloneapi index df7d5b42f..e073f8c21 100644 --- a/configuration/scripts/machines/Macros.derecho_inteloneapi +++ b/configuration/scripts/machines/Macros.derecho_inteloneapi @@ -12,11 +12,12 @@ FFLAGS := -fp-model precise -convert big_endian -assume byterecl -ftz -trace FFLAGS_NOOPT:= -O0 ifeq ($(ICE_BLDDEBUG), true) - FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created -link_mpi=dbg +# -check uninit is needed on the ld step but it still throws errors in 2023.* and 2024.0.*, likely compiler bug + FFLAGS += -O0 -g -check bounds -check pointers -fpe0 -check noarg_temp_created -link_mpi=dbg # FFLAGS += -O0 -g -check all -fpe0 -ftrapuv -fp-model except -check noarg_temp_created -link_mpi=dbg -stand f08 # FFLAGS += -O0 -g -check all -fpe0 -ftrapuv -fp-model except -check noarg_temp_created -init=snan,arrays -link_mpi=dbg else - FFLAGS += -O2 + FFLAGS += -O1 endif SCC := icx diff --git a/configuration/scripts/machines/env.derecho_cray b/configuration/scripts/machines/env.derecho_cray index 9faf34aa2..332c68e67 100644 --- a/configuration/scripts/machines/env.derecho_cray +++ b/configuration/scripts/machines/env.derecho_cray @@ -10,14 +10,14 @@ if ("$inp" != "-nomodules") then source ${MODULESHOME}/init/csh module --force purge -module load ncarenv/23.06 +module load ncarenv/23.09 module load craype -module load cce/15.0.1 +module load cce/16.0.1 module load ncarcompilers #module load cray-mpich/8.1.25 #module load hdf5/1.12.2 module load netcdf/4.9.2 -module load cray-libsci/23.02.1.1 +module load cray-libsci/23.09.1.1 # For perftools with mpiexec # module load perftools-base @@ -38,14 +38,14 @@ setenv OMP_STACKSIZE 64M setenv ICE_MACHINE_MACHNAME derecho setenv ICE_MACHINE_MACHINFO "HPE Cray EX Milan Slingshot 11" setenv ICE_MACHINE_ENVNAME cray -setenv ICE_MACHINE_ENVINFO "cce 15.0.1, netcdf4.9.2" +setenv ICE_MACHINE_ENVINFO "Cray clang/fortran cce 16.0.1, netcdf4.9.2" setenv ICE_MACHINE_MAKE gmake setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "qsub" setenv ICE_MACHINE_ACCT P00000000 -setenv ICE_MACHINE_QUEUE "main" +setenv ICE_MACHINE_QUEUE "develop" setenv ICE_MACHINE_TPNODE 128 setenv ICE_MACHINE_BLDTHRDS 1 setenv ICE_MACHINE_QSTAT "qstat " diff --git a/configuration/scripts/machines/env.derecho_gnu b/configuration/scripts/machines/env.derecho_gnu index 606dbbebc..0b5121c12 100644 --- a/configuration/scripts/machines/env.derecho_gnu +++ b/configuration/scripts/machines/env.derecho_gnu @@ -45,7 +45,7 @@ setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "qsub" setenv ICE_MACHINE_ACCT P00000000 -setenv ICE_MACHINE_QUEUE "main" +setenv ICE_MACHINE_QUEUE "develop" setenv ICE_MACHINE_TPNODE 128 setenv ICE_MACHINE_BLDTHRDS 1 setenv ICE_MACHINE_QSTAT "qstat " diff --git a/configuration/scripts/machines/env.derecho_intel b/configuration/scripts/machines/env.derecho_intel index fdf64e157..3c6bed2c0 100644 --- a/configuration/scripts/machines/env.derecho_intel +++ b/configuration/scripts/machines/env.derecho_intel @@ -10,14 +10,14 @@ if ("$inp" != "-nomodules") then source ${MODULESHOME}/init/csh module --force purge -module load ncarenv/23.06 +module load ncarenv/23.09 module load craype -module load intel/2023.0.0 +module load intel/2023.2.1 module load ncarcompilers #module load cray-mpich/8.1.25 #module load hdf5/1.12.2 module load netcdf/4.9.2 -module load cray-libsci/23.02.1.1 +module load cray-libsci/23.09.1.1 # For perftools with mpiexec # module load perftools-base @@ -38,14 +38,14 @@ setenv OMP_STACKSIZE 64M setenv ICE_MACHINE_MACHNAME derecho setenv ICE_MACHINE_MACHINFO "HPE Cray EX Milan Slingshot 11" setenv ICE_MACHINE_ENVNAME intel -setenv ICE_MACHINE_ENVINFO "ifort 2021.8.0 20221119, netcdf4.9.2" +setenv ICE_MACHINE_ENVINFO "ifort 2021.10.0 20230609, netcdf4.9.2" setenv ICE_MACHINE_MAKE gmake setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "qsub" setenv ICE_MACHINE_ACCT P00000000 -setenv ICE_MACHINE_QUEUE "main" +setenv ICE_MACHINE_QUEUE "develop" setenv ICE_MACHINE_TPNODE 128 setenv ICE_MACHINE_BLDTHRDS 1 setenv ICE_MACHINE_QSTAT "qstat " diff --git a/configuration/scripts/machines/env.derecho_intelclassic b/configuration/scripts/machines/env.derecho_intelclassic index a2d583733..b7ef39efe 100644 --- a/configuration/scripts/machines/env.derecho_intelclassic +++ b/configuration/scripts/machines/env.derecho_intelclassic @@ -45,7 +45,7 @@ setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "qsub" setenv ICE_MACHINE_ACCT P00000000 -setenv ICE_MACHINE_QUEUE "main" +setenv ICE_MACHINE_QUEUE "develop" setenv ICE_MACHINE_TPNODE 128 setenv ICE_MACHINE_BLDTHRDS 1 setenv ICE_MACHINE_QSTAT "qstat " diff --git a/configuration/scripts/machines/env.derecho_inteloneapi b/configuration/scripts/machines/env.derecho_inteloneapi index 358bd9834..70c98c68b 100644 --- a/configuration/scripts/machines/env.derecho_inteloneapi +++ b/configuration/scripts/machines/env.derecho_inteloneapi @@ -10,14 +10,14 @@ if ("$inp" != "-nomodules") then source ${MODULESHOME}/init/csh module --force purge -module load ncarenv/23.06 +module load ncarenv/23.09 module load craype -module load intel-oneapi/2023.0.0 +module load intel-oneapi/2023.2.1 module load ncarcompilers #module load cray-mpich/8.1.25 #module load hdf5/1.12.2 module load netcdf/4.9.2 -module load cray-libsci/23.02.1.1 +module load cray-libsci/23.09.1.1 # For perftools with mpiexec # module load perftools-base @@ -38,14 +38,14 @@ setenv OMP_STACKSIZE 64M setenv ICE_MACHINE_MACHNAME derecho setenv ICE_MACHINE_MACHINFO "HPE Cray EX Milan Slingshot 11" setenv ICE_MACHINE_ENVNAME inteloneapi -setenv ICE_MACHINE_ENVINFO "ifx 2023.0.0 20221201, netcdf4.9.2" +setenv ICE_MACHINE_ENVINFO "ifx 2023.2.0 20230721, netcdf4.9.2" setenv ICE_MACHINE_MAKE gmake setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "qsub" setenv ICE_MACHINE_ACCT P00000000 -setenv ICE_MACHINE_QUEUE "main" +setenv ICE_MACHINE_QUEUE "develop" setenv ICE_MACHINE_TPNODE 128 setenv ICE_MACHINE_BLDTHRDS 1 setenv ICE_MACHINE_QSTAT "qstat " diff --git a/configuration/scripts/machines/env.derecho_nvhpc b/configuration/scripts/machines/env.derecho_nvhpc index 4723c0da4..04c5ac456 100644 --- a/configuration/scripts/machines/env.derecho_nvhpc +++ b/configuration/scripts/machines/env.derecho_nvhpc @@ -10,14 +10,14 @@ if ("$inp" != "-nomodules") then source ${MODULESHOME}/init/csh module --force purge -module load ncarenv/23.06 +module load ncarenv/23.09 module load craype -module load nvhpc/23.5 +module load nvhpc/23.7 module load ncarcompilers #module load cray-mpich/8.1.25 #module load hdf5/1.12.2 module load netcdf/4.9.2 -module load cray-libsci/23.02.1.1 +module load cray-libsci/23.09.1.1 # For perftools with mpiexec # module load perftools-base @@ -38,14 +38,14 @@ setenv OMP_STACKSIZE 64M setenv ICE_MACHINE_MACHNAME derecho setenv ICE_MACHINE_MACHINFO "HPE Cray EX Milan Slingshot 11" setenv ICE_MACHINE_ENVNAME nvhpc -setenv ICE_MACHINE_ENVINFO "nvc 23.5-0, netcdf4.9.2" +setenv ICE_MACHINE_ENVINFO "nvfortran 23.7-0, netcdf4.9.2" setenv ICE_MACHINE_MAKE gmake setenv ICE_MACHINE_WKDIR /glade/derecho/scratch/$user/ICEPACK_RUNS setenv ICE_MACHINE_INPUTDATA /glade/campaign/cesm/development/pcwg setenv ICE_MACHINE_BASELINE /glade/derecho/scratch/$user/ICEPACK_BASELINE setenv ICE_MACHINE_SUBMIT "qsub" setenv ICE_MACHINE_ACCT P00000000 -setenv ICE_MACHINE_QUEUE "main" +setenv ICE_MACHINE_QUEUE "develop" setenv ICE_MACHINE_TPNODE 128 setenv ICE_MACHINE_BLDTHRDS 1 setenv ICE_MACHINE_QSTAT "qstat " From f5f03b92b206cbd59f9b284a0a98ef51c120b567 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Thu, 17 Oct 2024 09:48:12 -0700 Subject: [PATCH 26/30] Update Derecho Cray, rename subroutines, minor cleanup (#502) * Update Derecho Cray, rename subroutines, minor cleanup Update Derecho Cray, add -Rp to -O2 standard optimization to address SAME_TBS compiler bug that is triggered in limited cases. Reported issue to NCAR. -O2 -Rp changes answers relative to -O2. Rename two public Icepack subroutines, but maintain backward compatibility. Update the calls in Icepack driver, but also confirmed it works fine with the old names as well as in CICE with the old names. Closes #255 use icepack_therm_shared , only: icepack_init_thermo => icepack_init_salinity use icepack_therm_shared , only: icepack_init_trcr => icepack_init_enthalpy Add a check and abort for negative values in the sqrt in computation of Tin in function calculate_Tin_from_qin. Closes #482 Refactor calls to icepack_aggregate to make them consistent. This was part of the testing for the Derecho Cray bug, and decided to keep the implementation. Update comments associated with floeshape constant attribution. Change from Steele to Rothrock 1984. Closes #479 Clean up some of the variable declarations in subroutine set_state_var and module icedrv_state, merge multiple lines to one line and shift to assumed shape arrays where appropriate. Clean up implementation error in icedrv_restart.F90, subroutine restartfile. This subroutine was using a parameter, ntrcr, directly from icepack_tracers. Switched that to a call to icepack_query_tracer_sizes. Update documentation of kice noting it's use with BL99 and MU71. See #447. Generate updated interface documentation (./icepack.setup --docintfc) --- columnphysics/icepack_intfc.F90 | 7 +- columnphysics/icepack_parameters.F90 | 8 +- columnphysics/icepack_therm_shared.F90 | 42 +- configuration/driver/icedrv_InitMod.F90 | 39 +- configuration/driver/icedrv_init.F90 | 19 +- configuration/driver/icedrv_init_column.F90 | 4 +- configuration/driver/icedrv_restart.F90 | 36 +- configuration/driver/icedrv_state.F90 | 15 +- configuration/driver/icedrv_step.F90 | 28 +- .../scripts/machines/Macros.derecho_cray | 3 +- doc/source/icepack_index.rst | 2 +- doc/source/user_guide/interfaces.include | 743 ++++++++++-------- 12 files changed, 522 insertions(+), 424 deletions(-) diff --git a/columnphysics/icepack_intfc.F90 b/columnphysics/icepack_intfc.F90 index 2f8b648b3..2e96a7a9b 100644 --- a/columnphysics/icepack_intfc.F90 +++ b/columnphysics/icepack_intfc.F90 @@ -112,9 +112,12 @@ module icepack_intfc use icepack_therm_shared , only: icepack_snow_temperature use icepack_therm_shared , only: icepack_liquidus_temperature use icepack_therm_shared , only: icepack_sea_freezing_temperature - use icepack_therm_shared , only: icepack_init_thermo + use icepack_therm_shared , only: icepack_init_salinity use icepack_therm_shared , only: icepack_salinity_profile - use icepack_therm_shared , only: icepack_init_trcr + use icepack_therm_shared , only: icepack_init_enthalpy + ! for backwards compatibilty, remove in the future + use icepack_therm_shared , only: icepack_init_thermo => icepack_init_salinity + use icepack_therm_shared , only: icepack_init_trcr => icepack_init_enthalpy use icepack_mushy_physics , only: icepack_enthalpy_snow use icepack_mushy_physics , only: icepack_enthalpy_mush diff --git a/columnphysics/icepack_parameters.F90 b/columnphysics/icepack_parameters.F90 index ef82b0695..ed76b6b41 100644 --- a/columnphysics/icepack_parameters.F90 +++ b/columnphysics/icepack_parameters.F90 @@ -117,8 +117,8 @@ module icepack_parameters Timelt = 0.0_dbl_kind ,&! melting temperature, ice top surface (C) Tsmelt = 0.0_dbl_kind ,&! melting temperature, snow top surface (C) ice_ref_salinity =4._dbl_kind,&! (ppt) - ! kice is not used for mushy thermo kice = 2.03_dbl_kind ,&! thermal conductivity of fresh ice(W/m/deg) + ! kice is only used with ktherm=1 (BL99) and conduct='MU71' ksno = 0.30_dbl_kind ,&! thermal conductivity of snow (W/m/deg) hs_min = 1.e-4_dbl_kind ,&! min snow thickness for computing zTsn (m) snowpatch = 0.02_dbl_kind ,&! parameter for fractional snow area (m) @@ -316,7 +316,7 @@ module icepack_parameters nfreq = 25 ! number of frequencies real (kind=dbl_kind), public :: & - floeshape = 0.66_dbl_kind ! constant from Steele (unitless) + floeshape = 0.66_dbl_kind ! constant from Rothrock 1984 (unitless) real (kind=dbl_kind), public :: & floediam = 300.0_dbl_kind ! effective floe diameter for lateral melt (m) @@ -856,7 +856,7 @@ subroutine icepack_init_parameters( & nfreq_in ! number of frequencies real (kind=dbl_kind), intent(in), optional :: & - floeshape_in ! constant from Steele (unitless) + floeshape_in ! constant from Rothrock 1984 (unitless) logical (kind=log_kind), intent(in), optional :: & wave_spec_in ! if true, use wave forcing @@ -1876,7 +1876,7 @@ subroutine icepack_query_parameters( & nfreq_out ! number of frequencies real (kind=dbl_kind), intent(out), optional :: & - floeshape_out ! constant from Steele (unitless) + floeshape_out ! constant from Rothrock 1984 (unitless) logical (kind=log_kind), intent(out), optional :: & wave_spec_out ! if true, use wave forcing diff --git a/columnphysics/icepack_therm_shared.F90 b/columnphysics/icepack_therm_shared.F90 index 8f566bb9c..858e6c560 100644 --- a/columnphysics/icepack_therm_shared.F90 +++ b/columnphysics/icepack_therm_shared.F90 @@ -29,9 +29,9 @@ module icepack_therm_shared public :: calculate_Tin_from_qin, & surface_heat_flux, & dsurface_heat_flux_dTsf, & - icepack_init_thermo, & + icepack_init_salinity, & icepack_salinity_profile, & - icepack_init_trcr, & + icepack_init_enthalpy, & icepack_ice_temperature, & icepack_snow_temperature, & icepack_liquidus_temperature, & @@ -65,12 +65,12 @@ function calculate_Tin_from_qin (qin, Tmltk) & Tmltk ! melting temperature at one level real (kind=dbl_kind) :: & - Tin ! internal temperature + Tin ! internal temperature ! local variables real (kind=dbl_kind) :: & - aa1,bb1,cc1 ! quadratic solvers + aa1,bb1,cc1,csqrt ! quadratic solvers character(len=*),parameter :: subname='(calculate_Tin_from_qin)' @@ -78,8 +78,13 @@ function calculate_Tin_from_qin (qin, Tmltk) & aa1 = cp_ice bb1 = (cp_ocn-cp_ice)*Tmltk - qin/rhoi - Lfresh cc1 = Lfresh * Tmltk - Tin = min((-bb1 - sqrt(bb1*bb1 - c4*aa1*cc1)) / & - (c2*aa1),Tmltk) + csqrt = bb1*bb1 - c4*aa1*cc1 + if (csqrt < c0) then + call icepack_warnings_add(subname//' sqrt error: ') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + return + endif + Tin = min((-bb1 - sqrt(csqrt)) / (c2*aa1),Tmltk) else ! fresh ice Tin = (Lfresh + qin/rhoi) / cp_ice @@ -210,13 +215,14 @@ subroutine dsurface_heat_flux_dTsf(Tsf, rhoa, & end subroutine dsurface_heat_flux_dTsf !======================================================================= -!autodocument_start icepack_init_thermo -! Initialize the vertical profile of ice salinity and melting temperature. +!autodocument_start icepack_init_salinity +! Initialize the vertical profile of ice salinity. +! This subroutine was renamed from icepack_init_thermo in Oct 2024 ! ! authors: C. M. Bitz, UW ! William H. Lipscomb, LANL - subroutine icepack_init_thermo(sprofile) + subroutine icepack_init_salinity(sprofile) real (kind=dbl_kind), dimension(:), intent(out) :: & sprofile ! vertical salinity profile @@ -226,7 +232,7 @@ subroutine icepack_init_thermo(sprofile) integer (kind=int_kind) :: k ! ice layer index real (kind=dbl_kind) :: zn ! normalized ice thickness - character(len=*),parameter :: subname='(icepack_init_thermo)' + character(len=*),parameter :: subname='(icepack_init_salinity)' !----------------------------------------------------------------- ! Determine l_brine based on saltmax. @@ -239,7 +245,7 @@ subroutine icepack_init_thermo(sprofile) if (saltmax > min_salin) l_brine = .true. !----------------------------------------------------------------- - ! Prescibe vertical profile of salinity and melting temperature. + ! Prescibe vertical profile of salinity. ! Note this profile is only used for BL99 thermodynamics. !----------------------------------------------------------------- @@ -259,7 +265,7 @@ subroutine icepack_init_thermo(sprofile) enddo endif ! l_brine - end subroutine icepack_init_thermo + end subroutine icepack_init_salinity !======================================================================= !autodocument_start icepack_salinity_profile @@ -282,16 +288,17 @@ function icepack_salinity_profile(zn) result(salinity) nsal = 0.407_dbl_kind, & msal = 0.573_dbl_kind - character(len=*),parameter :: subname='(icepack_init_thermo)' + character(len=*),parameter :: subname='(icepack_salinity_profile)' salinity = (saltmax/c2)*(c1-cos(pi*zn**(nsal/(msal+zn)))) end function icepack_salinity_profile !======================================================================= -!autodocument_start icepack_init_trcr +!autodocument_start icepack_init_enthalpy +! This subroutine was renamed from icepack_init_trcr in Oct 2024 ! - subroutine icepack_init_trcr(Tair, Tf, & + subroutine icepack_init_enthalpy(Tair, Tf, & Sprofile, Tprofile, & Tsfc, & qin, qsn) @@ -320,7 +327,7 @@ subroutine icepack_init_trcr(Tair, Tf, & real (kind=dbl_kind) :: & slope, Ti - character(len=*),parameter :: subname='(icepack_init_trcr)' + character(len=*),parameter :: subname='(icepack_init_enthalpy)' ! surface temperature Tsfc = Tf ! default @@ -346,7 +353,7 @@ subroutine icepack_init_trcr(Tair, Tf, & qsn(k) = -rhos*(Lfresh - cp_ice*Ti) enddo ! nslyr - end subroutine icepack_init_trcr + end subroutine icepack_init_enthalpy !======================================================================= !autodocument_start icepack_liquidus_temperature @@ -406,6 +413,7 @@ function icepack_sea_freezing_temperature(sss) result(Tf) call icepack_warnings_add(subname//' tfrz_option unsupported: '//trim(tfrz_option)) call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + return endif diff --git a/configuration/driver/icedrv_InitMod.F90 b/configuration/driver/icedrv_InitMod.F90 index c077a9203..c45d28022 100644 --- a/configuration/driver/icedrv_InitMod.F90 +++ b/configuration/driver/icedrv_InitMod.F90 @@ -11,6 +11,7 @@ module icedrv_InitMod use icedrv_constants, only: nu_diag use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted use icepack_intfc, only: icepack_query_parameters, icepack_query_tracer_flags + use icepack_intfc, only: icepack_query_tracer_sizes use icepack_intfc, only: icepack_write_tracer_flags, icepack_write_tracer_indices use icepack_intfc, only: icepack_write_tracer_sizes, icepack_write_parameters use icedrv_system, only: icedrv_system_abort, icedrv_system_flush @@ -187,12 +188,13 @@ subroutine init_restart use icedrv_state ! almost everything integer(kind=int_kind) :: & - i ! horizontal indices + i, & ! horizontal indices + ntrcr ! tracer count logical (kind=log_kind) :: & - skl_bgc, & ! from icepack - z_tracers, & ! from icepack - tr_brine, & ! from icepack + skl_bgc, & ! from icepack + z_tracers, & ! from icepack + tr_brine, & ! from icepack tr_fsd ! from icepack character(len=*), parameter :: subname='(init_restart)' @@ -204,6 +206,7 @@ subroutine init_restart call icepack_query_parameters(skl_bgc_out=skl_bgc) call icepack_query_parameters(z_tracers_out=z_tracers) call icepack_query_tracer_flags(tr_brine_out=tr_brine, tr_fsd_out=tr_fsd) + call icepack_query_tracer_sizes(ntrcr_out=ntrcr) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & file=__FILE__,line= __LINE__) @@ -235,20 +238,20 @@ subroutine init_restart !----------------------------------------------------------------- do i = 1, nx if (tmask(i)) & - call icepack_aggregate(aicen=aicen(i,:), & - vicen=vicen(i,:), & - vsnon=vsnon(i,:), & - trcrn=trcrn(i,:,:), & - aice=aice (i), & - vice=vice (i), & - vsno=vsno (i), & - trcr=trcr (i,:), & - aice0=aice0(i), & - trcr_depend=trcr_depend, & - trcr_base=trcr_base, & - n_trcr_strata=n_trcr_strata, & - nt_strata=nt_strata, & - Tf=Tf(i)) + call icepack_aggregate(trcrn=trcrn(i,1:ntrcr,:), & + aicen=aicen(i,:), & + vicen=vicen(i,:), & + vsnon=vsnon(i,:), & + trcr=trcr (i,1:ntrcr), & + aice=aice (i), & + vice=vice (i), & + vsno=vsno (i), & + aice0=aice0(i), & + trcr_depend=trcr_depend(1:ntrcr), & + trcr_base=trcr_base (1:ntrcr,:), & + n_trcr_strata=n_trcr_strata(1:ntrcr), & + nt_strata=nt_strata (1:ntrcr,:), & + Tf = Tf(i)) enddo call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & diff --git a/configuration/driver/icedrv_init.F90 b/configuration/driver/icedrv_init.F90 index ac1873498..ddcd8b2f6 100644 --- a/configuration/driver/icedrv_init.F90 +++ b/configuration/driver/icedrv_init.F90 @@ -15,7 +15,7 @@ module icedrv_init use icepack_intfc, only: icepack_init_tracer_flags use icepack_intfc, only: icepack_init_tracer_sizes use icepack_intfc, only: icepack_init_tracer_indices - use icepack_intfc, only: icepack_init_trcr + use icepack_intfc, only: icepack_init_enthalpy use icepack_intfc, only: icepack_query_parameters use icepack_intfc, only: icepack_query_tracer_flags use icepack_intfc, only: icepack_query_tracer_sizes @@ -1301,27 +1301,24 @@ subroutine set_state_var (nx, & integer (kind=int_kind), intent(in) :: & nx ! number of grid cells - real (kind=dbl_kind), dimension (nx), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & Tair ! air temperature (K) ! ocean values may be redefined here, unlike in CICE - real (kind=dbl_kind), dimension (nx), intent(inout) :: & + real (kind=dbl_kind), dimension (:), intent(inout) :: & Tf , & ! freezing temperature (C) sst ! sea surface temperature (C) - real (kind=dbl_kind), dimension (nx,nilyr), & - intent(in) :: & + real (kind=dbl_kind), dimension (:,:), intent(in) :: & salinz , & ! initial salinity profile Tmltz ! initial melting temperature profile - real (kind=dbl_kind), dimension (nx,ncat), & - intent(out) :: & + real (kind=dbl_kind), dimension (:,:), intent(out) :: & aicen , & ! concentration of ice vicen , & ! volume per unit area of ice (m) vsnon ! volume per unit area of snow (m) - real (kind=dbl_kind), dimension (nx,max_ntrcr,ncat), & - intent(out) :: & + real (kind=dbl_kind), dimension (:,:,:), intent(out) :: & trcrn ! ice tracers ! 1: surface temperature of ice/snow (C) @@ -1431,7 +1428,7 @@ subroutine set_state_var (nx, & vicen(i,n) = hinit(n) * ainit(n) ! m vsnon(i,n) = c0 ! tracers - call icepack_init_trcr(Tair = Tair(i), & + call icepack_init_enthalpy(Tair = Tair(i), & Tf = Tf(i), & Sprofile = salinz(i,:), & Tprofile = Tmltz(i,:), & @@ -1502,7 +1499,7 @@ subroutine set_state_var (nx, & vicen(i,n) = hinit(n) * ainit(n) ! m vsnon(i,n) = min(aicen(i,n)*hsno_init,p2*vicen(i,n)) ! tracers - call icepack_init_trcr(Tair = Tair(i), & + call icepack_init_enthalpy(Tair = Tair(i), & Tf = Tf(i), & Sprofile = salinz(i,:), & Tprofile = Tmltz(i,:), & diff --git a/configuration/driver/icedrv_init_column.F90 b/configuration/driver/icedrv_init_column.F90 index ef2754b81..ce1d1bbd0 100644 --- a/configuration/driver/icedrv_init_column.F90 +++ b/configuration/driver/icedrv_init_column.F90 @@ -24,7 +24,7 @@ module icedrv_init_column use icepack_intfc, only: icepack_query_tracer_indices use icepack_intfc, only: icepack_query_parameters use icepack_intfc, only: icepack_init_zbgc - use icepack_intfc, only: icepack_init_thermo, icepack_init_radiation + use icepack_intfc, only: icepack_init_salinity, icepack_init_radiation use icepack_intfc, only: icepack_step_radiation, icepack_init_orbit use icepack_intfc, only: icepack_init_bgc use icepack_intfc, only: icepack_init_ocean_bio, icepack_load_ocean_bio_array @@ -69,7 +69,7 @@ subroutine init_thermo_vertical !----------------------------------------------------------------- call icepack_query_parameters(depressT_out=depressT) - call icepack_init_thermo(sprofile=sprofile) + call icepack_init_salinity(sprofile=sprofile) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & file=__FILE__, line=__LINE__) diff --git a/configuration/driver/icedrv_restart.F90 b/configuration/driver/icedrv_restart.F90 index 4cedb5073..c9b076677 100644 --- a/configuration/driver/icedrv_restart.F90 +++ b/configuration/driver/icedrv_restart.F90 @@ -13,7 +13,7 @@ module icedrv_restart use icedrv_restart_shared, only: restart_format use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted use icepack_intfc, only: icepack_query_tracer_flags, icepack_query_tracer_indices - use icepack_intfc, only: icepack_query_parameters + use icepack_intfc, only: icepack_query_parameters, icepack_query_tracer_sizes use icedrv_system, only: icedrv_system_abort #ifdef USE_NETCDF use netcdf @@ -261,7 +261,6 @@ subroutine restartfile (ice_ic) use icedrv_restart_shared, only: restart_format use icedrv_arrays_column, only: dhsn, ffracn, hin_max use icedrv_arrays_column, only: first_ice, first_ice_real - use icepack_tracers, only: ntrcr, nbtrcr character (*), optional :: ice_ic @@ -270,6 +269,9 @@ subroutine restartfile (ice_ic) integer (kind=int_kind) :: & i, k ! counting indices + integer (kind=int_kind) :: & + ntrcr + integer (kind=int_kind) :: & nt_Tsfc, nt_sice, nt_qice, nt_qsno @@ -287,7 +289,7 @@ subroutine restartfile (ice_ic) ! Query tracers call icepack_query_tracer_indices(nt_Tsfc_out=nt_Tsfc, nt_sice_out=nt_sice, & nt_qice_out=nt_qice, nt_qsno_out=nt_qsno) - + call icepack_query_tracer_sizes(ntrcr_out=ntrcr) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_aero_out=tr_aero, tr_iso_out=tr_iso, & tr_brine_out=tr_brine, & @@ -415,20 +417,20 @@ subroutine restartfile (ice_ic) do i = 1, nx if (tmask(i)) & - call icepack_aggregate (aicen=aicen(i,:), & - trcrn=trcrn(i,:,:), & - vicen=vicen(i,:), & - vsnon=vsnon(i,:), & - aice=aice (i), & - trcr=trcr (i,:), & - vice=vice (i), & - vsno=vsno (i), & - aice0=aice0(i), & - trcr_depend=trcr_depend, & - trcr_base=trcr_base, & - n_trcr_strata=n_trcr_strata, & - nt_strata=nt_strata, & - Tf = Tf(i)) + call icepack_aggregate(trcrn=trcrn(i,1:ntrcr,:), & + aicen=aicen(i,:), & + vicen=vicen(i,:), & + vsnon=vsnon(i,:), & + trcr=trcr (i,1:ntrcr), & + aice=aice (i), & + vice=vice (i), & + vsno=vsno (i), & + aice0=aice0(i), & + trcr_depend=trcr_depend(1:ntrcr), & + trcr_base=trcr_base (1:ntrcr,:), & + n_trcr_strata=n_trcr_strata(1:ntrcr), & + nt_strata=nt_strata (1:ntrcr,:), & + Tf = Tf(i)) aice_init(i) = aice(i) enddo diff --git a/configuration/driver/icedrv_state.F90 b/configuration/driver/icedrv_state.F90 index 1a9ca66f5..74ae11f7e 100644 --- a/configuration/driver/icedrv_state.F90 +++ b/configuration/driver/icedrv_state.F90 @@ -42,14 +42,12 @@ module icedrv_state ! state of the ice aggregated over all categories !----------------------------------------------------------------- - real (kind=dbl_kind), dimension(nx), & - public :: & + real (kind=dbl_kind), dimension(nx), public :: & aice , & ! concentration of ice vice , & ! volume per unit area of ice (m) vsno ! volume per unit area of snow (m) - real (kind=dbl_kind), & - dimension(nx,max_ntrcr), public :: & + real (kind=dbl_kind), dimension(nx,max_ntrcr), public :: & trcr ! ice tracers ! 1: surface temperature of ice/snow (C) @@ -57,18 +55,15 @@ module icedrv_state ! state of the ice for each category !----------------------------------------------------------------- - real (kind=dbl_kind), dimension (nx), & - public:: & + real (kind=dbl_kind), dimension (nx), public:: & aice0 ! concentration of open water - real (kind=dbl_kind), & - dimension (nx,ncat), public :: & + real (kind=dbl_kind), dimension (nx,ncat), public :: & aicen , & ! concentration of ice vicen , & ! volume per unit area of ice (m) vsnon ! volume per unit area of snow (m) - real (kind=dbl_kind), public, & - dimension (nx,max_ntrcr,ncat) :: & + real (kind=dbl_kind), dimension (nx,max_ntrcr,ncat), public :: & trcrn ! tracers ! 1: surface temperature of ice/snow (C) diff --git a/configuration/driver/icedrv_step.F90 b/configuration/driver/icedrv_step.F90 index 0c4538c4d..f99d47e4c 100644 --- a/configuration/driver/icedrv_step.F90 +++ b/configuration/driver/icedrv_step.F90 @@ -600,19 +600,21 @@ subroutine update_state (dt, daidt, dvidt, dagedt, offset) ! Aggregate the updated state variables (includes ghost cells). !----------------------------------------------------------------- - if (tmask(i)) then - call icepack_aggregate ( & - aicen=aicen(i,:), trcrn=trcrn(i,1:ntrcr,:), & - vicen=vicen(i,:), vsnon=vsnon(i,:), & - aice =aice (i), trcr =trcr (i,1:ntrcr), & - vice =vice (i), vsno =vsno (i), & - aice0=aice0(i), & - trcr_depend=trcr_depend (1:ntrcr), & - trcr_base=trcr_base (1:ntrcr,:), & - n_trcr_strata=n_trcr_strata(1:ntrcr), & - nt_strata=nt_strata (1:ntrcr,:), & - Tf=Tf(i)) - endif + if (tmask(i)) & + call icepack_aggregate(trcrn=trcrn(i,1:ntrcr,:), & + aicen=aicen(i,:), & + vicen=vicen(i,:), & + vsnon=vsnon(i,:), & + trcr=trcr (i,1:ntrcr), & + aice=aice (i), & + vice=vice (i), & + vsno=vsno (i), & + aice0=aice0(i), & + trcr_depend=trcr_depend(1:ntrcr), & + trcr_base=trcr_base (1:ntrcr,:), & + n_trcr_strata=n_trcr_strata(1:ntrcr), & + nt_strata=nt_strata (1:ntrcr,:), & + Tf = Tf(i)) if (present(offset)) then diff --git a/configuration/scripts/machines/Macros.derecho_cray b/configuration/scripts/machines/Macros.derecho_cray index 1ead7f5c8..1e95da90c 100644 --- a/configuration/scripts/machines/Macros.derecho_cray +++ b/configuration/scripts/machines/Macros.derecho_cray @@ -14,7 +14,8 @@ FFLAGS_NOOPT:= -O0 ifeq ($(ICE_BLDDEBUG), true) FFLAGS += -O0 -hfp0 -g -Rbcdps -Ktrap=fp else - FFLAGS += -O2 -hfp0 # -eo + # -Rp is needed to work around SAME_TBS compiler bug in cce/16, cce/17 + FFLAGS += -O2 -hfp0 -Rp # -eo endif SCC := cc diff --git a/doc/source/icepack_index.rst b/doc/source/icepack_index.rst index bd5e89214..712d1d891 100755 --- a/doc/source/icepack_index.rst +++ b/doc/source/icepack_index.rst @@ -249,7 +249,7 @@ section :ref:`tabnamelist`. "kappav", "visible extinction coefficient in ice, wavelength\ :math:`<`\ 700nm", "1.4 m\ :math:`^{-1}`" "kcatbound", ":math:`\bullet` category boundary formula", "" "kg_to_g", "kg to g conversion factor", "1000." - "kice", "thermal conductivity of fresh ice (:cite:`Bitz99`)", "2.03 W/m/deg" + "kice", "thermal conductivity of fresh ice with BL99+MU71 (:cite:`Bitz99`)", "2.03 W/m/deg" "kitd", ":math:`\bullet` type of itd conversions (0 = delta function, 1 = linear remap)", "1" "krdg_partic", ":math:`\bullet` ridging participation function", "1" "krdg_redist", ":math:`\bullet` ridging redistribution function", "1" diff --git a/doc/source/user_guide/interfaces.include b/doc/source/user_guide/interfaces.include index 44aebada4..a18385378 100644 --- a/doc/source/user_guide/interfaces.include +++ b/doc/source/user_guide/interfaces.include @@ -81,26 +81,22 @@ icepack_init_hbrine ! Initialize brine height tracer - subroutine icepack_init_hbrine(bgrid, igrid, cgrid, & - icgrid, swgrid, nblyr, nilyr, phi_snow) + subroutine icepack_init_hbrine(bgrid_out, igrid_out, cgrid_out, & + icgrid_out, swgrid_out, phi_snow) - integer (kind=int_kind), intent(in) :: & - nilyr, & ! number of ice layers - nblyr ! number of bio layers - - real (kind=dbl_kind), intent(inout) :: & + real (kind=dbl_kind), optional, intent(inout) :: & phi_snow ! porosity at the ice-snow interface - real (kind=dbl_kind), dimension (nblyr+2), intent(out) :: & - bgrid ! biology nondimensional vertical grid points + real (kind=dbl_kind), optional, dimension (:), intent(out) :: & + bgrid_out ! biology nondimensional vertical grid points - real (kind=dbl_kind), dimension (nblyr+1), intent(out) :: & - igrid ! biology vertical interface points + real (kind=dbl_kind), optional, dimension (:), intent(out) :: & + igrid_out ! biology vertical interface points - real (kind=dbl_kind), dimension (nilyr+1), intent(out) :: & - cgrid , & ! CICE vertical coordinate - icgrid , & ! interface grid for CICE (shortwave variable) - swgrid ! grid for ice tracers used in dEdd scheme + real (kind=dbl_kind), optional, dimension (:), intent(out) :: & + cgrid_out , & ! CICE vertical coordinate + icgrid_out , & ! interface grid for CICE (shortwave variable) + swgrid_out ! grid for ice tracers used in dEdd scheme @@ -113,14 +109,8 @@ icepack_init_zsalinity ! **DEPRECATED**, all code removed ! Interface provided for backwards compatibility - subroutine icepack_init_zsalinity(nblyr,ntrcr_o, Rayleigh_criteria, & - Rayleigh_real, trcrn_bgc, nt_bgc_S, ncat, sss) - - integer (kind=int_kind), intent(in) :: & - nblyr , & ! number of biolayers - ntrcr_o, & ! number of non bio tracers - ncat , & ! number of categories - nt_bgc_S ! zsalinity index + subroutine icepack_init_zsalinity(Rayleigh_criteria, & + Rayleigh_real, trcrn_bgc, sss) logical (kind=log_kind), intent(inout) :: & Rayleigh_criteria @@ -151,16 +141,13 @@ icepack_init_fsd_bounds ! ! authors: Lettie Roach, NIWA/VUW and C. M. Bitz, UW - subroutine icepack_init_fsd_bounds(nfsd, & + subroutine icepack_init_fsd_bounds( & floe_rad_l, & ! fsd size lower bound in m (radius) floe_rad_c, & ! fsd size bin centre in m (radius) floe_binwidth, & ! fsd size bin width in m (radius) c_fsd_range, & ! string for history output write_diags ) ! flag for writing diagnostics - integer (kind=int_kind), intent(in) :: & - nfsd ! number of floe size categories - real(kind=dbl_kind), dimension(:), intent(inout) :: & floe_rad_l, & ! fsd size lower bound in m (radius) floe_rad_c, & ! fsd size bin centre in m (radius) @@ -185,14 +172,11 @@ icepack_init_fsd ! ! authors: Lettie Roach, NIWA/VUW - subroutine icepack_init_fsd(nfsd, ice_ic, & + subroutine icepack_init_fsd(ice_ic, & floe_rad_c, & ! fsd size bin centre in m (radius) floe_binwidth, & ! fsd size bin width in m (radius) afsd) ! floe size distribution tracer - integer(kind=int_kind), intent(in) :: & - nfsd - character(len=char_len_long), intent(in) :: & ice_ic ! method of ice cover initialization @@ -216,11 +200,7 @@ icepack_cleanup_fsd ! ! authors: Elizabeth Hunke, LANL ! - subroutine icepack_cleanup_fsd (ncat, nfsd, afsdn) - - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nfsd ! number of floe size categories + subroutine icepack_cleanup_fsd (afsdn) real (kind=dbl_kind), dimension(:,:), intent(inout) :: & afsdn ! floe size distribution tracer @@ -326,9 +306,12 @@ icepack_intfc.F90 use icepack_therm_shared , only: icepack_snow_temperature use icepack_therm_shared , only: icepack_liquidus_temperature use icepack_therm_shared , only: icepack_sea_freezing_temperature - use icepack_therm_shared , only: icepack_init_thermo + use icepack_therm_shared , only: icepack_init_salinity use icepack_therm_shared , only: icepack_salinity_profile - use icepack_therm_shared , only: icepack_init_trcr + use icepack_therm_shared , only: icepack_init_enthalpy + ! for backwards compatibilty, remove in the future + use icepack_therm_shared , only: icepack_init_thermo => icepack_init_salinity + use icepack_therm_shared , only: icepack_init_trcr => icepack_init_enthalpy use icepack_mushy_physics , only: icepack_enthalpy_snow use icepack_mushy_physics , only: icepack_enthalpy_mush @@ -358,10 +341,7 @@ icepack_init_itd ! authors: William H. Lipscomb and Elizabeth C. Hunke, LANL ! C. M. Bitz, UW - subroutine icepack_init_itd(ncat, hin_max) - - integer (kind=int_kind), intent(in) :: & - ncat ! number of thickness categories + subroutine icepack_init_itd(hin_max) real (kind=dbl_kind), intent(out) :: & hin_max(0:ncat) ! category limits (m) @@ -379,10 +359,7 @@ icepack_init_itd_hist ! authors: William H. Lipscomb and Elizabeth C. Hunke, LANL ! C. M. Bitz, UW - subroutine icepack_init_itd_hist (ncat, hin_max, c_hi_range) - - integer (kind=int_kind), intent(in) :: & - ncat ! number of thickness categories + subroutine icepack_init_itd_hist (hin_max, c_hi_range) real (kind=dbl_kind), intent(in) :: & hin_max(0:ncat) ! category limits (m) @@ -403,22 +380,16 @@ icepack_aggregate ! authors: C. M. Bitz, UW ! W. H. Lipscomb, LANL - subroutine icepack_aggregate (ncat, & - aicen, trcrn, & + subroutine icepack_aggregate(aicen, trcrn, & vicen, vsnon, & aice, trcr, & vice, vsno, & aice0, & - ntrcr, & trcr_depend, & trcr_base, & n_trcr_strata, & nt_strata, Tf) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - ntrcr ! number of tracers in use - real (kind=dbl_kind), dimension (:), intent(in) :: & aicen , & ! concentration of ice vicen , & ! volume per unit area of ice (m) @@ -475,15 +446,11 @@ icepack_ice_strength ! authors: William H. Lipscomb, LANL ! Elizabeth C. Hunke, LANL - subroutine icepack_ice_strength (ncat, & - aice, vice, & + subroutine icepack_ice_strength(aice, vice, & aice0, aicen, & vicen, & strength) - integer (kind=int_kind), intent(in) :: & - ncat ! number of thickness categories - real (kind=dbl_kind), intent(in) :: & aice , & ! concentration of ice vice , & ! volume per unit area of ice (m) @@ -509,10 +476,8 @@ icepack_step_ridge ! authors: William H. Lipscomb, LANL ! Elizabeth C. Hunke, LANL - subroutine icepack_step_ridge (dt, ndtd, & - nilyr, nslyr, & - nblyr, & - ncat, hin_max, & + subroutine icepack_step_ridge(dt, ndtd, & + hin_max, & rdg_conv, rdg_shear, & aicen, & trcrn, & @@ -524,7 +489,6 @@ icepack_step_ridge dvirdgdt, opening, & fpond, & fresh, fhocn, & - n_aero, & faero_ocn, fiso_ocn, & aparticn, krdgn, & aredistn, vredistn, & @@ -542,12 +506,7 @@ icepack_step_ridge Tf ! freezing temperature integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - ndtd , & ! number of dynamics supercycles - nblyr , & ! number of bio layers - nilyr , & ! number of ice layers - nslyr , & ! number of snow layers - n_aero ! number of aerosol tracers + ndtd ! number of dynamics supercycles real (kind=dbl_kind), dimension(0:ncat), intent(inout) :: & hin_max ! category limits (m) @@ -853,7 +812,7 @@ icepack_init_parameters zref_in, hs_min_in, snowpatch_in, rhosi_in, sk_l_in, & saltmax_in, phi_init_in, min_salin_in, salt_loss_in, & Tliquidus_max_in, & - min_bgc_in, dSin0_frazil_in, hi_ssl_in, hs_ssl_in, & + min_bgc_in, dSin0_frazil_in, hi_ssl_in, hs_ssl_in, hs_ssl_min_in, & awtvdr_in, awtidr_in, awtvdf_in, awtidf_in, & qqqice_in, TTTice_in, qqqocn_in, TTTocn_in, & ktherm_in, conduct_in, fbot_xfer_type_in, calc_Tsfc_in, dts_b_in, & @@ -864,17 +823,18 @@ icepack_init_parameters phi_i_mushy_in, shortwave_in, albedo_type_in, albsnowi_in, & albicev_in, albicei_in, albsnowv_in, & ahmax_in, R_ice_in, R_pnd_in, R_snw_in, dT_mlt_in, rsnw_mlt_in, & - kalg_in, kstrength_in, krdg_partic_in, krdg_redist_in, mu_rdg_in, & + kalg_in, R_gC2molC_in, kstrength_in, krdg_partic_in, krdg_redist_in, mu_rdg_in, & atmbndy_in, calc_strair_in, formdrag_in, highfreq_in, natmiter_in, & atmiter_conv_in, calc_dragio_in, & tfrz_option_in, kitd_in, kcatbound_in, hs0_in, frzpnd_in, & - saltflux_option_in, & + saltflux_option_in, congel_freeze_in, & floeshape_in, wave_spec_in, wave_spec_type_in, nfreq_in, & dpscale_in, rfracmin_in, rfracmax_in, pndaspect_in, hs1_in, hp1_in, & 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, & + modal_aero_in, use_macromolecules_in, restartbgc_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, & - phi_snow_in, T_max_in, fsal_in, & + phi_snow_in, T_max_in, fsal_in, use_atm_dust_iron_in, & 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, & @@ -886,7 +846,38 @@ icepack_init_parameters 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, snw_ssp_table_in ) + snw_aging_table_in, snw_ssp_table_in, grid_o_t_in, tau_min_in, tau_max_in, & + f_don_protein_in, kn_bac_protein_in, f_don_Am_protein_in, & + ratio_Si2N_diatoms_in, & + ratio_Si2N_sp_in, ratio_Si2N_phaeo_in, ratio_S2N_diatoms_in, & + ratio_S2N_sp_in, ratio_S2N_phaeo_in, ratio_Fe2C_diatoms_in, & + ratio_Fe2C_sp_in, ratio_Fe2C_phaeo_in, ratio_Fe2N_diatoms_in, & + ratio_Fe2N_sp_in, ratio_Fe2N_phaeo_in, ratio_Fe2DON_in, & + ratio_Fe2DOC_s_in, ratio_Fe2DOC_l_in, & + chlabs_diatoms_in, chlabs_sp_in, chlabs_phaeo_in, alpha2max_low_diatoms_in, & + alpha2max_low_sp_in, alpha2max_low_phaeo_in, beta2max_diatoms_in, & + beta2max_sp_in, beta2max_phaeo_in, mu_max_diatoms_in, mu_max_sp_in, & + mu_max_phaeo_in, grow_Tdep_diatoms_in, grow_Tdep_sp_in, & + grow_Tdep_phaeo_in, fr_graze_diatoms_in, fr_graze_sp_in, & + fr_graze_phaeo_in, mort_pre_diatoms_in, mort_pre_sp_in, & + mort_pre_phaeo_in, mort_Tdep_diatoms_in, mort_Tdep_sp_in, & + mort_Tdep_phaeo_in, k_exude_diatoms_in, k_exude_sp_in, k_exude_phaeo_in, & + K_Nit_diatoms_in, K_Nit_sp_in, K_Nit_phaeo_in, & + K_Am_diatoms_in, K_Am_sp_in, K_Am_phaeo_in, & + K_Sil_diatoms_in, K_Sil_sp_in, K_Sil_phaeo_in, & + K_Fe_diatoms_in, K_Fe_sp_in, K_Fe_phaeo_in, & + f_doc_s_in, f_doc_l_in, f_exude_s_in, f_exude_l_in, & + k_bac_s_in, k_bac_l_in, algaltype_diatoms_in, & + algaltype_sp_in, algaltype_phaeo_in, nitratetype_in, & + ammoniumtype_in, silicatetype_in, dmspptype_in, & + dmspdtype_in, humtype_in, doctype_s_in, doctype_l_in, & + dictype_1_in, dontype_protein_in, fedtype_1_in, feptype_1_in, & + zaerotype_bc1_in, zaerotype_bc2_in, zaerotype_dust1_in, & + zaerotype_dust2_in, zaerotype_dust3_in, zaerotype_dust4_in, & + ratio_C2N_diatoms_in, ratio_C2N_sp_in, ratio_C2N_phaeo_in, & + ratio_chl2N_diatoms_in, ratio_chl2N_sp_in, ratio_chl2N_phaeo_in, & + F_abs_chl_diatoms_in, F_abs_chl_sp_in, F_abs_chl_phaeo_in, & + ratio_C2N_proteins_in ) !----------------------------------------------------------------- ! control settings @@ -978,15 +969,20 @@ icepack_init_parameters phi_i_mushy_in ! liquid fraction of congelation ice character(len=*), intent(in), optional :: & - tfrz_option_in ! form of ocean freezing temperature - ! 'minus1p8' = -1.8 C - ! 'linear_salt' = -depressT * sss - ! 'mushy' conforms with ktherm=2 + congel_freeze_in ! congelation computation + ! 'two-step' = original formulation + ! 'one-step' = Plante et al, The Cryosphere, 2024 character(len=*), intent(in), optional :: & - saltflux_option_in ! Salt flux computation - ! 'constant' reference value of ice_ref_salinity - ! 'prognostic' prognostic salt flux + tfrz_option_in ! form of ocean freezing temperature + ! 'minus1p8' = -1.8 C + ! 'linear_salt' = -depressT * sss + ! 'mushy' conforms with ktherm=2 + + character(len=*), intent(in), optional :: & + saltflux_option_in ! Salt flux computation + ! 'constant' reference value of ice_ref_salinity + ! 'prognostic' prognostic salt flux !----------------------------------------------------------------------- ! Parameters for radiation @@ -999,7 +995,8 @@ icepack_init_parameters stefan_boltzmann_in, & ! W/m^2/K^4 kappav_in, & ! vis extnctn coef in ice, wvlngth<700nm (1/m) hi_ssl_in, & ! ice surface scattering layer thickness (m) - hs_ssl_in, & ! visible, direct + hs_ssl_in, & ! snow surface scattering layer thickness (m) + hs_ssl_min_in, & ! minimum snow surface scattering layer thickness for aerosols (m) awtvdr_in, & ! visible, direct ! for history and awtidr_in, & ! near IR, direct ! diagnostics awtvdf_in, & ! visible, diffuse @@ -1026,7 +1023,8 @@ icepack_init_parameters dT_mlt_in , & ! change in temp for non-melt to melt snow grain ! radius change (C) rsnw_mlt_in , & ! maximum melting snow grain radius (10^-6 m) - kalg_in ! algae absorption coefficient for 0.5 m thick layer + kalg_in , & ! algae absorption coefficient for 0.5 m thick layer + R_gC2molC_in ! g carbon per mol logical (kind=log_kind), intent(in), optional :: & sw_redist_in ! redistribute shortwave @@ -1113,7 +1111,7 @@ icepack_init_parameters nfreq_in ! number of frequencies real (kind=dbl_kind), intent(in), optional :: & - floeshape_in ! constant from Steele (unitless) + floeshape_in ! constant from Rothrock 1984 (unitless) logical (kind=log_kind), intent(in), optional :: & wave_spec_in ! if true, use wave forcing @@ -1135,6 +1133,10 @@ icepack_init_parameters solve_zbgc_in, & ! if .true., solve vertical biochemistry portion of code dEdd_algae_in, & ! if .true., algal absorptionof Shortwave is computed in the modal_aero_in, & ! if .true., use modal aerosol formulation in shortwave + use_macromolecules_in, & ! if .true., ocean DOC is already split into + ! polysaccharid, lipid and protein fractions + use_atm_dust_iron_in, & ! if .true., compute iron contribution from dust + restartbgc_in, & conserv_check_in ! if .true., run conservation checks and abort if checks fail logical (kind=log_kind), intent(in), optional :: & @@ -1144,12 +1146,112 @@ icepack_init_parameters real (kind=dbl_kind), intent(in), optional :: & grid_o_in , & ! for bottom flux l_sk_in , & ! characteristic diffusive scale (zsalinity) (m) + grid_o_t_in , & ! top grid point length scale initbio_frac_in, & ! fraction of ocean tracer concentration used to initialize tracer phi_snow_in ! snow porosity at the ice/snow interface real (kind=dbl_kind), intent(in), optional :: & grid_oS_in , & ! for bottom flux (zsalinity) l_skS_in ! 0.02 characteristic skeletal layer thickness (m) (zsalinity) + + real (kind=dbl_kind), intent(in), optional :: & + ratio_Si2N_diatoms_in, & ! algal Si to N (mol/mol) + ratio_Si2N_sp_in , & + ratio_Si2N_phaeo_in , & + ratio_S2N_diatoms_in , & ! algal S to N (mol/mol) + ratio_S2N_sp_in , & + ratio_S2N_phaeo_in , & + ratio_Fe2C_diatoms_in, & ! algal Fe to C (umol/mol) + ratio_Fe2C_sp_in , & + ratio_Fe2C_phaeo_in , & + ratio_Fe2N_diatoms_in, & ! algal Fe to N (umol/mol) + ratio_Fe2N_sp_in , & + ratio_Fe2N_phaeo_in , & + ratio_Fe2DON_in , & ! Fe to N of DON (nmol/umol) + ratio_Fe2DOC_s_in , & ! Fe to C of DOC (nmol/umol) saccharids + ratio_Fe2DOC_l_in , & ! Fe to C of DOC (nmol/umol) lipids + tau_min_in , & ! rapid mobile to stationary exchanges (s) = 1.5 hours + tau_max_in , & ! long time mobile to stationary exchanges (s) = 2 days + chlabs_diatoms_in , & ! chl absorption (1/m/(mg/m^3)) + chlabs_sp_in , & ! + chlabs_phaeo_in , & ! + alpha2max_low_diatoms_in , & ! light limitation (1/(W/m^2)) + alpha2max_low_sp_in , & + alpha2max_low_phaeo_in , & + beta2max_diatoms_in , & ! light inhibition (1/(W/m^2)) + beta2max_sp_in , & + beta2max_phaeo_in , & + mu_max_diatoms_in , & ! maximum growth rate (1/day) + mu_max_sp_in , & + mu_max_phaeo_in , & + grow_Tdep_diatoms_in, & ! Temperature dependence of growth (1/C) + grow_Tdep_sp_in , & + grow_Tdep_phaeo_in , & + fr_graze_diatoms_in , & ! Fraction grazed + fr_graze_sp_in , & + fr_graze_phaeo_in , & + mort_pre_diatoms_in , & ! Mortality (1/day) + mort_pre_sp_in , & + mort_pre_phaeo_in , & + mort_Tdep_diatoms_in, & ! T dependence of mortality (1/C) + mort_Tdep_sp_in , & + mort_Tdep_phaeo_in , & + k_exude_diatoms_in , & ! algal exudation (1/d) + k_exude_sp_in , & + k_exude_phaeo_in , & + K_Nit_diatoms_in , & ! nitrate half saturation (mmol/m^3) + K_Nit_sp_in , & + K_Nit_phaeo_in , & + K_Am_diatoms_in , & ! ammonium half saturation (mmol/m^3) + K_Am_sp_in , & + K_Am_phaeo_in , & + K_Sil_diatoms_in , & ! silicate half saturation (mmol/m^3) + K_Sil_sp_in , & + K_Sil_phaeo_in , & + K_Fe_diatoms_in , & ! iron half saturation (nM) + K_Fe_sp_in , & + K_Fe_phaeo_in , & + f_don_protein_in , & ! fraction of spilled grazing to proteins + kn_bac_protein_in , & ! Bacterial degredation of DON (1/d) + f_don_Am_protein_in , & ! fraction of remineralized DON to ammonium + f_doc_s_in , & ! fraction of mortality to DOC + f_doc_l_in , & + f_exude_s_in , & ! fraction of exudation to DOC + f_exude_l_in , & + k_bac_s_in , & ! Bacterial degredation of DOC (1/d) + k_bac_l_in , & + algaltype_diatoms_in , & ! mobility type + algaltype_sp_in , & ! + algaltype_phaeo_in , & ! + nitratetype_in , & ! + ammoniumtype_in , & ! + silicatetype_in , & ! + dmspptype_in , & ! + dmspdtype_in , & ! + humtype_in , & ! + doctype_s_in , & ! + doctype_l_in , & ! + dictype_1_in , & ! + dontype_protein_in , & ! + fedtype_1_in , & ! + feptype_1_in , & ! + zaerotype_bc1_in , & ! + zaerotype_bc2_in , & ! + zaerotype_dust1_in , & ! + zaerotype_dust2_in , & ! + zaerotype_dust3_in , & ! + zaerotype_dust4_in , & ! + ratio_C2N_diatoms_in , & ! algal C to N ratio (mol/mol) + ratio_C2N_sp_in , & ! + ratio_C2N_phaeo_in , & ! + ratio_chl2N_diatoms_in, & ! algal chlorophyll to N ratio (mg/mmol) + ratio_chl2N_sp_in , & ! + ratio_chl2N_phaeo_in , & ! + F_abs_chl_diatoms_in , & ! scales absorbed radiation for dEdd + F_abs_chl_sp_in , & ! + F_abs_chl_phaeo_in , & ! + ratio_C2N_proteins_in ! ratio of C to N in proteins (mol/mol) + real (kind=dbl_kind), intent(in), optional :: & fr_resp_in , & ! fraction of algal growth lost due to respiration algal_vel_in , & ! 0.5 cm/d(m/s) Lavoie 2005 1.5 cm/day @@ -1269,7 +1371,7 @@ icepack_query_parameters zref_out, hs_min_out, snowpatch_out, rhosi_out, sk_l_out, & saltmax_out, phi_init_out, min_salin_out, salt_loss_out, & Tliquidus_max_out, & - min_bgc_out, dSin0_frazil_out, hi_ssl_out, hs_ssl_out, & + min_bgc_out, dSin0_frazil_out, hi_ssl_out, hs_ssl_out, hs_ssl_min_out, & awtvdr_out, awtidr_out, awtvdf_out, awtidf_out, cpl_frazil_out, & qqqice_out, TTTice_out, qqqocn_out, TTTocn_out, update_ocn_f_out, & Lfresh_out, cprho_out, Cp_out, ustar_min_out, hi_min_out, a_rapid_mode_out, & @@ -1279,15 +1381,16 @@ icepack_query_parameters albedo_type_out, albicev_out, albicei_out, albsnowv_out, & albsnowi_out, ahmax_out, R_ice_out, R_pnd_out, R_snw_out, dT_mlt_out, & rsnw_mlt_out, dEdd_algae_out, & - kalg_out, kstrength_out, krdg_partic_out, krdg_redist_out, mu_rdg_out, & + kalg_out, R_gC2molC_out, kstrength_out, krdg_partic_out, krdg_redist_out, mu_rdg_out, & atmbndy_out, calc_strair_out, formdrag_out, highfreq_out, natmiter_out, & atmiter_conv_out, calc_dragio_out, & tfrz_option_out, kitd_out, kcatbound_out, hs0_out, frzpnd_out, & - saltflux_option_out, & + saltflux_option_out, congel_freeze_out, & floeshape_out, wave_spec_out, wave_spec_type_out, nfreq_out, & dpscale_out, rfracmin_out, rfracmax_out, pndaspect_out, hs1_out, hp1_out, & 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, & + modal_aero_out, use_macromolecules_out, restartbgc_out, use_atm_dust_iron_out, & + skl_bgc_out, solve_zsal_out, grid_o_out, l_sk_out, & initbio_frac_out, grid_oS_out, l_skS_out, & phi_snow_out, conserv_check_out, & fr_resp_out, algal_vel_out, R_dFe2dust_out, dustFe_sol_out, & @@ -1301,7 +1404,37 @@ icepack_query_parameters 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, snw_ssp_table_out ) + snw_aging_table_out, snw_ssp_table_out, ratio_Si2N_diatoms_out, & + ratio_Si2N_sp_out, ratio_Si2N_phaeo_out, ratio_S2N_diatoms_out, & + ratio_S2N_sp_out, ratio_S2N_phaeo_out, ratio_Fe2C_diatoms_out, & + ratio_Fe2C_sp_out, ratio_Fe2C_phaeo_out, ratio_Fe2N_diatoms_out, & + ratio_Fe2N_sp_out, ratio_Fe2N_phaeo_out, ratio_Fe2DON_out, & + ratio_Fe2DOC_s_out, ratio_Fe2DOC_l_out, grid_o_t_out, tau_min_out, tau_max_out, & + chlabs_diatoms_out, chlabs_sp_out, chlabs_phaeo_out, alpha2max_low_diatoms_out, & + alpha2max_low_sp_out, alpha2max_low_phaeo_out, beta2max_diatoms_out, & + beta2max_sp_out, beta2max_phaeo_out, mu_max_diatoms_out, mu_max_sp_out, & + mu_max_phaeo_out, grow_Tdep_diatoms_out, grow_Tdep_sp_out, & + grow_Tdep_phaeo_out, fr_graze_diatoms_out, fr_graze_sp_out, & + fr_graze_phaeo_out, mort_pre_diatoms_out, mort_pre_sp_out, & + mort_pre_phaeo_out, mort_Tdep_diatoms_out, mort_Tdep_sp_out, & + mort_Tdep_phaeo_out, k_exude_diatoms_out, k_exude_sp_out, k_exude_phaeo_out, & + K_Nit_diatoms_out, K_Nit_sp_out, K_Nit_phaeo_out, & + K_Am_diatoms_out, K_Am_sp_out, K_Am_phaeo_out, & + K_Sil_diatoms_out, K_Sil_sp_out, K_Sil_phaeo_out, & + K_Fe_diatoms_out, K_Fe_sp_out, K_Fe_phaeo_out, & + f_don_protein_out, kn_bac_protein_out, f_don_Am_protein_out, & + f_doc_s_out, f_doc_l_out, f_exude_s_out, f_exude_l_out, & + k_bac_s_out, k_bac_l_out, algaltype_diatoms_out, & + algaltype_sp_out, algaltype_phaeo_out, nitratetype_out, & + ammoniumtype_out, silicatetype_out, dmspptype_out, & + dmspdtype_out, humtype_out, doctype_s_out, doctype_l_out, & + dictype_1_out, dontype_protein_out, fedtype_1_out, feptype_1_out, & + zaerotype_bc1_out, zaerotype_bc2_out, zaerotype_dust1_out, & + zaerotype_dust2_out, zaerotype_dust3_out, zaerotype_dust4_out, & + ratio_C2N_diatoms_out, ratio_C2N_sp_out, ratio_C2N_phaeo_out, & + ratio_chl2N_diatoms_out, ratio_chl2N_sp_out, ratio_chl2N_phaeo_out, & + F_abs_chl_diatoms_out, F_abs_chl_sp_out, F_abs_chl_phaeo_out, & + ratio_C2N_proteins_out ) !----------------------------------------------------------------- ! control settings @@ -1402,16 +1535,21 @@ icepack_query_parameters phi_i_mushy_out ! liquid fraction of congelation ice character(len=*), intent(out), optional :: & - tfrz_option_out ! form of ocean freezing temperature - ! 'minus1p8' = -1.8 C - ! 'constant' = Tocnfrz - ! 'linear_salt' = -depressT * sss - ! 'mushy' conforms with ktherm=2 + congel_freeze_out ! congelation computation + ! 'two-step' = original formulation + ! 'one-step' = Plante et al, The Cryosphere, 2024 + + character(len=*), intent(out), optional :: & + tfrz_option_out ! form of ocean freezing temperature + ! 'minus1p8' = -1.8 C + ! 'constant' = Tocnfrz + ! 'linear_salt' = -depressT * sss + ! 'mushy' conforms with ktherm=2 character(len=*), intent(out), optional :: & - saltflux_option_out ! Salt flux computation - ! 'constant' reference value of ice_ref_salinity - ! 'prognostic' prognostic salt flux + saltflux_option_out ! Salt flux computation + ! 'constant' reference value of ice_ref_salinity + ! 'prognostic' prognostic salt flux !----------------------------------------------------------------------- @@ -1425,7 +1563,8 @@ icepack_query_parameters stefan_boltzmann_out, & ! W/m^2/K^4 kappav_out, & ! vis extnctn coef in ice, wvlngth<700nm (1/m) hi_ssl_out, & ! ice surface scattering layer thickness (m) - hs_ssl_out, & ! visible, direct + hs_ssl_out, & ! snow surface scattering layer thickness (m) + hs_ssl_min_out, & ! minimum snow surface scattering layer thickness for aerosols (m) awtvdr_out, & ! visible, direct ! for history and awtidr_out, & ! near IR, direct ! diagnostics awtvdf_out, & ! visible, diffuse @@ -1452,7 +1591,8 @@ icepack_query_parameters dT_mlt_out , & ! change in temp for non-melt to melt snow grain ! radius change (C) rsnw_mlt_out , & ! maximum melting snow grain radius (10^-6 m) - kalg_out ! algae absorption coefficient for 0.5 m thick layer + kalg_out , & ! algae absorption coefficient for 0.5 m thick layer + R_gC2molC_out ! grams carbon per mol logical (kind=log_kind), intent(out), optional :: & sw_redist_out ! redistribute shortwave @@ -1539,7 +1679,7 @@ icepack_query_parameters nfreq_out ! number of frequencies real (kind=dbl_kind), intent(out), optional :: & - floeshape_out ! constant from Steele (unitless) + floeshape_out ! constant from Rothrock 1984 (unitless) logical (kind=log_kind), intent(out), optional :: & wave_spec_out ! if true, use wave forcing @@ -1561,6 +1701,10 @@ icepack_query_parameters solve_zbgc_out, & ! if .true., solve vertical biochemistry portion of code dEdd_algae_out, & ! if .true., algal absorptionof Shortwave is computed in the modal_aero_out, & ! if .true., use modal aerosol formulation in shortwave + use_macromolecules_out, & ! if .true., ocean DOC is already split + ! into polysaccharid, lipid and protein fractions + use_atm_dust_iron_out, & ! if .true., compute iron contribution from dust + restartbgc_out, & conserv_check_out ! if .true., run conservation checks and abort if checks fail logical (kind=log_kind), intent(out), optional :: & @@ -1570,12 +1714,112 @@ icepack_query_parameters real (kind=dbl_kind), intent(out), optional :: & grid_o_out , & ! for bottom flux l_sk_out , & ! characteristic diffusive scale (zsalinity) (m) + grid_o_t_out , & ! top grid point length scale initbio_frac_out, & ! fraction of ocean tracer concentration used to initialize tracer phi_snow_out ! snow porosity at the ice/snow interface real (kind=dbl_kind), intent(out), optional :: & grid_oS_out , & ! for bottom flux (zsalinity) l_skS_out ! 0.02 characteristic skeletal layer thickness (m) (zsalinity) + + real (kind=dbl_kind), intent(out), optional :: & + ratio_Si2N_diatoms_out, & ! algal Si to N (mol/mol) + ratio_Si2N_sp_out , & + ratio_Si2N_phaeo_out , & + ratio_S2N_diatoms_out , & ! algal S to N (mol/mol) + ratio_S2N_sp_out , & + ratio_S2N_phaeo_out , & + ratio_Fe2C_diatoms_out, & ! algal Fe to C (umol/mol) + ratio_Fe2C_sp_out , & + ratio_Fe2C_phaeo_out , & + ratio_Fe2N_diatoms_out, & ! algal Fe to N (umol/mol) + ratio_Fe2N_sp_out , & + ratio_Fe2N_phaeo_out , & + ratio_Fe2DON_out , & ! Fe to N of DON (nmol/umol) + ratio_Fe2DOC_s_out , & ! Fe to C of DOC (nmol/umol) saccharids + ratio_Fe2DOC_l_out , & ! Fe to C of DOC (nmol/umol) lipids + tau_min_out , & ! rapid mobile to stationary exchanges (s) = 1.5 hours + tau_max_out , & ! long time mobile to stationary exchanges (s) = 2 days + chlabs_diatoms_out , & ! chl absorption (1/m/(mg/m^3)) + chlabs_sp_out , & ! + chlabs_phaeo_out , & ! + alpha2max_low_diatoms_out , & ! light limitation (1/(W/m^2)) + alpha2max_low_sp_out , & + alpha2max_low_phaeo_out , & + beta2max_diatoms_out , & ! light inhibition (1/(W/m^2)) + beta2max_sp_out , & + beta2max_phaeo_out , & + mu_max_diatoms_out , & ! maximum growth rate (1/day) + mu_max_sp_out , & + mu_max_phaeo_out , & + grow_Tdep_diatoms_out, & ! Temperature dependence of growth (1/C) + grow_Tdep_sp_out , & + grow_Tdep_phaeo_out , & + fr_graze_diatoms_out , & ! Fraction grazed + fr_graze_sp_out , & + fr_graze_phaeo_out , & + mort_pre_diatoms_out , & ! Mortality (1/day) + mort_pre_sp_out , & + mort_pre_phaeo_out , & + mort_Tdep_diatoms_out, & ! T dependence of mortality (1/C) + mort_Tdep_sp_out , & + mort_Tdep_phaeo_out , & + k_exude_diatoms_out , & ! algal exudation (1/d) + k_exude_sp_out , & + k_exude_phaeo_out , & + K_Nit_diatoms_out , & ! nitrate half saturation (mmol/m^3) + K_Nit_sp_out , & + K_Nit_phaeo_out , & + K_Am_diatoms_out , & ! ammonium half saturation (mmol/m^3) + K_Am_sp_out , & + K_Am_phaeo_out , & + K_Sil_diatoms_out , & ! silicate half saturation (mmol/m^3) + K_Sil_sp_out , & + K_Sil_phaeo_out , & + K_Fe_diatoms_out , & ! iron half saturation (nM) + K_Fe_sp_out , & + K_Fe_phaeo_out , & + f_don_protein_out , & ! fraction of spilled grazing to proteins + kn_bac_protein_out , & ! Bacterial degredation of DON (1/d) + f_don_Am_protein_out , & ! fraction of remineralized DON to ammonium + f_doc_s_out , & ! fraction of mortality to DOC + f_doc_l_out , & + f_exude_s_out , & ! fraction of exudation to DOC + f_exude_l_out , & + k_bac_s_out , & ! Bacterial degredation of DOC (1/d) + k_bac_l_out , & + algaltype_diatoms_out , & ! mobility type + algaltype_sp_out , & ! + algaltype_phaeo_out , & ! + nitratetype_out , & ! + ammoniumtype_out , & ! + silicatetype_out , & ! + dmspptype_out , & ! + dmspdtype_out , & ! + humtype_out , & ! + doctype_s_out , & ! + doctype_l_out , & ! + dictype_1_out , & ! + dontype_protein_out , & ! + fedtype_1_out , & ! + feptype_1_out , & ! + zaerotype_bc1_out , & ! + zaerotype_bc2_out , & ! + zaerotype_dust1_out , & ! + zaerotype_dust2_out , & ! + zaerotype_dust3_out , & ! + zaerotype_dust4_out , & ! + ratio_C2N_diatoms_out , & ! algal C to N ratio (mol/mol) + ratio_C2N_sp_out , & ! + ratio_C2N_phaeo_out , & ! + ratio_chl2N_diatoms_out, & ! algal chlorophyll to N ratio (mg/mmol) + ratio_chl2N_sp_out , & ! + ratio_chl2N_phaeo_out , & ! + F_abs_chl_diatoms_out , & ! scales absorbed radiation for dEdd + F_abs_chl_sp_out , & ! + F_abs_chl_phaeo_out , & ! + ratio_C2N_proteins_out ! ratio of C to N in proteins (mol/mol) + real (kind=dbl_kind), intent(out), optional :: & fr_resp_out , & ! fraction of algal growth lost due to respiration algal_vel_out , & ! 0.5 cm/d(m/s) Lavoie 2005 1.5 cm/day @@ -1785,7 +2029,6 @@ icepack_step_radiation ! Elizabeth C. Hunke, LANL subroutine icepack_step_radiation (dt, & - swgrid, igrid, & fbri, & aicen, vicen, & vsnon, Tsfcn, & @@ -1847,12 +2090,6 @@ icepack_step_radiation real (kind=dbl_kind), intent(inout) :: & coszen ! cosine solar zenith angle, < 0 for sun below horizon - real (kind=dbl_kind), dimension (:), intent(in) :: & - igrid ! biology vertical interface points - - real (kind=dbl_kind), dimension (:), intent(in) :: & - swgrid ! grid for ice tracers used in dEdd scheme - real (kind=dbl_kind), dimension(:), intent(in) :: & aicen , & ! ice area fraction in each category vicen , & ! ice volume in each category (m) @@ -1940,8 +2177,7 @@ icepack_step_snow ! authors: Elizabeth C. Hunke, LANL ! Nicole Jeffery, LANL - subroutine icepack_step_snow(dt, nilyr, & - nslyr, ncat, & + subroutine icepack_step_snow(dt, & wind, aice, & aicen, vicen, & vsnon, Tsfc, & @@ -1953,11 +2189,6 @@ icepack_step_snow 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) @@ -2005,9 +2236,7 @@ icepack_step_therm2 ! authors: William H. Lipscomb, LANL ! Elizabeth C. Hunke, LANL - subroutine icepack_step_therm2 (dt, ncat, nltrcr, & - nilyr, nslyr, & - hin_max, nblyr, & + subroutine icepack_step_therm2(dt, hin_max, & aicen, & vicen, vsnon, & aicen_init, vicen_init, & @@ -2024,15 +2253,14 @@ icepack_step_therm2 frain, fpond, & fresh, fsalt, & fhocn, update_ocn_f, & - bgrid, cgrid, & - igrid, faero_ocn, & + faero_ocn, & first_ice, fzsal, & flux_bio, ocean_bio, & frazil_diag, & frz_onset, yday, & fiso_ocn, HDO_ocn, & H2_16O_ocn, H2_18O_ocn, & - nfsd, wave_sig_ht, & + wave_sig_ht, & wave_spectrum, & wavefreq, & dwavefreq, & @@ -2042,16 +2270,6 @@ icepack_step_therm2 use icepack_parameters, only: icepack_init_parameters - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nltrcr , & ! number of zbgc tracers - nblyr , & ! number of bio layers - nilyr , & ! number of ice layers - nslyr ! number of snow layers - - integer (kind=int_kind), intent(in), optional :: & - nfsd ! number of floe size categories - logical (kind=log_kind), intent(in), optional :: & update_ocn_f ! if true, update fresh water and salt fluxes @@ -2076,15 +2294,6 @@ icepack_step_therm2 integer (kind=int_kind), dimension (:,:), intent(in) :: & nt_strata ! indices of underlying tracer layers - real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: & - bgrid ! biology nondimensional vertical grid points - - real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: & - igrid ! biology vertical interface points - - real (kind=dbl_kind), dimension (nilyr+1), intent(in) :: & - cgrid ! CICE vertical coordinate - real (kind=dbl_kind), dimension(:), intent(in) :: & salinz , & ! initial salinity profile ocean_bio ! ocean concentration of biological tracer @@ -2164,21 +2373,19 @@ icepack_step_therm2 icepack_therm_shared.F90 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. _icepack_init_thermo: +.. _icepack_init_salinity: -icepack_init_thermo +icepack_init_salinity ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: fortran - ! Initialize the vertical profile of ice salinity and melting temperature. + ! Initialize the vertical profile of ice salinity. + ! This subroutine was renamed from icepack_init_thermo in Oct 2024 ! ! authors: C. M. Bitz, UW ! William H. Lipscomb, LANL - subroutine icepack_init_thermo(nilyr, sprofile) - - integer (kind=int_kind), intent(in) :: & - nilyr ! number of ice layers + subroutine icepack_init_salinity(sprofile) real (kind=dbl_kind), dimension(:), intent(out) :: & sprofile ! vertical salinity profile @@ -2206,23 +2413,19 @@ icepack_salinity_profile -.. _icepack_init_trcr: +.. _icepack_init_enthalpy: -icepack_init_trcr +icepack_init_enthalpy ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: fortran + ! This subroutine was renamed from icepack_init_trcr in Oct 2024 ! - subroutine icepack_init_trcr(Tair, Tf, & + subroutine icepack_init_enthalpy(Tair, Tf, & Sprofile, Tprofile, & Tsfc, & - nilyr, nslyr, & qin, qsn) - integer (kind=int_kind), intent(in) :: & - nilyr, & ! number of ice layers - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & Tair, & ! air temperature (K) Tf ! freezing temperature (C) @@ -2315,7 +2518,7 @@ icepack_step_therm1 ! authors: William H. Lipscomb, LANL ! Elizabeth C. Hunke, LANL - subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + subroutine icepack_step_therm1(dt, & aicen_init , & vicen_init , vsnon_init , & aice , aicen , & @@ -2404,11 +2607,6 @@ icepack_step_therm1 yday , prescribed_ice, & zlvs) - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nilyr , & ! number of ice layers - nslyr ! number of snow layers - real (kind=dbl_kind), intent(in) :: & dt , & ! time step uvel , & ! x-component of velocity (m/s) @@ -3027,15 +3225,12 @@ icepack_compute_tracers ! Compute tracer fields. ! Given atrcrn = aicen*trcrn (or vicen*trcrn, vsnon*trcrn), compute trcrn. - subroutine icepack_compute_tracers (ntrcr, trcr_depend, & + subroutine icepack_compute_tracers (trcr_depend, & atrcrn, aicen, & vicen, vsnon, & trcr_base, n_trcr_strata, & nt_strata, trcrn, Tf) - integer (kind=int_kind), intent(in) :: & - ntrcr ! number of tracers in use - integer (kind=int_kind), dimension (ntrcr), intent(in) :: & trcr_depend, & ! = 0 for aicen tracers, 1 for vicen, 2 for vsnon n_trcr_strata ! number of underlying tracer layers @@ -3177,8 +3372,7 @@ icepack_step_wavefracture ! authors: 2018 Lettie Roach, NIWA/VUW ! subroutine icepack_step_wavefracture(wave_spec_type, & - dt, ncat, nfsd, & - nfreq, & + dt, nfreq, & aice, vice, aicen, & floe_rad_l, floe_rad_c, & wave_spectrum, wavefreq, dwavefreq, & @@ -3186,12 +3380,10 @@ icepack_step_wavefracture character (len=char_len), intent(in) :: & - wave_spec_type ! type of wave spectrum forcing + wave_spec_type ! type of wave spectrum forcing integer (kind=int_kind), intent(in) :: & - nfreq, & ! number of wave frequency categories - ncat, & ! number of thickness categories - nfsd ! number of floe size categories + nfreq ! number of wave frequency categories real (kind=dbl_kind), intent(in) :: & dt, & ! time step @@ -3234,23 +3426,8 @@ icepack_init_bgc .. code-block:: fortran ! - subroutine icepack_init_bgc(ncat, nblyr, nilyr, ntrcr_o, & - cgrid, igrid, ntrcr, nbtrcr, & - sicen, trcrn, sss, ocean_bio_all) - - integer (kind=int_kind), intent(in) :: & - ncat , & ! number of thickness categories - nilyr , & ! number of ice layers - nblyr , & ! number of bio layers - ntrcr_o,& ! number of tracers not including bgc - ntrcr , & ! number of tracers in use - nbtrcr ! number of bio tracers in use - - real (kind=dbl_kind), dimension (nblyr+1), intent(inout) :: & - igrid ! biology vertical interface points - - real (kind=dbl_kind), dimension (nilyr+1), intent(inout) :: & - cgrid ! CICE vertical coordinate + subroutine icepack_init_bgc( & + sicen, trcrn, sss, ocean_bio_all, DOCPoolFractions) real (kind=dbl_kind), dimension(nilyr, ncat), intent(in) :: & sicen ! salinity on the cice grid @@ -3261,9 +3438,12 @@ icepack_init_bgc real (kind=dbl_kind), intent(in) :: & sss ! sea surface salinity (ppt) - real (kind=dbl_kind), dimension (:), intent(inout) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & ocean_bio_all ! fixed order, all values even for tracers false + real (kind=dbl_kind), dimension (:), optional, intent(out) :: & + DOCPoolFractions ! Fraction of DOC in polysacharids, lipids, and proteins + .. _icepack_init_zbgc: @@ -3274,76 +3454,14 @@ icepack_init_zbgc ! - subroutine icepack_init_zbgc ( & - R_Si2N_in, R_S2N_in, R_Fe2C_in, R_Fe2N_in, R_C2N_in, R_C2N_DON_in, & - R_chl2N_in, F_abs_chl_in, R_Fe2DON_in, R_Fe2DOC_in, chlabs_in, & - alpha2max_low_in, beta2max_in, mu_max_in, fr_graze_in, mort_pre_in, & - mort_Tdep_in, k_exude_in, K_Nit_in, K_Am_in, K_sil_in, K_Fe_in, & - f_don_in, kn_bac_in, f_don_Am_in, f_doc_in, f_exude_in, k_bac_in, & - grow_Tdep_in, zbgc_frac_init_in, & - zbgc_init_frac_in, tau_ret_in, tau_rel_in, bgc_tracer_type_in, & - fr_resp_in, algal_vel_in, R_dFe2dust_in, dustFe_sol_in, T_max_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, y_sk_DMS_in, t_sk_conv_in, t_sk_ox_in, fsal_in) - - real (kind=dbl_kind), optional :: R_C2N_in(:) ! algal C to N (mole/mole) - real (kind=dbl_kind), optional :: R_chl2N_in(:) ! 3 algal chlorophyll to N (mg/mmol) - real (kind=dbl_kind), optional :: F_abs_chl_in(:) ! to scale absorption in Dedd - real (kind=dbl_kind), optional :: R_C2N_DON_in(:) ! increase compare to algal R_Fe2C - real (kind=dbl_kind), optional :: R_Si2N_in(:) ! algal Sil to N (mole/mole) - real (kind=dbl_kind), optional :: R_S2N_in(:) ! algal S to N (mole/mole) - real (kind=dbl_kind), optional :: R_Fe2C_in(:) ! algal Fe to carbon (umol/mmol) - real (kind=dbl_kind), optional :: R_Fe2N_in(:) ! algal Fe to N (umol/mmol) - real (kind=dbl_kind), optional :: R_Fe2DON_in(:) ! Fe to N of DON (nmol/umol) - real (kind=dbl_kind), optional :: R_Fe2DOC_in(:) ! Fe to C of DOC (nmol/umol) - - real (kind=dbl_kind), optional :: fr_resp_in ! frac of algal growth lost due to respiration - real (kind=dbl_kind), optional :: algal_vel_in ! 0.5 cm/d(m/s) Lavoie 2005 1.5 cm/day - real (kind=dbl_kind), optional :: R_dFe2dust_in ! g/g (3.5% content) Tagliabue 2009 - real (kind=dbl_kind), optional :: dustFe_sol_in ! solubility fraction - real (kind=dbl_kind), optional :: T_max_in ! maximum temperature (C) - real (kind=dbl_kind), optional :: op_dep_min_in ! Light attenuates for optical depths exceeding min - real (kind=dbl_kind), optional :: fr_graze_s_in ! fraction of grazing spilled or slopped - real (kind=dbl_kind), optional :: fr_graze_e_in ! fraction of assimilation excreted - real (kind=dbl_kind), optional :: fr_mort2min_in ! fractionation of mortality to Am - real (kind=dbl_kind), optional :: fr_dFe_in ! fraction of remineralized nitrogen - ! (in units of algal iron) - real (kind=dbl_kind), optional :: k_nitrif_in ! nitrification rate (1/day) - real (kind=dbl_kind), optional :: t_iron_conv_in ! desorption loss pFe to dFe (day) - real (kind=dbl_kind), optional :: max_loss_in ! restrict uptake to % of remaining value - real (kind=dbl_kind), optional :: max_dfe_doc1_in ! max ratio of dFe to saccharides in the ice (nM Fe/muM C) - real (kind=dbl_kind), optional :: fr_resp_s_in ! DMSPd fraction of respiration loss as DMSPd - real (kind=dbl_kind), optional :: y_sk_DMS_in ! fraction conversion given high yield - real (kind=dbl_kind), optional :: t_sk_conv_in ! Stefels conversion time (d) - real (kind=dbl_kind), optional :: t_sk_ox_in ! DMS oxidation time (d) - real (kind=dbl_kind), optional :: fsal_in ! salinity limitation factor (1) - - real (kind=dbl_kind), optional :: chlabs_in(:) ! chla absorption 1/m/(mg/m^3) - real (kind=dbl_kind), optional :: alpha2max_low_in(:) ! light limitation (1/(W/m^2)) - real (kind=dbl_kind), optional :: beta2max_in(:) ! light inhibition (1/(W/m^2)) - real (kind=dbl_kind), optional :: mu_max_in(:) ! maximum growth rate (1/d) - real (kind=dbl_kind), optional :: grow_Tdep_in(:) ! T dependence of growth (1/C) - real (kind=dbl_kind), optional :: fr_graze_in(:) ! fraction of algae grazed - real (kind=dbl_kind), optional :: mort_pre_in(:) ! mortality (1/day) - real (kind=dbl_kind), optional :: mort_Tdep_in(:) ! T dependence of mortality (1/C) - real (kind=dbl_kind), optional :: k_exude_in(:) ! algal carbon exudation rate (1/d) - real (kind=dbl_kind), optional :: K_Nit_in(:) ! nitrate half saturation (mmol/m^3) - real (kind=dbl_kind), optional :: K_Am_in(:) ! ammonium half saturation (mmol/m^3) - real (kind=dbl_kind), optional :: K_Sil_in(:) ! silicon half saturation (mmol/m^3) - real (kind=dbl_kind), optional :: K_Fe_in(:) ! iron half saturation or micromol/m^3 - real (kind=dbl_kind), optional :: f_don_in(:) ! fraction of spilled grazing to DON - real (kind=dbl_kind), optional :: kn_bac_in(:) ! Bacterial degredation of DON (1/d) - real (kind=dbl_kind), optional :: f_don_Am_in(:) ! fraction of remineralized DON to Am - real (kind=dbl_kind), optional :: f_doc_in(:) ! fraction of mort_N that goes to each doc pool - real (kind=dbl_kind), optional :: f_exude_in(:) ! fraction of exuded carbon to each DOC pool - real (kind=dbl_kind), optional :: k_bac_in(:) ! Bacterial degredation of DOC (1/d) - - real (kind=dbl_kind), optional :: zbgc_frac_init_in(:) ! initializes mobile fraction - real (kind=dbl_kind), optional :: bgc_tracer_type_in(:) ! described tracer in mobile or stationary phases - real (kind=dbl_kind), optional :: zbgc_init_frac_in(:) ! fraction of ocean tracer concentration in new ice - real (kind=dbl_kind), optional :: tau_ret_in(:) ! retention timescale (s), mobile to stationary phase - real (kind=dbl_kind), optional :: tau_rel_in(:) ! release timescale (s), stationary to mobile phase + subroutine icepack_init_zbgc (& + zbgc_frac_init_in, zbgc_init_frac_in, tau_ret_in, tau_rel_in, bgc_tracer_type_in) + + real (kind=dbl_kind), dimension (:), intent(in), optional :: zbgc_frac_init_in(:) ! initializes mobile fraction + real (kind=dbl_kind), dimension (:), intent(in), optional :: bgc_tracer_type_in(:) ! described tracer in mobile or stationary phases + real (kind=dbl_kind), dimension (:), intent(in), optional :: zbgc_init_frac_in(:) ! fraction of ocean tracer concentration in new ice + real (kind=dbl_kind), dimension (:), intent(in), optional :: tau_ret_in(:) ! retention timescale (s), mobile to stationary phase + real (kind=dbl_kind), dimension (:), intent(in), optional :: tau_rel_in(:) ! release timescale (s), stationary to mobile phase @@ -3354,54 +3472,40 @@ icepack_biogeochemistry .. code-block:: fortran ! - subroutine icepack_biogeochemistry(dt, & - ntrcr, nbtrcr, & upNO, upNH, iDi, iki, zfswin, & - zsal_tot, darcy_V, grow_net, & + darcy_V, grow_net, & PP_net, hbri,dhbr_bot, dhbr_top, Zoo,& - fbio_snoice, fbio_atmice, ocean_bio, & + fbio_snoice, fbio_atmice, ocean_bio_dh, ocean_bio, & first_ice, fswpenln, bphi, bTiz, ice_bio_net, & - snow_bio_net, fswthrun, Rayleigh_criteria, & - sice_rho, fzsal, fzsal_g, & - bgrid, igrid, icgrid, cgrid, & - nblyr, nilyr, nslyr, n_algae, n_zaero, ncat, & - n_doc, n_dic, n_don, n_fed, n_fep, & + snow_bio_net, totalChla, fswthrun, & meltbn, melttn, congeln, snoicen, & - sst, sss, fsnow, meltsn, & + sst, sss, Tf, fsnow, meltsn, & !hmix, & hin_old, flux_bio, flux_bio_atm, & aicen_init, vicen_init, aicen, vicen, vsnon, & - aice0, trcrn, vsnon_init, skl_bgc) + aice0, trcrn, vsnon_init, & + flux_bion, bioPorosityIceCell, & + bioSalinityIceCell, bioTemperatureIceCell) real (kind=dbl_kind), intent(in) :: & dt ! time step - integer (kind=int_kind), intent(in) :: & - ncat, & - nilyr, & - nslyr, & - nblyr, & - ntrcr, & - nbtrcr, & - n_algae, n_zaero, & - n_doc, n_dic, n_don, n_fed, n_fep - real (kind=dbl_kind), dimension (:), intent(inout) :: & - bgrid , & ! biology nondimensional vertical grid points - igrid , & ! biology vertical interface points - cgrid , & ! CICE vertical coordinate - icgrid , & ! interface grid for CICE (shortwave variable) - ocean_bio , & ! contains all the ocean bgc tracer concentrations fbio_snoice , & ! fluxes from snow to ice fbio_atmice , & ! fluxes from atm to ice dhbr_top , & ! brine top change dhbr_bot , & ! brine bottom change darcy_V , & ! darcy velocity positive up (m/s) hin_old , & ! old ice thickness - sice_rho , & ! avg sea ice density (kg/m^3) ice_bio_net , & ! depth integrated tracer (mmol/m^2) snow_bio_net , & ! depth integrated snow tracer (mmol/m^2) - flux_bio ! all bio fluxes to ocean + flux_bio ! all bio fluxes to ocean + + real (kind=dbl_kind), dimension (:), intent(in) :: & + ocean_bio ! contains the ocean bgc tracer concentrations in use (mmol/m^3) + + real (kind=dbl_kind), optional, dimension (:), intent(out) :: & + ocean_bio_dh ! The ocean bgc tracer concentrations in use * brine thickness * phi (mmol/m^2) logical (kind=log_kind), dimension (:), intent(inout) :: & first_ice ! distinguishes ice that disappears (e.g. melts) @@ -3409,6 +3513,14 @@ icepack_biogeochemistry ! during a single time step from ice that was ! there the entire time step (true until ice forms) + real (kind=dbl_kind), optional, dimension (:,:), intent(out) :: & + flux_bion ! per categeory ice to ocean biogeochemistry flux (mmol/m2/s) + + real (kind=dbl_kind), optional, dimension (:), intent(inout) :: & + bioPorosityIceCell, & ! category average porosity on the interface bio grid + bioSalinityIceCell, & ! (ppt) category average porosity on the interface bio grid + bioTemperatureIceCell ! (oC) category average porosity on the interface bio grid + real (kind=dbl_kind), dimension (:,:), intent(inout) :: & Zoo , & ! N losses accumulated in timestep (ie. zooplankton/bacteria) ! mmol/m^3 @@ -3426,15 +3538,8 @@ icepack_biogeochemistry upNO , & ! nitrate uptake rate (mmol/m^2/d) times aice upNH ! ammonium uptake rate (mmol/m^2/d) times aice - real (kind=dbl_kind), intent(inout), optional :: & - zsal_tot ! Total ice salinity in per grid cell (g/m^2) (deprecated) - - real (kind=dbl_kind), intent(inout), optional :: & - fzsal , & ! Total flux of salt to ocean at time step for conservation (deprecated) - fzsal_g ! Total gravity drainage flux (deprecated) - - logical (kind=log_kind), intent(inout), optional :: & - Rayleigh_criteria ! .true. means Ra_c was reached (deprecated) + real (kind=dbl_kind), optional, intent(inout) :: & + totalChla ! ice integrated chla and summed over all algal groups (mg/m^2) real (kind=dbl_kind), dimension (:,:), intent(in) :: & fswpenln ! visible SW entering ice layers (W m-2) @@ -3458,11 +3563,10 @@ icepack_biogeochemistry aice0 , & ! open water area fraction sss , & ! sea surface salinity (ppt) sst , & ! sea surface temperature (C) + !hmix , & ! mixed layer depth (m) + Tf , & ! basal freezing temperature (C) fsnow ! snowfall rate (kg/m^2 s) - logical (kind=log_kind), intent(in) :: & - skl_bgc ! if true, solve skeletal biochemistry - .. _icepack_load_ocean_bio_array: @@ -3473,20 +3577,10 @@ icepack_load_ocean_bio_array ! basic initialization for ocean_bio_all - subroutine icepack_load_ocean_bio_array(max_nbtrcr, & - max_algae, max_don, max_doc, max_dic, max_aero, max_fe, & + subroutine icepack_load_ocean_bio_array(& nit, amm, sil, dmsp, dms, algalN, & doc, don, dic, fed, fep, zaeros, ocean_bio_all, hum) - integer (kind=int_kind), intent(in) :: & - max_algae , & ! maximum number of algal types - max_dic , & ! maximum number of dissolved inorganic carbon types - max_doc , & ! maximum number of dissolved organic carbon types - max_don , & ! maximum number of dissolved organic nitrogen types - max_fe , & ! maximum number of iron types - max_aero , & ! maximum number of aerosols - max_nbtrcr ! maximum number of bio tracers - real (kind=dbl_kind), intent(in) :: & nit , & ! ocean nitrate (mmol/m^3) amm , & ! ammonia/um (mmol/m^3) @@ -3495,25 +3589,25 @@ icepack_load_ocean_bio_array dms , & ! dms (mmol/m^3) hum ! humic material (mmol/m^3) - real (kind=dbl_kind), dimension (max_algae), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & algalN ! ocean algal nitrogen (mmol/m^3) (diatoms, phaeo, pico) - real (kind=dbl_kind), dimension (max_doc), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & doc ! ocean doc (mmol/m^3) (proteins, EPS, lipid) - real (kind=dbl_kind), dimension (max_don), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & don ! ocean don (mmol/m^3) - real (kind=dbl_kind), dimension (max_dic), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & dic ! ocean dic (mmol/m^3) - real (kind=dbl_kind), dimension (max_fe), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & fed, fep ! ocean disolved and particulate fe (nM) - real (kind=dbl_kind), dimension (max_aero), intent(in) :: & + real (kind=dbl_kind), dimension (:), intent(in) :: & zaeros ! ocean aerosols (mmol/m^3) - real (kind=dbl_kind), dimension (max_nbtrcr), intent(inout) :: & + real (kind=dbl_kind), dimension (:), intent(out) :: & ocean_bio_all ! fixed order, all values even for tracers false @@ -3527,16 +3621,9 @@ icepack_init_ocean_bio ! Initialize ocean concentration subroutine icepack_init_ocean_bio (amm, dmsp, dms, algalN, doc, dic, don, & - fed, fep, hum, nit, sil, zaeros, max_dic, max_don, max_fe, max_aero,& - CToN, CToN_DON) - - integer (kind=int_kind), intent(in) :: & - max_dic, & - max_don, & - max_fe, & - max_aero + fed, fep, hum, nit, sil, zaeros,CToN, CToN_DON) - real (kind=dbl_kind), intent(out):: & + real (kind=dbl_kind), intent(out), optional:: & amm , & ! ammonium dmsp , & ! DMSPp dms , & ! DMS @@ -3544,7 +3631,7 @@ icepack_init_ocean_bio nit , & ! nitrate sil ! silicate - real (kind=dbl_kind), dimension(:), intent(out):: & + real (kind=dbl_kind), dimension(:), intent(out), optional:: & algalN , & ! algae doc , & ! DOC dic , & ! DIC @@ -3553,7 +3640,7 @@ icepack_init_ocean_bio fep , & ! Particulate Iron zaeros ! BC and dust - real (kind=dbl_kind), dimension(:), intent(inout), optional :: & + real (kind=dbl_kind), dimension(:), intent(out), optional :: & CToN , & ! carbon to nitrogen ratio for algae CToN_DON ! nitrogen to carbon ratio for proteins From 6da5668281568d61cd6a936bf3a97d2cedbfa772 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Thu, 24 Oct 2024 12:07:17 -0700 Subject: [PATCH 27/30] Add dorebin and docleanup optional arguments to icepack_step_ridge (#503) Add dorebin and docleanup optional arguments to icepack_step_ridge to support NOT calling cleanup_itd and NOT calling rebin in the ridge_ice. Closes #478 Rename limit_aice_in argument in ridge_ice to limit_aice. This argument is not used in Icepack or CICE at the moment. Update interface document Based on https://github.com/ESMG/Icepack/tree/optional_cleanup --- columnphysics/icepack_itd.F90 | 39 +++++++++++++++--------- columnphysics/icepack_mechred.F90 | 34 ++++++++++++++++++--- doc/source/user_guide/interfaces.include | 8 ++++- 3 files changed, 60 insertions(+), 21 deletions(-) diff --git a/columnphysics/icepack_itd.F90 b/columnphysics/icepack_itd.F90 index 1870ec4ad..013373ad8 100644 --- a/columnphysics/icepack_itd.F90 +++ b/columnphysics/icepack_itd.F90 @@ -738,8 +738,8 @@ end subroutine column_conservation_check !======================================================================= ! Cleanup subroutine that rebins thickness categories if necessary, -! eliminates very small ice areas while conserving mass and energy, -! aggregates state variables, and does a boundary call. +! eliminates very small ice areas while conserving mass and energy +! and aggregates state variables. ! It is a good idea to call this subroutine after the thermodynamics ! (thermo_vertical/thermo_itd) and again after the dynamics ! (evp/transport/ridging). @@ -758,7 +758,8 @@ subroutine cleanup_itd (dt, hin_max, & fpond, fresh, & fsalt, fhocn, & faero_ocn, fiso_ocn, & - flux_bio, Tf, limit_aice_in) + flux_bio, Tf, & + limit_aice, dorebin) real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -817,8 +818,9 @@ subroutine cleanup_itd (dt, hin_max, & fiso_ocn ! isotope flux to ocean (kg/m^2/s) logical (kind=log_kind), intent(in), optional :: & - limit_aice_in ! if false, allow aice to be out of bounds - ! may want to allow this for unit tests + dorebin, & ! if false, do not call rebin (default true) + limit_aice ! if false, allow aice to be out of bounds + ! may want to allow this for unit tests (default true) ! local variables @@ -842,7 +844,8 @@ subroutine cleanup_itd (dt, hin_max, & dflux_bio ! zapped biology flux (mmol/m^2/s) logical (kind=log_kind) :: & - limit_aice ! if true, check for aice out of bounds + ldorebin , & ! if true, call rebin + llimit_aice ! if true, check for aice out of bounds character(len=*),parameter :: subname='(cleanup_itd)' @@ -850,10 +853,16 @@ subroutine cleanup_itd (dt, hin_max, & ! Initialize !----------------------------------------------------------------- - if (present(limit_aice_in)) then - limit_aice = limit_aice_in + if (present(limit_aice)) then + llimit_aice = limit_aice else - limit_aice = .true. + llimit_aice = .true. + endif + + if (present(dorebin)) then + ldorebin = dorebin + else + ldorebin = .true. endif dfpond = c0 @@ -871,7 +880,7 @@ subroutine cleanup_itd (dt, hin_max, & call aggregate_area (aicen, aice, aice0) if (icepack_warnings_aborted(subname)) return - if (limit_aice) then ! check for aice out of bounds + if (llimit_aice) then ! check for aice out of bounds if (aice > c1+puny .or. aice < -puny) then call icepack_warnings_setabort(.true.,__FILE__,__LINE__) call icepack_warnings_add(subname//' aggregate ice area out of bounds') @@ -883,13 +892,13 @@ subroutine cleanup_itd (dt, hin_max, & enddo return endif - endif ! limit_aice + endif ! llimit_aice !----------------------------------------------------------------- ! Identify grid cells with ice. !----------------------------------------------------------------- - if (aice > puny) then + if (ldorebin .and. aice > puny) then !----------------------------------------------------------------- ! Make sure ice in each category is within its thickness bounds. @@ -898,7 +907,7 @@ subroutine cleanup_itd (dt, hin_max, & ! correctly (e.g., very fast ice growth). !----------------------------------------------------------------- - call rebin (trcr_depend, & + call rebin (trcr_depend, & trcr_base, & n_trcr_strata, & nt_strata, & @@ -913,7 +922,7 @@ subroutine cleanup_itd (dt, hin_max, & ! Zero out ice categories with very small areas. !----------------------------------------------------------------- - if (limit_aice) then + if (llimit_aice) then call zap_small_areas (dt, & aice, aice0, & aicen, trcrn, & @@ -937,7 +946,7 @@ subroutine cleanup_itd (dt, hin_max, & return endif - endif ! l_limit_aice + endif ! llimit_aice !------------------------------------------------------------------- ! Zap snow that has out of bounds temperatures diff --git a/columnphysics/icepack_mechred.F90 b/columnphysics/icepack_mechred.F90 index 6205b581a..70766cc60 100644 --- a/columnphysics/icepack_mechred.F90 +++ b/columnphysics/icepack_mechred.F90 @@ -1740,7 +1740,9 @@ subroutine icepack_step_ridge(dt, ndtd, & araftn, vraftn, & aice, fsalt, & first_ice, fzsal, & - flux_bio, closing, Tf ) + flux_bio, closing, & + Tf, & + docleanup, dorebin) real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -1815,6 +1817,10 @@ subroutine icepack_step_ridge(dt, ndtd, & logical (kind=log_kind), dimension(:), intent(inout) :: & first_ice ! true until ice forms + logical (kind=log_kind), intent(in), optional :: & + docleanup, & ! if false, do not call cleanup_itd (default true) + dorebin ! if false, do not call rebin in cleanup_itd (default true) + !autodocument_end ! local variables @@ -1822,6 +1828,10 @@ subroutine icepack_step_ridge(dt, ndtd, & real (kind=dbl_kind) :: & dtt ! thermo time step + logical (kind=log_kind) :: & + ldocleanup, &! if true, call cleanup_itd + ldorebin ! if true, call rebin in cleanup_itd + logical (kind=log_kind), save :: & first_call = .true. ! first call flag @@ -1841,6 +1851,17 @@ subroutine icepack_step_ridge(dt, ndtd, & endif endif + if (present(docleanup)) then + ldocleanup = docleanup + else + ldocleanup = .true. + endif + + if (present(dorebin)) then + ldorebin = dorebin + else + ldorebin = .true. + endif !----------------------------------------------------------------- ! Identify ice-ocean cells. @@ -1880,8 +1901,9 @@ subroutine icepack_step_ridge(dt, ndtd, & ! categories with very small areas. !----------------------------------------------------------------- - dtt = dt * ndtd ! for proper averaging over thermo timestep - call cleanup_itd (dtt, hin_max, & + if (ldocleanup) then + dtt = dt * ndtd ! for proper averaging over thermo timestep + call cleanup_itd(dtt, hin_max, & aicen, trcrn, & vicen, vsnon, & aice0, aice, & @@ -1893,8 +1915,10 @@ subroutine icepack_step_ridge(dt, ndtd, & fpond, fresh, & fsalt, fhocn, & faero_ocn, fiso_ocn, & - flux_bio, Tf) - if (icepack_warnings_aborted(subname)) return + flux_bio, Tf, & + dorebin = ldorebin) + if (icepack_warnings_aborted(subname)) return + endif first_call = .false. diff --git a/doc/source/user_guide/interfaces.include b/doc/source/user_guide/interfaces.include index a18385378..ae640d1bf 100644 --- a/doc/source/user_guide/interfaces.include +++ b/doc/source/user_guide/interfaces.include @@ -497,7 +497,9 @@ icepack_step_ridge araftn, vraftn, & aice, fsalt, & first_ice, fzsal, & - flux_bio, closing, Tf ) + flux_bio, closing, & + Tf, & + docleanup, dorebin) real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -572,6 +574,10 @@ icepack_step_ridge logical (kind=log_kind), dimension(:), intent(inout) :: & first_ice ! true until ice forms + logical (kind=log_kind), intent(in), optional :: & + docleanup, & ! if false, do not call cleanup_itd (default true) + dorebin ! if false, do not call rebin in cleanup_itd (default true) + icepack_mushy_physics.F90 From 286630fdecc8efc4dcf4bd7ecf2315101c69c391 Mon Sep 17 00:00:00 2001 From: "David A. Bailey" Date: Wed, 30 Oct 2024 18:29:04 -0600 Subject: [PATCH 28/30] FSD fixes for conservation (#495) This is a bug fix plus some rearranging for conservation in CICE. This impacts FSD cases as well as non-FSD cases. There are two main aspects to the bug fix: Initial ice and snow volume values at the beginning of the lateral melt routine are now used for updating the snow and ice enthalpy as well other tracers for lateral melting. This is answer changing in all cases! The other fix is to move the computation of vi0new_lat (lateral growth from FSD) outside of the subroutine fsd_lateral_growth and a check to make sure the category vi0new (vin0new) does not exceed the total vi0new. This is a warning and it recomputes to ensure conservation. This is only answer changing in FSD cases. There is also a change in definition of floe_area_c, so that it is precisely half way between floe_area_l and floe_area_h. The original computation of floe_area_c based on floe_rad_c biases the area towards the lower value. Update the fsd subroutine arguments (floe_rad_c, floe_rad_l, floe_binwidth, c_fsd_range) to store static data inside Icepack when computed in Icepack rather than pass them back and forth. Provide an ability to pass out the values from Icepack as optional arguments. Move the computation of rsiden and get rid of fside which is no longer needed. Clean up some comments and indentation Update swccsm3 test, set ktherm=1 Update interface documentation There is an associated CICE tag to go with this. --- columnphysics/icepack_fsd.F90 | 140 +++--- columnphysics/icepack_therm_itd.F90 | 434 +++++++----------- columnphysics/icepack_therm_vertical.F90 | 122 ++++- columnphysics/icepack_wavefracspec.F90 | 19 +- configuration/driver/icedrv_InitMod.F90 | 13 +- configuration/driver/icedrv_arrays_column.F90 | 17 +- configuration/driver/icedrv_flux.F90 | 3 +- configuration/driver/icedrv_forcing.F90 | 1 + configuration/driver/icedrv_init.F90 | 5 - configuration/driver/icedrv_step.F90 | 34 +- configuration/scripts/options/set_nml.swccsm3 | 1 + doc/source/user_guide/interfaces.include | 66 +-- 12 files changed, 408 insertions(+), 447 deletions(-) diff --git a/columnphysics/icepack_fsd.F90 b/columnphysics/icepack_fsd.F90 index 28f12d922..2e5175afa 100644 --- a/columnphysics/icepack_fsd.F90 +++ b/columnphysics/icepack_fsd.F90 @@ -55,13 +55,19 @@ module icepack_fsd public :: icepack_init_fsd_bounds, icepack_init_fsd, icepack_cleanup_fsd, & fsd_lateral_growth, fsd_add_new_ice, fsd_weld_thermo, get_subdt_fsd - real(kind=dbl_kind), dimension(:), allocatable :: & + real(kind=dbl_kind), dimension(:), allocatable, public :: & floe_rad_h, & ! fsd size higher bound in m (radius) + floe_rad_c, & ! fsd size center in m (radius) + floe_rad_l, & ! fsd size lower bound in m (radius) + floe_binwidth, & ! fsd size binwidth in m (radius) floe_area_l, & ! fsd area at lower bound (m^2) floe_area_h, & ! fsd area at higher bound (m^2) floe_area_c, & ! fsd area at bin centre (m^2) floe_area_binwidth ! floe area bin width (m^2) + character (len=35), dimension(:), allocatable, public :: & + c_fsd_range ! string for history output + integer(kind=int_kind), dimension(:,:), allocatable, public :: & iweld ! floe size categories that can combine ! during welding (dimensionless) @@ -85,22 +91,22 @@ module icepack_fsd ! authors: Lettie Roach, NIWA/VUW and C. M. Bitz, UW subroutine icepack_init_fsd_bounds( & - floe_rad_l, & ! fsd size lower bound in m (radius) - floe_rad_c, & ! fsd size bin centre in m (radius) - floe_binwidth, & ! fsd size bin width in m (radius) - c_fsd_range, & ! string for history output - write_diags ) ! flag for writing diagnostics + floe_rad_l_out, & ! fsd size lower bound in m (radius) + floe_rad_c_out, & ! fsd size bin centre in m (radius) + floe_binwidth_out, & ! fsd size bin width in m (radius) + c_fsd_range_out, & ! string for history output + write_diags) ! flag for writing diagnostics - real(kind=dbl_kind), dimension(:), intent(inout) :: & - floe_rad_l, & ! fsd size lower bound in m (radius) - floe_rad_c, & ! fsd size bin centre in m (radius) - floe_binwidth ! fsd size bin width in m (radius) + real(kind=dbl_kind), dimension(:), intent(out), optional :: & + floe_rad_l_out, & ! fsd size lower bound in m (radius) + floe_rad_c_out, & ! fsd size bin centre in m (radius) + floe_binwidth_out ! fsd size bin width in m (radius) - character (len=35), intent(out) :: & - c_fsd_range(nfsd) ! string for history output + character (len=35), dimension(:), intent(out), optional :: & + c_fsd_range_out ! string for history output logical (kind=log_kind), intent(in), optional :: & - write_diags ! write diags flag + write_diags ! write diags flag !autodocument_end @@ -111,11 +117,8 @@ subroutine icepack_init_fsd_bounds( & real (kind=dbl_kind) :: test - real (kind=dbl_kind), dimension (0:nfsd) :: & - floe_rad - real (kind=dbl_kind), dimension(:), allocatable :: & - lims + lims, floe_rad character(len=8) :: c_fsd1,c_fsd2 character(len=2) :: c_nf @@ -169,10 +172,15 @@ subroutine icepack_init_fsd_bounds( & allocate( & floe_rad_h (nfsd), & ! fsd size higher bound in m (radius) + floe_rad_l (nfsd), & ! fsd size lower bound in m (radius) + floe_rad_c (nfsd), & ! fsd size center in m (radius) + floe_rad (0:nfsd), & ! fsd bounds in m (radius) floe_area_l (nfsd), & ! fsd area at lower bound (m^2) floe_area_h (nfsd), & ! fsd area at higher bound (m^2) floe_area_c (nfsd), & ! fsd area at bin centre (m^2) floe_area_binwidth (nfsd), & ! floe area bin width (m^2) + floe_binwidth (nfsd), & ! floe bin width (m) + c_fsd_range (nfsd), & ! iweld (nfsd, nfsd), & ! fsd categories that can weld stat=ierr) if (ierr/=0) then @@ -186,8 +194,11 @@ subroutine icepack_init_fsd_bounds( & floe_rad_c = (floe_rad_h+floe_rad_l)/c2 floe_area_l = c4*floeshape*floe_rad_l**2 - floe_area_c = c4*floeshape*floe_rad_c**2 floe_area_h = c4*floeshape*floe_rad_h**2 +! floe_area_c = c4*floeshape*floe_rad_c**2 +! This is exactly in the middle of floe_area_h and floe_area_l +! Whereas the above calculation is closer to floe_area_l. + floe_area_c = (floe_area_h+floe_area_l)/c2 floe_binwidth = floe_rad_h - floe_rad_l @@ -220,20 +231,56 @@ subroutine icepack_init_fsd_bounds( & enddo if (present(write_diags)) then - if (write_diags) then - write(warnstr,*) ' ' - call icepack_warnings_add(warnstr) - write(warnstr,*) subname - call icepack_warnings_add(warnstr) - write(warnstr,*) 'floe_rad(n-1) < fsd Cat n < floe_rad(n)' - call icepack_warnings_add(warnstr) - do n = 1, nfsd - write(warnstr,*) floe_rad(n-1),' < fsd Cat ',n, ' < ',floe_rad(n) + if (write_diags) then + write(warnstr,*) ' ' call icepack_warnings_add(warnstr) - enddo - write(warnstr,*) ' ' - call icepack_warnings_add(warnstr) + write(warnstr,*) subname + call icepack_warnings_add(warnstr) + write(warnstr,*) 'floe_rad(n-1) < fsd Cat n < floe_rad(n)' + call icepack_warnings_add(warnstr) + do n = 1, nfsd + write(warnstr,*) floe_rad(n-1),' < fsd Cat ',n, ' < ',floe_rad(n) + call icepack_warnings_add(warnstr) + enddo + write(warnstr,*) ' ' + call icepack_warnings_add(warnstr) + endif + endif + + if (present(floe_rad_l_out)) then + if (size(floe_rad_l_out) /= size(floe_rad_l)) then + call icepack_warnings_add(subname//' floe_rad_l_out incorrect size') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + return + endif + floe_rad_l_out(:) = floe_rad_l(:) + endif + + if (present(floe_rad_c_out)) then + if (size(floe_rad_c_out) /= size(floe_rad_c)) then + call icepack_warnings_add(subname//' floe_rad_c_out incorrect size') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + return + endif + floe_rad_c_out(:) = floe_rad_c(:) endif + + if (present(floe_binwidth_out)) then + if (size(floe_binwidth_out) /= size(floe_binwidth)) then + call icepack_warnings_add(subname//' floe_binwidth_out incorrect size') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + return + endif + floe_binwidth_out(:) = floe_binwidth(:) + endif + + if (present(c_fsd_range_out)) then + if (size(c_fsd_range_out) /= size(c_fsd_range)) then + call icepack_warnings_add(subname//' c_fsd_range_out incorrect size') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + return + endif + c_fsd_range_out(:) = c_fsd_range(:) endif end subroutine icepack_init_fsd_bounds @@ -256,18 +303,11 @@ end subroutine icepack_init_fsd_bounds ! ! authors: Lettie Roach, NIWA/VUW - subroutine icepack_init_fsd(ice_ic, & - floe_rad_c, & ! fsd size bin centre in m (radius) - floe_binwidth, & ! fsd size bin width in m (radius) - afsd) ! floe size distribution tracer + subroutine icepack_init_fsd(ice_ic, afsd) ! floe size distribution tracer character(len=char_len_long), intent(in) :: & ice_ic ! method of ice cover initialization - real(kind=dbl_kind), dimension(:), intent(inout) :: & - floe_rad_c, & ! fsd size bin centre in m (radius) - floe_binwidth ! fsd size bin width in m (radius) - real (kind=dbl_kind), dimension (:), intent(inout) :: & afsd ! floe size tracer: fraction distribution of floes @@ -323,7 +363,6 @@ subroutine icepack_cleanup_fsd (afsdn) character(len=*), parameter :: subname='(icepack_cleanup_fsd)' - if (tr_fsd) then do n = 1, ncat @@ -378,14 +417,11 @@ end subroutine icepack_cleanup_fsdn ! ! authors: Lettie Roach, NIWA/VUW - subroutine partition_area (floe_rad_c, aice, & + subroutine partition_area (aice, & aicen, vicen, & afsdn, lead_area, & latsurf_area) - real (kind=dbl_kind), dimension(:), intent(in) :: & - floe_rad_c ! fsd size bin centre in m (radius) - real (kind=dbl_kind), intent(in) :: & aice ! ice concentration @@ -476,7 +512,7 @@ end subroutine partition_area subroutine fsd_lateral_growth (dt, aice, & aicen, vicen, & vi0new, & - frazil, floe_rad_c, & + frazil, & afsdn, & lead_area, latsurf_area, & G_radial, d_an_latg, & @@ -497,10 +533,6 @@ subroutine fsd_lateral_growth (dt, aice, & vi0new , & ! volume of new ice added to cat 1 (m) frazil ! frazil ice growth (m/step-->cm/day) - ! floe size distribution - real (kind=dbl_kind), dimension (:), intent(in) :: & - floe_rad_c ! fsd size bin centre in m (radius) - real (kind=dbl_kind), dimension(ncat), intent(out) :: & d_an_latg ! change in aicen occuring due to lateral growth @@ -529,7 +561,7 @@ subroutine fsd_lateral_growth (dt, aice, & d_an_latg = c0 ! partition volume into lateral growth and frazil - call partition_area (floe_rad_c, aice, & + call partition_area (aice, & aicen, vicen, & afsdn, lead_area, & latsurf_area) @@ -540,9 +572,6 @@ subroutine fsd_lateral_growth (dt, aice, & vi0new_lat = vi0new * lead_area / (c1 + aice/latsurf_area) end if - ! for history/diagnostics - frazil = vi0new - vi0new_lat - ! lateral growth increment if (vi0new_lat > puny) then G_radial = vi0new_lat/dt @@ -563,8 +592,6 @@ subroutine fsd_lateral_growth (dt, aice, & endif ! vi0new_lat > 0 ! Use remaining ice volume as in standard model, - ! but ice cannot grow into the area that has grown laterally - vi0new = vi0new - vi0new_lat tot_latg = SUM(d_an_latg(:)) end subroutine fsd_lateral_growth @@ -589,7 +616,6 @@ end subroutine fsd_lateral_growth subroutine fsd_add_new_ice (n, & dt, ai0new, & d_an_latg, d_an_newi, & - floe_rad_c, floe_binwidth, & G_radial, area2, & wave_sig_ht, & wave_spectrum, & @@ -623,9 +649,7 @@ subroutine fsd_add_new_ice (n, & real (kind=dbl_kind), dimension (:), intent(in) :: & aicen_init , & ! fractional area of ice - aicen , & ! after update - floe_rad_c , & ! fsd size bin centre in m (radius) - floe_binwidth ! fsd size bin width in m (radius) + aicen ! after update real (kind=dbl_kind), dimension (:,:), intent(in) :: & afsdn ! floe size distribution tracer diff --git a/columnphysics/icepack_therm_itd.F90 b/columnphysics/icepack_therm_itd.F90 index 02a9ab4b8..0fcc96738 100644 --- a/columnphysics/icepack_therm_itd.F90 +++ b/columnphysics/icepack_therm_itd.F90 @@ -20,6 +20,9 @@ module icepack_therm_itd use icepack_kinds + + use icepack_fsd, only: floe_rad_c, floe_binwidth + use icepack_parameters, only: c0, c1, c2, c3, c4, c6, c10 use icepack_parameters, only: p001, p1, p333, p5, p666, puny, bignum use icepack_parameters, only: rhos, rhoi, Lfresh, ice_ref_salinity @@ -870,12 +873,11 @@ subroutine lateral_melt (dt, fpond, & fresh, fsalt, & fhocn, faero_ocn, & fiso_ocn, & - rside, meltl, & - fside, wlat, & + rsiden, meltl, & + wlat, & aicen, vicen, & vsnon, trcrn, & - flux_bio, d_afsd_latm,& - floe_rad_c, floe_binwidth) + flux_bio, d_afsd_latm) real (kind=dbl_kind), intent(in) :: & dt ! time step (s) @@ -888,15 +890,12 @@ subroutine lateral_melt (dt, fpond, & real (kind=dbl_kind), dimension (:,:), intent(inout) :: & trcrn ! tracer array - real (kind=dbl_kind), intent(in) :: & - rside ! fraction of ice that melts laterally + real (kind=dbl_kind), dimension (:), intent(in) :: & + rsiden ! fraction of ice that melts laterally real (kind=dbl_kind), intent(in), optional :: & wlat ! lateral melt rate (m/s) - real (kind=dbl_kind), intent(inout) :: & - fside ! lateral heat flux (W/m^2) - real (kind=dbl_kind), intent(inout) :: & fpond , & ! fresh water flux to ponds (kg/m^2/s) fresh , & ! fresh water flux to ocean (kg/m^2/s) @@ -913,10 +912,6 @@ subroutine lateral_melt (dt, fpond, & real (kind=dbl_kind), dimension(:), intent(inout), optional :: & fiso_ocn ! isotope flux to ocean (kg/m^2/s) - real (kind=dbl_kind), dimension (:), intent(in), optional :: & - floe_rad_c , & ! fsd size bin centre in m (radius) - floe_binwidth ! fsd size bin width in m (radius) - real (kind=dbl_kind), dimension (:), intent(out), optional :: & d_afsd_latm ! change in fsd due to lateral melt (m) @@ -934,19 +929,13 @@ subroutine lateral_melt (dt, fpond, & dfsalt , & ! change in fsalt dvssl , & ! snow surface layer volume dvint , & ! snow interior layer - bin1_arealoss, tmp ! - - logical (kind=log_kind) :: & - fsd_wlat, & ! .true. if wlat present and wlat > puny - flag ! .true. if there could be lateral melting + tmp real (kind=dbl_kind), dimension (ncat) :: & aicen_init, & ! initial area fraction vicen_init, & ! volume per unit area of ice (m) - vsnon_init, & ! initial volume of snow (m) - G_radialn , & ! rate of lateral melt (m/s) - delta_an , & ! change in the ITD - rsiden ! delta_an/aicen + vsnon_init, & ! volume per unit area of snow (m) + G_radialn ! rate of lateral melt (m/s) real (kind=dbl_kind), dimension (:,:), allocatable :: & afsdn , & ! floe size distribution tracer @@ -966,19 +955,18 @@ subroutine lateral_melt (dt, fpond, & character(len=*), parameter :: subname='(lateral_melt)' - flag = .false. + if (tr_fsd) d_afsd_latm = c0 + + if (.not. any(rsiden(:) > c0)) return ! no lateral melt, get out now + dfhocn = c0 dfpond = c0 dfresh = c0 dfsalt = c0 dvssl = c0 dvint = c0 - bin1_arealoss = c0 - tmp = c0 - vicen_init = vicen(:) - G_radialn = c0 - delta_an = c0 - rsiden = c0 + vicen_init(:) = vicen(:) + vsnon_init(:) = vsnon(:) if (tr_fsd) then call icepack_cleanup_fsd (trcrn(nt_fsd:nt_fsd+nfsd-1,:)) @@ -995,216 +983,141 @@ subroutine lateral_melt (dt, fpond, & afsdn = trcrn(nt_fsd:nt_fsd+nfsd-1,:) afsdn_init = afsdn ! for diagnostics df_flx = c0 - d_afsd_latm = c0 f_flx = c0 end if - ! fsd_wlat == if (tr_fsd .and. wlat > puny) - ! need fsd_wlat because wlat is optional - fsd_wlat = .false. - if (tr_fsd .and. present(wlat)) then - if (wlat > puny) fsd_wlat = .true. - endif - - if (fsd_wlat) then - flag = .true. - - ! for FSD rside and fside not yet computed correctly, redo here - fside = c0 - do n = 1, ncat - - G_radialn(n) = -wlat ! negative - - if (any(afsdn(:,n) < c0)) then - write(warnstr,*) subname, 'lateral_melt B afsd < 0 ',n - call icepack_warnings_add(warnstr) - endif - - bin1_arealoss = -trcrn(nt_fsd+1-1,n) * aicen(n) * dt & - * G_radialn(n) / floe_binwidth(1) - - delta_an(n) = c0 - do k = 1, nfsd - delta_an(n) = delta_an(n) + ((c2/floe_rad_c(k))*aicen(n) & - * trcrn(nt_fsd+k-1,n)*G_radialn(n)*dt) ! delta_an < 0 - end do - - ! add negative area loss from fsd - delta_an(n) = delta_an(n) - bin1_arealoss - - if (delta_an(n) > c0) then - write(warnstr,*) subname, 'ERROR delta_an > 0 ',delta_an(n) - call icepack_warnings_add(warnstr) - endif - - ! following original code, not necessary for fsd - if (aicen(n) > c0) rsiden(n) = MIN(-delta_an(n)/aicen(n),c1) - - if (rsiden(n) < c0) then - write(warnstr,*) subname, 'ERROR rsiden < 0 ',rsiden(n) - call icepack_warnings_add(warnstr) - endif - - ! melting energy/unit area in each column, etot < 0 - etot = c0 - do k = 1, nslyr - etot = etot + trcrn(nt_qsno+k-1,n) * vsnon(n)/real(nslyr,kind=dbl_kind) - enddo - - do k = 1, nilyr - etot = etot + trcrn(nt_qice+k-1,n) * vicen(n)/real(nilyr,kind=dbl_kind) - enddo ! nilyr - - ! lateral heat flux, fside < 0 - fside = fside + rsiden(n)*etot/dt - - enddo ! ncat - - else if (rside > c0) then ! original, non-fsd implementation - - flag = .true. - rsiden(:) = rside ! initialize - - endif - - if (flag) then ! grid cells with lateral melting. - - do n = 1, ncat + do n = 1, ncat !----------------------------------------------------------------- ! Melt the ice and increment fluxes. !----------------------------------------------------------------- - ! fluxes to coupler - ! dfresh > 0, dfsalt > 0, dfpond > 0 + ! fluxes to coupler + ! dfresh > 0, dfsalt > 0, dfpond > 0 - dfresh = (rhoi*vicen(n) + rhos*vsnon(n)) * rsiden(n) / dt - if (saltflux_option == 'prognostic') then - sicen = c0 - do k=1,nilyr - sicen = sicen + trcrn(nt_sice+k-1,n) / real(nilyr,kind=dbl_kind) - enddo - dfsalt = rhoi*vicen(n)*sicen*p001 * rsiden(n) / dt - else - dfsalt = rhoi*vicen(n)*ice_ref_salinity*p001 * rsiden(n) / dt - endif - fresh = fresh + dfresh - fsalt = fsalt + dfsalt - - if (tr_pond_topo) then - dfpond = aicen(n)*trcrn(nt_apnd,n)*trcrn(nt_hpnd,n)*rsiden(n) - fpond = fpond - dfpond - endif - - ! history diagnostics - meltl = meltl + vicen(n)*rsiden(n) + dfresh = (rhoi*vicen(n) + rhos*vsnon(n)) * rsiden(n) / dt + if (saltflux_option == 'prognostic') then + sicen = c0 + do k=1,nilyr + sicen = sicen + trcrn(nt_sice+k-1,n) / real(nilyr,kind=dbl_kind) + enddo + dfsalt = rhoi*vicen(n)*sicen*p001 * rsiden(n) / dt + else + dfsalt = rhoi*vicen(n)*ice_ref_salinity*p001 * rsiden(n) / dt + endif + fresh = fresh + dfresh + fsalt = fsalt + dfsalt - ! state variables - vicen_init(n) = vicen(n) - vsnon_init(n) = vsnon(n) - aicen(n) = aicen(n) * (c1 - rsiden(n)) - vicen(n) = vicen(n) * (c1 - rsiden(n)) - vsnon(n) = vsnon(n) * (c1 - rsiden(n)) + if (tr_pond_topo) then + dfpond = aicen(n)*trcrn(nt_apnd,n)*trcrn(nt_hpnd,n)*rsiden(n) + fpond = fpond - dfpond + endif - ! floe size distribution - if (tr_fsd) then - if (rsiden(n) > puny) then - if (aicen(n) > puny) then + ! history diagnostics + meltl = meltl + vicen_init(n)*rsiden(n) - ! adaptive subtimestep - elapsed_t = c0 - afsd_tmp(:) = afsdn_init(:,n) - d_afsd_tmp(:) = c0 - nsubt = 0 + ! state variables + aicen(n) = aicen(n) * (c1 - rsiden(n)) + vicen(n) = vicen(n) * (c1 - rsiden(n)) + vsnon(n) = vsnon(n) * (c1 - rsiden(n)) - DO WHILE (elapsed_t.lt.dt) + ! floe size distribution + if (tr_fsd) then + if (rsiden(n) > puny) then + if (aicen(n) > puny) then - nsubt = nsubt + 1 - if (nsubt.gt.100) then - write(warnstr,*) subname, 'latm not converging' - call icepack_warnings_add(warnstr) - endif + ! adaptive subtimestep + elapsed_t = c0 + afsd_tmp(:) = afsdn_init(:,n) + d_afsd_tmp(:) = c0 + nsubt = 0 - ! finite differences - df_flx(:) = c0 - f_flx (:) = c0 - do k = 2, nfsd - f_flx(k) = G_radialn(n) * afsd_tmp(k) / floe_binwidth(k) - end do + DO WHILE (elapsed_t.lt.dt) - do k = 1, nfsd - df_flx(k) = f_flx(k+1) - f_flx(k) - end do + nsubt = nsubt + 1 + if (nsubt.gt.100) then + write(warnstr,*) subname, 'latm not converging' + call icepack_warnings_add(warnstr) + endif - if (abs(sum(df_flx(:))) > puny) then - write(warnstr,*) subname, 'sum(df_flx) /= 0' - call icepack_warnings_add(warnstr) - endif + ! finite differences + df_flx(:) = c0 + f_flx (:) = c0 + G_radialn(n) = -wlat + do k = 2, nfsd + f_flx(k) = G_radialn(n) * afsd_tmp(k) / floe_binwidth(k) + end do - ! this term ensures area conservation - tmp = SUM(afsd_tmp(:)/floe_rad_c(:)) + do k = 1, nfsd + df_flx(k) = f_flx(k+1) - f_flx(k) + end do - ! fsd tendency - do k = 1, nfsd - d_afsd_tmp(k) = -df_flx(k) + c2 * G_radialn(n) * afsd_tmp(k) & - * (c1/floe_rad_c(k) - tmp) - end do + if (abs(sum(df_flx(:))) > puny) then + write(warnstr,*) subname, 'sum(df_flx) /= 0' + call icepack_warnings_add(warnstr) + endif - ! timestep required for this - subdt = get_subdt_fsd(afsd_tmp(:), d_afsd_tmp(:)) - subdt = MIN(subdt, dt) + ! this term ensures area conservation + tmp = SUM(afsd_tmp(:)/floe_rad_c(:)) - ! update fsd and elapsed time - afsd_tmp(:) = afsd_tmp(:) + subdt*d_afsd_tmp(:) - elapsed_t = elapsed_t + subdt + ! fsd tendency + do k = 1, nfsd + d_afsd_tmp(k) = -df_flx(k) + c2 * G_radialn(n) * afsd_tmp(k) & + * (c1/floe_rad_c(k) - tmp) + end do + ! timestep required for this + subdt = get_subdt_fsd(afsd_tmp(:), d_afsd_tmp(:)) + subdt = MIN(subdt, dt) - END DO + ! update fsd and elapsed time + afsd_tmp(:) = afsd_tmp(:) + subdt*d_afsd_tmp(:) + elapsed_t = elapsed_t + subdt - afsdn(:,n) = afsd_tmp(:) + END DO + afsdn(:,n) = afsd_tmp(:) - end if ! aicen - end if ! rside > 0, otherwise do nothing + end if ! aicen + end if ! rside > 0, otherwise do nothing - end if ! tr_fsd + end if ! tr_fsd - ! fluxes - do k = 1, nilyr - ! enthalpy tracers do not change (e/v constant) - ! heat flux to coupler for ice melt (dfhocn < 0) - dfhocn = trcrn(nt_qice+k-1,n)*rsiden(n) / dt & - * vicen(n)/real(nilyr,kind=dbl_kind) - fhocn = fhocn + dfhocn - enddo ! nilyr - - do k = 1, nslyr - ! heat flux to coupler for snow melt (dfhocn < 0) - dfhocn = trcrn(nt_qsno+k-1,n)*rsiden(n) / dt & - * vsnon(n)/real(nslyr,kind=dbl_kind) - fhocn = fhocn + dfhocn - enddo ! nslyr + ! fluxes + do k = 1, nilyr + ! enthalpy tracers do not change (e/v constant) + ! heat flux to coupler for ice melt (dfhocn < 0) + dfhocn = trcrn(nt_qice+k-1,n)*rsiden(n) / dt & + * vicen_init(n)/real(nilyr,kind=dbl_kind) + fhocn = fhocn + dfhocn + enddo ! nilyr - if (tr_aero) then - do k = 1, n_aero - faero_ocn(k) = faero_ocn(k) + (vsnon(n) & - *(trcrn(nt_aero +4*(k-1),n) & - + trcrn(nt_aero+1+4*(k-1),n)) & - + vicen(n) & - *(trcrn(nt_aero+2+4*(k-1),n) & - + trcrn(nt_aero+3+4*(k-1),n))) & - * rsiden(n) / dt - enddo ! k - endif ! tr_aero - - if (tr_iso) then - do k = 1, n_iso - fiso_ocn(k) = fiso_ocn(k) & - + (vsnon(n)*trcrn(nt_isosno+k-1,n) & - + vicen(n)*trcrn(nt_isoice+k-1,n)) & - * rside / dt - enddo ! k - endif ! tr_iso + do k = 1, nslyr + ! heat flux to coupler for snow melt (dfhocn < 0) + dfhocn = trcrn(nt_qsno+k-1,n)*rsiden(n) / dt & + * vsnon_init(n)/real(nslyr,kind=dbl_kind) + fhocn = fhocn + dfhocn + enddo ! nslyr + + if (tr_aero) then + do k = 1, n_aero + faero_ocn(k) = faero_ocn(k) & + + (vsnon_init(n) * (trcrn(nt_aero +4*(k-1),n) & + + trcrn(nt_aero+1+4*(k-1),n)) & + + vicen_init(n) * (trcrn(nt_aero+2+4*(k-1),n) & + + trcrn(nt_aero+3+4*(k-1),n))) & + * rsiden(n) / dt + enddo ! k + endif ! tr_aero + + if (tr_iso) then + do k = 1, n_iso + fiso_ocn(k) = fiso_ocn(k) & + + (vsnon_init(n)*trcrn(nt_isosno+k-1,n) & + + vicen_init(n)*trcrn(nt_isoice+k-1,n)) & + * rsiden(n) / dt + enddo ! k + endif ! tr_iso !----------------------------------------------------------------- ! Biogeochemistry @@ -1229,32 +1142,31 @@ subroutine lateral_melt (dt, fpond, & trcrn, flux_bio) if (icepack_warnings_aborted(subname)) return - endif ! flag - if (tr_fsd) then + if (tr_fsd) then - trcrn(nt_fsd:nt_fsd+nfsd-1,:) = afsdn + trcrn(nt_fsd:nt_fsd+nfsd-1,:) = afsdn - call icepack_cleanup_fsd (trcrn(nt_fsd:nt_fsd+nfsd-1,:) ) - if (icepack_warnings_aborted(subname)) return + call icepack_cleanup_fsd (trcrn(nt_fsd:nt_fsd+nfsd-1,:) ) + if (icepack_warnings_aborted(subname)) return - ! diagnostics - do k = 1, nfsd - d_afsd_latm(k) = c0 - do n = 1, ncat - d_afsd_latm(k) = d_afsd_latm(k) & - + afsdn(k,n)*aicen(n) - afsdn_init(k,n)*aicen_init(n) - end do - end do + ! diagnostics + do k = 1, nfsd + d_afsd_latm(k) = c0 + do n = 1, ncat + d_afsd_latm(k) = d_afsd_latm(k) & + + afsdn(k,n)*aicen(n) - afsdn_init(k,n)*aicen_init(n) + end do + end do - deallocate(afsdn) - deallocate(afsdn_init) - deallocate(df_flx) - deallocate(afsd_tmp) - deallocate(d_afsd_tmp) - deallocate(f_flx) + deallocate(afsdn) + deallocate(afsdn_init) + deallocate(df_flx) + deallocate(afsd_tmp) + deallocate(d_afsd_tmp) + deallocate(f_flx) - end if + end if end subroutine lateral_melt @@ -1301,8 +1213,7 @@ subroutine add_new_ice (dt, & wavefreq, & dwavefreq, & d_afsd_latg, & - d_afsd_newi, & - floe_rad_c, floe_binwidth) + d_afsd_newi) use icepack_fsd, only: fsd_lateral_growth, fsd_add_new_ice @@ -1376,10 +1287,6 @@ subroutine add_new_ice (dt, & wavefreq, & ! wave frequencies (s^-1) dwavefreq ! wave frequency bin widths (s^-1) - real (kind=dbl_kind), dimension (:), intent(in), optional :: & - floe_rad_c , & ! fsd size bin centre in m (radius) - floe_binwidth ! fsd size bin width in m (radius) - real (kind=dbl_kind), dimension(:), intent(out), optional :: & ! change in thickness distribution (area) d_afsd_latg , & ! due to fsd lateral growth @@ -1608,11 +1515,30 @@ subroutine add_new_ice (dt, & call fsd_lateral_growth(dt, aice, & aicen, vicen, & vi0new, frazil, & - floe_rad_c, afsdn, & + afsdn, & lead_area, latsurf_area, & G_radial, d_an_latg, & tot_latg) if (icepack_warnings_aborted(subname)) return + + ! volume added to each category from lateral growth + do n = 1, ncat + if (aicen(n) > puny) then + vin0new(n) = d_an_latg(n) * vicen(n)/aicen(n) + endif + end do + + ! check lateral growth doesn't exceed total growth + ! if it does, adjust it + if (SUM(vin0new)>vi0new) then + write(warnstr,*) subname,'lateral growth warning ',vi0new,SUM(vin0new) + call icepack_warnings_add(warnstr) + vin0new(:) = vin0new(:)*vi0new/SUM(vin0new) + end if + + vi0new = vi0new - SUM(vin0new) + frazil = frazil - SUM(vin0new) + endif ai0mod = aice0 @@ -1639,11 +1565,6 @@ subroutine add_new_ice (dt, & vi0new = c0 endif ! aice0 > puny - ! volume added to each category from lateral growth - do n = 1, ncat - if (aicen(n) > c0) vin0new(n) = d_an_latg(n) * vicen(n)/aicen(n) - end do - ! combine areal change from new ice growth and lateral growth d_an_newi(1) = ai0new d_an_tot(2:ncat) = d_an_latg(2:ncat) @@ -1790,7 +1711,6 @@ subroutine add_new_ice (dt, & call fsd_add_new_ice (n, & dt, ai0new, & d_an_latg, d_an_newi, & - floe_rad_c, floe_binwidth, & G_radial, area2, & wave_sig_ht, & wave_spectrum, & @@ -1933,8 +1853,8 @@ subroutine icepack_step_therm2(dt, hin_max, & nt_strata, & Tf, sss, & salinz, & - rside, meltl, & - fside, wlat, & + rsiden, meltl, & + wlat, & frzmlt, frazil, & frain, fpond, & fresh, fsalt, & @@ -1951,8 +1871,7 @@ subroutine icepack_step_therm2(dt, hin_max, & wavefreq, & dwavefreq, & d_afsd_latg, d_afsd_newi, & - d_afsd_latm, d_afsd_weld, & - floe_rad_c, floe_binwidth) + d_afsd_latm, d_afsd_weld) use icepack_parameters, only: icepack_init_parameters @@ -1966,7 +1885,6 @@ subroutine icepack_step_therm2(dt, hin_max, & dt , & ! time step Tf , & ! freezing temperature (C) sss , & ! sea surface salinity (ppt) - rside , & ! fraction of ice that melts laterally frzmlt ! freezing/melting potential (W/m^2) integer (kind=int_kind), dimension (:), intent(in) :: & @@ -1981,13 +1899,13 @@ subroutine icepack_step_therm2(dt, hin_max, & nt_strata ! indices of underlying tracer layers real (kind=dbl_kind), dimension(:), intent(in) :: & + rsiden , & ! fraction of ice that melts laterally salinz , & ! initial salinity profile ocean_bio ! ocean concentration of biological tracer real (kind=dbl_kind), intent(inout) :: & aice , & ! sea ice concentration aice0 , & ! concentration of open water - fside , & ! lateral heat flux (W/m^2) frain , & ! rainfall rate (kg/m^2 s) fpond , & ! fresh water flux to ponds (kg/m^2/s) fresh , & ! fresh water flux to ocean (kg/m^2/s) @@ -2050,10 +1968,6 @@ subroutine icepack_step_therm2(dt, hin_max, & d_afsd_latm, & ! lateral melt d_afsd_weld ! welding - real (kind=dbl_kind), dimension (:), intent(in), optional :: & - floe_rad_c, & ! fsd size bin centre in m (radius) - floe_binwidth ! fsd size bin width in m (radius) - !autodocument_end ! local variables @@ -2090,9 +2004,7 @@ subroutine icepack_step_therm2(dt, hin_max, & present(d_afsd_latg) .and. & present(d_afsd_newi) .and. & present(d_afsd_latm) .and. & - present(d_afsd_weld) .and. & - present(floe_rad_c) .and. & - present(floe_binwidth))) then + present(d_afsd_weld))) then call icepack_warnings_add(subname//' error in FSD arguments, tr_fsd=T') call icepack_warnings_setabort(.true.,__FILE__,__LINE__) return @@ -2177,8 +2089,7 @@ subroutine icepack_step_therm2(dt, hin_max, & wave_sig_ht, & wave_spectrum, & wavefreq, dwavefreq, & - d_afsd_latg, d_afsd_newi, & - floe_rad_c, floe_binwidth) + d_afsd_latg, d_afsd_newi) if (icepack_warnings_aborted(subname)) return @@ -2190,13 +2101,12 @@ subroutine icepack_step_therm2(dt, hin_max, & fresh, fsalt, & fhocn, faero_ocn, & fiso_ocn, & - rside, meltl, & - fside, wlat, & + rsiden, meltl, & + wlat, & aicen, vicen, & vsnon, trcrn, & flux_bio, & - d_afsd_latm, & - floe_rad_c,floe_binwidth) + d_afsd_latm) if (icepack_warnings_aborted(subname)) return ! Floe welding during freezing conditions diff --git a/columnphysics/icepack_therm_vertical.F90 b/columnphysics/icepack_therm_vertical.F90 index 6dda193af..bf96096eb 100644 --- a/columnphysics/icepack_therm_vertical.F90 +++ b/columnphysics/icepack_therm_vertical.F90 @@ -20,7 +20,10 @@ module icepack_therm_vertical use icepack_kinds - use icepack_parameters, only: c0, c1, p001, p5, puny + + use icepack_fsd, only: floe_rad_c, floe_binwidth + + use icepack_parameters, only: c0, c1, c2, p001, p5, puny use icepack_parameters, only: pi, depressT, Lvap, hs_min, cp_ice, min_salin use icepack_parameters, only: cp_ocn, rhow, rhoi, rhos, Lfresh, rhofresh, ice_ref_salinity use icepack_parameters, only: ktherm, calc_Tsfc, rsnw_fall, rsnw_tmax @@ -30,7 +33,7 @@ module icepack_therm_vertical use icepack_parameters, only: saltflux_option, congel_freeze use icepack_parameters, only: icepack_chkoptargflag - use icepack_tracers, only: ncat, nilyr, nslyr + use icepack_tracers, only: ncat, nilyr, nslyr, nfsd use icepack_tracers, only: tr_iage, tr_FY, tr_aero, tr_pond, tr_fsd, tr_iso use icepack_tracers, only: tr_pond_lvl, tr_pond_topo use icepack_tracers, only: n_aero, n_iso @@ -484,8 +487,9 @@ subroutine frzmlt_bottom_lateral (dt, & fbot_xfer_type, & strocnxT, strocnyT, & Tbot, fbot, & - rside, Cdn_ocn, & - fside, wlat) + rsiden, Cdn_ocn, & + wlat, aicen, & + afsdn) real (kind=dbl_kind), intent(in) :: & dt ! time step @@ -513,14 +517,28 @@ subroutine frzmlt_bottom_lateral (dt, & real (kind=dbl_kind), intent(out) :: & Tbot , & ! ice bottom surface temperature (deg C) - fbot , & ! heat flux to ice bottom (W/m^2) - rside , & ! fraction of ice that melts laterally - fside ! lateral heat flux (W/m^2) + fbot ! heat flux to ice bottom (W/m^2) + + real (kind=dbl_kind), dimension(:), intent(out) :: & + rsiden ! fraction of ice that melts laterally real (kind=dbl_kind), intent(out), optional :: & wlat ! lateral melt rate (m/s) + real (kind=dbl_kind), dimension(:), intent(in) :: & + aicen ! ice concentration + + real (kind=dbl_kind), dimension (:,:), intent(in), optional :: & + afsdn ! area floe size distribution + ! local variables + real (kind=dbl_kind), dimension (ncat) :: & + delta_an , & ! change in the ITD + G_radialn ! lateral melt rate in FSD (m/s) + + real (kind=dbl_kind) :: & + rside , & ! + fside ! lateral heat flux (W/m^2) integer (kind=int_kind) :: & n , & ! thickness category index @@ -534,6 +552,7 @@ subroutine frzmlt_bottom_lateral (dt, & real (kind=dbl_kind) :: & deltaT , & ! SST - Tbot >= 0 ustar , & ! skin friction velocity for fbot (m/s) + bin1_arealoss, & xtmp ! temporary variable ! Parameters for bottom melting @@ -555,11 +574,11 @@ subroutine frzmlt_bottom_lateral (dt, & ! Identify grid cells where ice can melt. !----------------------------------------------------------------- - rside = c0 - fside = c0 + rsiden(:) = c0 Tbot = Tf fbot = c0 wlat_loc = c0 + if (present(wlat)) wlat=c0 if (aice > puny .and. frzmlt < c0) then ! ice can melt @@ -599,10 +618,52 @@ subroutine frzmlt_bottom_lateral (dt, & rside = wlat_loc*dt*pi/(floeshape*floediam) ! Steele rside = max(c0,min(rside,c1)) + if (rside == c0) return ! nothing more to do so get out + + rsiden(:) = rside + + if (tr_fsd) then ! alter rsiden now since floes are not of size floediam + + do n = 1, ncat + G_radialn(n) = -wlat_loc ! negative + + ! afsdn present check up the calling tree + if (any(afsdn(:,n) < c0)) then + write(warnstr,*) subname, 'lateral_melt B afsd < 0 ',n + call icepack_warnings_add(warnstr) + endif + + bin1_arealoss = -afsdn(1,n) / floe_binwidth(1) ! when scaled by *G_radialn(n)*dt*aicen(n) + + delta_an(n) = c0 + do k = 1, nfsd + ! this is delta_an(n) when scaled by *G_radialn(n)*dt*aicen(n) + delta_an(n) = delta_an(n) + ((c2/floe_rad_c(k)) * afsdn(k,n)) ! delta_an < 0 + end do + + ! add negative area loss from fsd + delta_an(n) = (delta_an(n) - bin1_arealoss)*G_radialn(n)*dt + + if (delta_an(n) > c0) then + write(warnstr,*) subname, 'ERROR delta_an > 0 ',delta_an(n) + call icepack_warnings_add(warnstr) + endif + + ! following original code, not necessary for fsd + if (aicen(n) > c0) rsiden(n) = MIN(-delta_an(n),c1) + + if (rsiden(n) < c0) then + write(warnstr,*) subname, 'ERROR rsiden < 0 ',rsiden(n) + call icepack_warnings_add(warnstr) + endif + enddo ! ncat + + endif ! if tr_fsd + !----------------------------------------------------------------- ! Compute heat flux associated with this value of rside. !----------------------------------------------------------------- - + fside = c0 do n = 1, ncat etot = c0 @@ -617,20 +678,23 @@ subroutine frzmlt_bottom_lateral (dt, & enddo ! nilyr ! lateral heat flux, fside < 0 - fside = fside + rside*etot/dt + fside = fside + rsiden(n)*etot/dt enddo ! n !----------------------------------------------------------------- ! Limit bottom and lateral heat fluxes if necessary. - ! FYI: fside is not yet correct for fsd, may need to adjust fbot further + ! Limit rside so we don't melt laterally more ice than frzmlt permits !----------------------------------------------------------------- xtmp = frzmlt/(fbot + fside - puny) xtmp = min(xtmp, c1) + xtmp = max(xtmp, c0) fbot = fbot * xtmp - rside = rside * xtmp - fside = fside * xtmp + + do n = 1, ncat + rsiden(n) = rsiden(n) * xtmp ! xtmp is almost always 1 so usually nothing happens here + enddo ! ncat endif @@ -2089,8 +2153,8 @@ subroutine icepack_step_therm1(dt, & strocnxT , strocnyT , & fbot , & Tbot , Tsnice , & - frzmlt , rside , & - fside , wlat , & + frzmlt , rsiden , & + wlat , & fsnow , frain , & fpond , fsloss , & fsurf , fsurfn , & @@ -2137,7 +2201,7 @@ subroutine icepack_step_therm1(dt, & lmask_n , lmask_s , & mlt_onset , frz_onset , & yday , prescribed_ice, & - zlvs) + zlvs , afsdn) real (kind=dbl_kind), intent(in) :: & dt , & ! time step @@ -2213,8 +2277,6 @@ subroutine icepack_step_therm1(dt, & strocnyT , & ! ice-ocean stress, y-direction fbot , & ! ice-ocean heat flux at bottom surface (W/m^2) frzmlt , & ! freezing/melting potential (W/m^2) - rside , & ! fraction of ice that melts laterally - fside , & ! lateral heat flux (W/m^2) sst , & ! sea surface temperature (C) Tf , & ! freezing temperature (C) Tbot , & ! ice bottom surface temperature (deg C) @@ -2227,7 +2289,7 @@ subroutine icepack_step_therm1(dt, & frz_onset ! day of year that freezing begins (congel or frazil) real (kind=dbl_kind), intent(out), optional :: & - wlat ! lateral melt rate (m/s) + wlat ! lateral melt rate (m/s) real (kind=dbl_kind), intent(inout), optional :: & fswthru_vdr , & ! vis dir shortwave penetrating to ocean (W/m^2) @@ -2261,6 +2323,9 @@ subroutine icepack_step_therm1(dt, & H2_18O_ocn , & ! ocean concentration of H2_18O (kg/kg) zlvs ! atm level height for scalars (if different than zlvl) (m) + real (kind=dbl_kind), dimension(:,:), intent(in), optional :: & + afsdn ! afsd tracer + real (kind=dbl_kind), dimension(:), intent(inout) :: & aicen_init , & ! fractional area of ice vicen_init , & ! volume per unit area of ice (m) @@ -2276,6 +2341,7 @@ subroutine icepack_step_therm1(dt, & ipnd , & ! melt pond refrozen lid thickness (m) iage , & ! volume-weighted ice age FY , & ! area-weighted first-year ice area + rsiden , & ! fraction of ice that melts laterally fsurfn , & ! net flux to top surface, excluding fcondtop fcondtopn , & ! downward cond flux at top surface (W m-2) fcondbotn , & ! downward cond flux at bottom surface (W m-2) @@ -2420,8 +2486,13 @@ subroutine icepack_step_therm1(dt, & return endif if (tr_fsd) then - if (.not.(present(wlat))) then - call icepack_warnings_add(subname//' error in FSD arguments, tr_fsd=T') + if (.not.present(afsdn)) then + call icepack_warnings_add(subname//' error missing afsdn argument, tr_fsd=T') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + return + endif + if (size(afsdn,dim=1) /= nfsd .or. size(afsdn,dim=2) /= ncat) then + call icepack_warnings_add(subname//' error size of afsdn argument, tr_fsd=T') call icepack_warnings_setabort(.true.,__FILE__,__LINE__) return endif @@ -2492,7 +2563,7 @@ subroutine icepack_step_therm1(dt, & endif !----------------------------------------------------------------- - ! Adjust frzmlt to account for ice-ocean heat fluxes since last + ! Use frzmlt to account for ice-ocean heat fluxes since last ! call to coupler. ! Compute lateral and bottom heat fluxes. !----------------------------------------------------------------- @@ -2506,8 +2577,9 @@ subroutine icepack_step_therm1(dt, & fbot_xfer_type, & strocnxT, strocnyT, & Tbot, fbot, & - rside, Cdn_ocn, & - fside, wlat) + rsiden, Cdn_ocn, & + wlat, aicen, & + afsdn) if (icepack_warnings_aborted(subname)) return diff --git a/columnphysics/icepack_wavefracspec.F90 b/columnphysics/icepack_wavefracspec.F90 index 1beb7a234..34c4e448f 100644 --- a/columnphysics/icepack_wavefracspec.F90 +++ b/columnphysics/icepack_wavefracspec.F90 @@ -182,7 +182,6 @@ end function get_dafsd_wave subroutine icepack_step_wavefracture(wave_spec_type, & dt, nfreq, & aice, vice, aicen, & - floe_rad_l, floe_rad_c, & wave_spectrum, wavefreq, dwavefreq, & trcrn, d_afsd_wave) @@ -201,10 +200,6 @@ subroutine icepack_step_wavefracture(wave_spec_type, & real (kind=dbl_kind), dimension(ncat), intent(in) :: & aicen ! ice area fraction (categories) - real(kind=dbl_kind), dimension(:), intent(in) :: & - floe_rad_l, & ! fsd size lower bound in m (radius) - floe_rad_c ! fsd size bin centre in m (radius) - real (kind=dbl_kind), dimension (:), intent(in) :: & wavefreq, & ! wave frequencies (s^-1) dwavefreq ! wave frequency bin widths (s^-1) @@ -243,6 +238,9 @@ subroutine icepack_step_wavefracture(wave_spec_type, & afsd_tmp , & ! tracer array d_afsd_tmp ! change + real (kind=dbl_kind) :: & + local_sig_ht + character(len=*),parameter :: & subname='(icepack_step_wavefracture)' @@ -256,15 +254,15 @@ subroutine icepack_step_wavefracture(wave_spec_type, & ! if all ice is not in first floe size category if (.NOT. ALL(trcrn(nt_fsd,:).ge.c1-puny)) then - + local_sig_ht = c4*SQRT(SUM(wave_spectrum(:)*dwavefreq(:))) ! do not try to fracture for minimal ice concentration or zero wave spectrum - if ((aice > p01).and.(MAXVAL(wave_spectrum(:)) > puny)) then +! if ((aice > p01).and.(MAXVAL(wave_spectrum(:)) > puny)) then + if ((aice > p01).and.(local_sig_ht>0.1_dbl_kind)) then hbar = vice / aice ! calculate fracture histogram call wave_frac(nfreq, wave_spec_type, & - floe_rad_l, floe_rad_c, & wavefreq, dwavefreq, & hbar, wave_spectrum, fracture_hist) @@ -393,7 +391,6 @@ end subroutine icepack_step_wavefracture ! authors: 2018 Lettie Roach, NIWA/VUW subroutine wave_frac(nfreq, wave_spec_type, & - floe_rad_l, floe_rad_c, & wavefreq, dwavefreq, & hbar, spec_efreq, frac_local) @@ -406,10 +403,6 @@ subroutine wave_frac(nfreq, wave_spec_type, & real (kind=dbl_kind), intent(in) :: & hbar ! mean ice thickness (m) - real(kind=dbl_kind), dimension(:), intent(in) :: & - floe_rad_l, & ! fsd size lower bound in m (radius) - floe_rad_c ! fsd size bin centre in m (radius) - real (kind=dbl_kind), dimension (:), intent(in) :: & wavefreq, & ! wave frequencies (s^-1) dwavefreq, & ! wave frequency bin widths (s^-1) diff --git a/configuration/driver/icedrv_InitMod.F90 b/configuration/driver/icedrv_InitMod.F90 index c45d28022..ba1b1de6f 100644 --- a/configuration/driver/icedrv_InitMod.F90 +++ b/configuration/driver/icedrv_InitMod.F90 @@ -31,16 +31,14 @@ module icedrv_InitMod subroutine icedrv_initialize - use icedrv_arrays_column, only: hin_max, c_hi_range - use icedrv_arrays_column, only: floe_rad_l, floe_rad_c, & - floe_binwidth, c_fsd_range + use icedrv_arrays_column, only: hin_max, c_hi_range, floe_rad_c use icedrv_calendar, only: dt, time, istep, istep1, & init_calendar, calendar use icepack_intfc, only: icepack_init_itd, icepack_init_itd_hist use icepack_intfc, only: icepack_init_fsd_bounds use icepack_intfc, only: icepack_init_snow use icepack_intfc, only: icepack_warnings_flush - use icedrv_domain_size, only: ncat, nfsd + use icedrv_domain_size, only: ncat ! use icedrv_diagnostics, only: icedrv_diagnostics_debug use icedrv_flux, only: init_coupler_flux, init_history_therm, & init_flux_atm_ocn @@ -98,12 +96,7 @@ subroutine icedrv_initialize endif if (tr_fsd) then - call icepack_init_fsd_bounds( & - floe_rad_l=floe_rad_l, & ! fsd size lower bound in m (radius) - floe_rad_c=floe_rad_c, & ! fsd size bin centre in m (radius) - floe_binwidth=floe_binwidth, & ! fsd size bin width in m (radius) - c_fsd_range=c_fsd_range , & ! string for history output - write_diags=.true.) + call icepack_init_fsd_bounds(floe_rad_c_out=floe_rad_c, write_diags=.true. ) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted(subname)) then call icedrv_system_abort(file=__FILE__,line=__LINE__) diff --git a/configuration/driver/icedrv_arrays_column.F90 b/configuration/driver/icedrv_arrays_column.F90 index b55f129f4..dbe1ab56a 100644 --- a/configuration/driver/icedrv_arrays_column.F90 +++ b/configuration/driver/icedrv_arrays_column.F90 @@ -221,29 +221,22 @@ module icedrv_arrays_column ! floe size distribution real(kind=dbl_kind), dimension(nfsd), public :: & - floe_rad_l, & ! fsd size lower bound in m (radius) - floe_rad_c, & ! fsd size bin centre in m (radius) - floe_binwidth ! fsd size bin width in m (radius) + floe_rad_c ! fsd size bin centre in m (radius) real (kind=dbl_kind), dimension (nx), public :: & - wave_sig_ht ! significant height of waves (m) + wave_sig_ht ! significant height of waves (m) real (kind=dbl_kind), dimension (nfreq), public :: & - wavefreq, & ! wave frequencies - dwavefreq ! wave frequency bin widths + wavefreq, & ! wave frequencies + dwavefreq ! wave frequency bin widths real (kind=dbl_kind), dimension (nx,nfreq), public :: & - wave_spectrum ! wave spectrum + wave_spectrum ! wave spectrum real (kind=dbl_kind), dimension (nx,nfsd), public :: & ! change in floe size distribution due to processes d_afsd_newi, d_afsd_latg, d_afsd_latm, d_afsd_wave, d_afsd_weld - character (len=35), public, dimension(nfsd) :: & - c_fsd_range ! fsd floe_rad bounds (m) - - - !======================================================================= end module icedrv_arrays_column diff --git a/configuration/driver/icedrv_flux.F90 b/configuration/driver/icedrv_flux.F90 index 39c090818..321a84912 100644 --- a/configuration/driver/icedrv_flux.F90 +++ b/configuration/driver/icedrv_flux.F90 @@ -248,6 +248,7 @@ module icedrv_flux real (kind=dbl_kind), & dimension (nx,ncat), public :: & + rsiden, & ! fraction of ice that melts laterally fsurfn, & ! category fsurf fcondtopn,& ! category fcondtop fcondbotn,& ! category fcondbot @@ -272,8 +273,6 @@ module icedrv_flux !----------------------------------------------------------------- real (kind=dbl_kind), dimension (nx), public :: & - rside , & ! fraction of ice that melts laterally - fside , & ! lateral heat flux (W/m^2) wlat , & ! lateral melt rate (m/s) fsw , & ! incoming shortwave radiation (W/m^2) coszen , & ! cosine solar zenith angle, < 0 for sun below horizon diff --git a/configuration/driver/icedrv_forcing.F90 b/configuration/driver/icedrv_forcing.F90 index b3f360f7a..98e390e22 100644 --- a/configuration/driver/icedrv_forcing.F90 +++ b/configuration/driver/icedrv_forcing.F90 @@ -1150,6 +1150,7 @@ subroutine get_wave_spec ! wave spectrum and frequencies ! get hardwired frequency bin info and a dummy wave spectrum profile + call icepack_init_wave(nfreq=nfreq, & wave_spectrum_profile=wave_spectrum_profile, & wavefreq=wavefreq, dwavefreq=dwavefreq) diff --git a/configuration/driver/icedrv_init.F90 b/configuration/driver/icedrv_init.F90 index ddcd8b2f6..f342d74fe 100644 --- a/configuration/driver/icedrv_init.F90 +++ b/configuration/driver/icedrv_init.F90 @@ -1296,7 +1296,6 @@ subroutine set_state_var (nx, & use icedrv_arrays_column, only: hin_max use icedrv_domain_size, only: nilyr, nslyr, max_ntrcr, ncat, nfsd - use icedrv_arrays_column, only: floe_rad_c, floe_binwidth integer (kind=int_kind), intent(in) :: & nx ! number of grid cells @@ -1437,8 +1436,6 @@ subroutine set_state_var (nx, & ! floe size distribution if (tr_fsd) call icepack_init_fsd(ice_ic=ice_ic, & - floe_rad_c=floe_rad_c, & - floe_binwidth=floe_binwidth, & afsd=trcrn(i,nt_fsd:nt_fsd+nfsd-1,n)) ! surface temperature trcrn(i,nt_Tsfc,n) = Tsfc ! deg C @@ -1507,8 +1504,6 @@ subroutine set_state_var (nx, & qin=qin(:), qsn=qsn(:)) ! floe size distribution if (tr_fsd) call icepack_init_fsd(ice_ic=ice_ic, & - floe_rad_c=floe_rad_c, & - floe_binwidth=floe_binwidth, & afsd=trcrn(i,nt_fsd:nt_fsd+nfsd-1,n)) ! surface temperature diff --git a/configuration/driver/icedrv_step.F90 b/configuration/driver/icedrv_step.F90 index f99d47e4c..13f6f2f83 100644 --- a/configuration/driver/icedrv_step.F90 +++ b/configuration/driver/icedrv_step.F90 @@ -112,8 +112,8 @@ subroutine step_therm1 (dt) use icedrv_arrays_column, only: fswthrun, fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf use icedrv_arrays_column, only: meltsliqn, meltsliq use icedrv_calendar, only: yday - use icedrv_domain_size, only: ncat, nilyr, nslyr, n_aero, n_iso, nx - use icedrv_flux, only: frzmlt, sst, Tf, strocnxT, strocnyT, rside, fside, wlat, & + use icedrv_domain_size, only: ncat, nilyr, nslyr, n_aero, n_iso, nfsd, nx + use icedrv_flux, only: frzmlt, sst, Tf, strocnxT, strocnyT, rsiden, wlat, & fbot, Tbot, Tsnice use icedrv_flux, only: meltsn, melttn, meltbn, congeln, snoicen, uatm, vatm use icedrv_flux, only: wind, rhoa, potT, Qa, Qa_iso, zlvl, strax, stray, flatn @@ -151,7 +151,7 @@ subroutine step_therm1 (dt) integer (kind=int_kind) :: & ntrcr, nt_apnd, nt_hpnd, nt_ipnd, nt_alvl, nt_vlvl, nt_Tsfc, & - nt_iage, nt_FY, nt_qice, nt_sice, nt_qsno, & + nt_iage, nt_FY, nt_qice, nt_sice, nt_qsno, nt_fsd, & nt_aero, nt_isosno, nt_isoice, nt_rsnw, nt_smice, nt_smliq logical (kind=log_kind) :: & @@ -202,7 +202,7 @@ subroutine step_therm1 (dt) nt_qice_out=nt_qice, nt_sice_out=nt_sice, & nt_aero_out=nt_aero, nt_qsno_out=nt_qsno, & nt_rsnw_out=nt_rsnw, nt_smice_out=nt_smice, nt_smliq_out=nt_smliq, & - nt_isosno_out=nt_isosno, nt_isoice_out=nt_isoice) + nt_isosno_out=nt_isosno, nt_isoice_out=nt_isoice, nt_fsd_out=nt_fsd) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & file=__FILE__,line= __LINE__) @@ -325,7 +325,7 @@ subroutine step_therm1 (dt) strocnxT = strocnxT(i), strocnyT = strocnyT(i), & fbot = fbot(i), frzmlt = frzmlt(i), & Tbot = Tbot(i), Tsnice = Tsnice(i), & - rside = rside(i), fside = fside(i), & + rsiden = rsiden(i,:), & wlat = wlat(i), & fsnow = fsnow(i), frain = frain(i), & fpond = fpond(i), fsloss = fsloss(i), & @@ -370,6 +370,7 @@ subroutine step_therm1 (dt) snoice = snoice(i), snoicen = snoicen(i,:), & dsnow = dsnow(i), dsnown = dsnown(i,:), & meltsliqn= meltsliqn(i,:), & + afsdn = trcrn (i,nt_fsd:nt_fsd+nfsd-1,:), & lmask_n = lmask_n(i), lmask_s = lmask_s(i), & mlt_onset=mlt_onset(i), frz_onset = frz_onset(i), & yday = yday, prescribed_ice = prescribed_ice) @@ -429,14 +430,13 @@ subroutine step_therm2 (dt) use icedrv_arrays_column, only: hin_max, ocean_bio, & wave_sig_ht, wave_spectrum, & wavefreq, dwavefreq, & - floe_rad_c, floe_binwidth, & d_afsd_latg, d_afsd_newi, d_afsd_latm, d_afsd_weld use icedrv_arrays_column, only: first_ice use icedrv_calendar, only: yday use icedrv_domain_size, only: ncat, nilyr, nslyr, n_aero, nblyr, & - nx, nfsd + nx use icedrv_flux, only: fresh, frain, fpond, frzmlt, frazil, frz_onset - use icedrv_flux, only: fsalt, Tf, sss, salinz, fhocn, rside, fside, wlat + use icedrv_flux, only: fsalt, Tf, sss, salinz, fhocn, rsiden, wlat use icedrv_flux, only: meltl, frazil_diag, flux_bio, faero_ocn, fiso_ocn use icedrv_flux, only: HDO_ocn, H2_16O_ocn, H2_18O_ocn use icedrv_init, only: tmask @@ -497,9 +497,9 @@ subroutine step_therm2 (dt) n_trcr_strata=n_trcr_strata(1:ntrcr), & nt_strata=nt_strata(1:ntrcr,:), & Tf=Tf(i), sss=sss(i), & - salinz=salinz(i,:), fside=fside(i), & + salinz=salinz(i,:), & wlat=wlat(i), & - rside=rside(i), meltl=meltl(i), & + rsiden=rsiden(i,:), meltl=meltl(i), & frzmlt=frzmlt(i), frazil=frazil(i), & frain=frain(i), fpond=fpond(i), & fresh=fresh(i), fsalt=fsalt(i), & @@ -522,9 +522,7 @@ subroutine step_therm2 (dt) d_afsd_latg=d_afsd_latg(i,:), & d_afsd_newi=d_afsd_newi(i,:), & d_afsd_latm=d_afsd_latm(i,:), & - d_afsd_weld=d_afsd_weld(i,:), & - floe_rad_c=floe_rad_c(:), & - floe_binwidth=floe_binwidth(:)) + d_afsd_weld=d_afsd_weld(i,:)) endif ! tmask @@ -654,8 +652,8 @@ end subroutine update_state subroutine step_dyn_wave (dt) use icedrv_arrays_column, only: wave_spectrum, wave_sig_ht, & - d_afsd_wave, floe_rad_l, floe_rad_c, wavefreq, dwavefreq - use icedrv_domain_size, only: ncat, nfsd, nfreq, nx + d_afsd_wave, wavefreq, dwavefreq + use icedrv_domain_size, only: ncat, nfreq, nx use icedrv_state, only: trcrn, aicen, aice, vice use icepack_intfc, only: icepack_step_wavefracture @@ -685,11 +683,9 @@ subroutine step_dyn_wave (dt) aice = aice (i), & vice = vice (i), & aicen = aicen (i,:), & - floe_rad_l = floe_rad_l (:), & - floe_rad_c = floe_rad_c (:), & wave_spectrum = wave_spectrum(i,:), & - wavefreq = wavefreq (:), & - dwavefreq = dwavefreq (:), & + wavefreq = wavefreq (:), & + dwavefreq = dwavefreq (:), & trcrn = trcrn (i,:,:), & d_afsd_wave = d_afsd_wave (i,:)) end do ! i diff --git a/configuration/scripts/options/set_nml.swccsm3 b/configuration/scripts/options/set_nml.swccsm3 index ae4d64d96..4ec03fddb 100644 --- a/configuration/scripts/options/set_nml.swccsm3 +++ b/configuration/scripts/options/set_nml.swccsm3 @@ -1,3 +1,4 @@ +ktherm = 1 shortwave = 'ccsm3' albedo_type = 'ccsm3' calc_tsfc = .true. diff --git a/doc/source/user_guide/interfaces.include b/doc/source/user_guide/interfaces.include index ae640d1bf..b41f6055d 100644 --- a/doc/source/user_guide/interfaces.include +++ b/doc/source/user_guide/interfaces.include @@ -142,22 +142,22 @@ icepack_init_fsd_bounds ! authors: Lettie Roach, NIWA/VUW and C. M. Bitz, UW subroutine icepack_init_fsd_bounds( & - floe_rad_l, & ! fsd size lower bound in m (radius) - floe_rad_c, & ! fsd size bin centre in m (radius) - floe_binwidth, & ! fsd size bin width in m (radius) - c_fsd_range, & ! string for history output - write_diags ) ! flag for writing diagnostics + floe_rad_l_out, & ! fsd size lower bound in m (radius) + floe_rad_c_out, & ! fsd size bin centre in m (radius) + floe_binwidth_out, & ! fsd size bin width in m (radius) + c_fsd_range_out, & ! string for history output + write_diags) ! flag for writing diagnostics - real(kind=dbl_kind), dimension(:), intent(inout) :: & - floe_rad_l, & ! fsd size lower bound in m (radius) - floe_rad_c, & ! fsd size bin centre in m (radius) - floe_binwidth ! fsd size bin width in m (radius) + real(kind=dbl_kind), dimension(:), intent(out), optional :: & + floe_rad_l_out, & ! fsd size lower bound in m (radius) + floe_rad_c_out, & ! fsd size bin centre in m (radius) + floe_binwidth_out ! fsd size bin width in m (radius) - character (len=35), intent(out) :: & - c_fsd_range(nfsd) ! string for history output + character (len=35), dimension(:), intent(out), optional :: & + c_fsd_range_out ! string for history output logical (kind=log_kind), intent(in), optional :: & - write_diags ! write diags flag + write_diags ! write diags flag @@ -172,18 +172,11 @@ icepack_init_fsd ! ! authors: Lettie Roach, NIWA/VUW - subroutine icepack_init_fsd(ice_ic, & - floe_rad_c, & ! fsd size bin centre in m (radius) - floe_binwidth, & ! fsd size bin width in m (radius) - afsd) ! floe size distribution tracer + subroutine icepack_init_fsd(ice_ic, afsd) ! floe size distribution tracer character(len=char_len_long), intent(in) :: & ice_ic ! method of ice cover initialization - real(kind=dbl_kind), dimension(:), intent(inout) :: & - floe_rad_c, & ! fsd size bin centre in m (radius) - floe_binwidth ! fsd size bin width in m (radius) - real (kind=dbl_kind), dimension (:), intent(inout) :: & afsd ! floe size tracer: fraction distribution of floes @@ -2253,8 +2246,8 @@ icepack_step_therm2 nt_strata, & Tf, sss, & salinz, & - rside, meltl, & - fside, wlat, & + rsiden, meltl, & + wlat, & frzmlt, frazil, & frain, fpond, & fresh, fsalt, & @@ -2271,8 +2264,7 @@ icepack_step_therm2 wavefreq, & dwavefreq, & d_afsd_latg, d_afsd_newi, & - d_afsd_latm, d_afsd_weld, & - floe_rad_c, floe_binwidth) + d_afsd_latm, d_afsd_weld) use icepack_parameters, only: icepack_init_parameters @@ -2286,7 +2278,6 @@ icepack_step_therm2 dt , & ! time step Tf , & ! freezing temperature (C) sss , & ! sea surface salinity (ppt) - rside , & ! fraction of ice that melts laterally frzmlt ! freezing/melting potential (W/m^2) integer (kind=int_kind), dimension (:), intent(in) :: & @@ -2301,13 +2292,13 @@ icepack_step_therm2 nt_strata ! indices of underlying tracer layers real (kind=dbl_kind), dimension(:), intent(in) :: & + rsiden , & ! fraction of ice that melts laterally salinz , & ! initial salinity profile ocean_bio ! ocean concentration of biological tracer real (kind=dbl_kind), intent(inout) :: & aice , & ! sea ice concentration aice0 , & ! concentration of open water - fside , & ! lateral heat flux (W/m^2) frain , & ! rainfall rate (kg/m^2 s) fpond , & ! fresh water flux to ponds (kg/m^2/s) fresh , & ! fresh water flux to ocean (kg/m^2/s) @@ -2370,10 +2361,6 @@ icepack_step_therm2 d_afsd_latm, & ! lateral melt d_afsd_weld ! welding - real (kind=dbl_kind), dimension (:), intent(in), optional :: & - floe_rad_c, & ! fsd size bin centre in m (radius) - floe_binwidth ! fsd size bin width in m (radius) - icepack_therm_shared.F90 @@ -2563,8 +2550,8 @@ icepack_step_therm1 strocnxT , strocnyT , & fbot , & Tbot , Tsnice , & - frzmlt , rside , & - fside , wlat , & + frzmlt , rsiden , & + wlat , & fsnow , frain , & fpond , fsloss , & fsurf , fsurfn , & @@ -2611,7 +2598,7 @@ icepack_step_therm1 lmask_n , lmask_s , & mlt_onset , frz_onset , & yday , prescribed_ice, & - zlvs) + zlvs , afsdn) real (kind=dbl_kind), intent(in) :: & dt , & ! time step @@ -2687,8 +2674,6 @@ icepack_step_therm1 strocnyT , & ! ice-ocean stress, y-direction fbot , & ! ice-ocean heat flux at bottom surface (W/m^2) frzmlt , & ! freezing/melting potential (W/m^2) - rside , & ! fraction of ice that melts laterally - fside , & ! lateral heat flux (W/m^2) sst , & ! sea surface temperature (C) Tf , & ! freezing temperature (C) Tbot , & ! ice bottom surface temperature (deg C) @@ -2701,7 +2686,7 @@ icepack_step_therm1 frz_onset ! day of year that freezing begins (congel or frazil) real (kind=dbl_kind), intent(out), optional :: & - wlat ! lateral melt rate (m/s) + wlat ! lateral melt rate (m/s) real (kind=dbl_kind), intent(inout), optional :: & fswthru_vdr , & ! vis dir shortwave penetrating to ocean (W/m^2) @@ -2735,6 +2720,9 @@ icepack_step_therm1 H2_18O_ocn , & ! ocean concentration of H2_18O (kg/kg) zlvs ! atm level height for scalars (if different than zlvl) (m) + real (kind=dbl_kind), dimension(:,:), intent(in), optional :: & + afsdn ! afsd tracer + real (kind=dbl_kind), dimension(:), intent(inout) :: & aicen_init , & ! fractional area of ice vicen_init , & ! volume per unit area of ice (m) @@ -2750,6 +2738,7 @@ icepack_step_therm1 ipnd , & ! melt pond refrozen lid thickness (m) iage , & ! volume-weighted ice age FY , & ! area-weighted first-year ice area + rsiden , & ! fraction of ice that melts laterally fsurfn , & ! net flux to top surface, excluding fcondtop fcondtopn , & ! downward cond flux at top surface (W m-2) fcondbotn , & ! downward cond flux at bottom surface (W m-2) @@ -3380,7 +3369,6 @@ icepack_step_wavefracture subroutine icepack_step_wavefracture(wave_spec_type, & dt, nfreq, & aice, vice, aicen, & - floe_rad_l, floe_rad_c, & wave_spectrum, wavefreq, dwavefreq, & trcrn, d_afsd_wave) @@ -3399,10 +3387,6 @@ icepack_step_wavefracture real (kind=dbl_kind), dimension(ncat), intent(in) :: & aicen ! ice area fraction (categories) - real(kind=dbl_kind), dimension(:), intent(in) :: & - floe_rad_l, & ! fsd size lower bound in m (radius) - floe_rad_c ! fsd size bin centre in m (radius) - real (kind=dbl_kind), dimension (:), intent(in) :: & wavefreq, & ! wave frequencies (s^-1) dwavefreq ! wave frequency bin widths (s^-1) From 8c3f26a45c14896957529e0f2bd2644a03012973 Mon Sep 17 00:00:00 2001 From: "David A. Bailey" Date: Fri, 15 Nov 2024 15:03:32 -0700 Subject: [PATCH 29/30] Make dsnow and dsnown optional (#506) This is the icepack part of making both dsnow and dsnown optional. Later I can add some diagnostics for these in CICE. --- columnphysics/icepack_therm_vertical.F90 | 28 +++++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/columnphysics/icepack_therm_vertical.F90 b/columnphysics/icepack_therm_vertical.F90 index bf96096eb..7ec9bf47c 100644 --- a/columnphysics/icepack_therm_vertical.F90 +++ b/columnphysics/icepack_therm_vertical.F90 @@ -2361,12 +2361,14 @@ subroutine icepack_step_therm1(dt, & melttn , & ! top ice melt (m) meltbn , & ! bottom ice melt (m) congeln , & ! congelation ice growth (m) - snoicen , & ! snow-ice growth (m) - dsnown ! change in snow thickness (m/step-->cm/day) + snoicen ! snow-ice growth (m) real (kind=dbl_kind), dimension(:), intent(in) :: & fswthrun ! SW through ice to ocean (W/m^2) + real (kind=dbl_kind), dimension(:), intent(inout), optional :: & + dsnown ! change in snow thickness (m/step-->cm/day) + real (kind=dbl_kind), dimension(:), intent(in), optional :: & fswthrun_vdr , & ! vis dir SW through ice to ocean (W/m^2) fswthrun_vdf , & ! vis dif SW through ice to ocean (W/m^2) @@ -2442,6 +2444,8 @@ subroutine icepack_step_therm1(dt, & l_fswthrun_vdf, & ! vis dif SW local n ice to ocean (W/m^2) l_fswthrun_idr, & ! nir dir SW local n ice to ocean (W/m^2) l_fswthrun_idf, & ! nir dif SW local n ice to ocean (W/m^2) + l_dsnow, & ! local snow change + l_dsnown, & ! local snow change category l_meltsliq ! mass of snow melt local (kg/m^2) real (kind=dbl_kind) :: & @@ -2485,6 +2489,12 @@ subroutine icepack_step_therm1(dt, & call icepack_warnings_setabort(.true.,__FILE__,__LINE__) return endif + if ((present(dsnow) .and. .not.present(dsnown)) .or. & + (present(dsnown) .and. .not.present(dsnow))) then + call icepack_warnings_add(subname//' error in dsnow arguments') + call icepack_warnings_setabort(.true.,__FILE__,__LINE__) + return + endif if (tr_fsd) then if (.not.present(afsdn)) then call icepack_warnings_add(subname//' error missing afsdn argument, tr_fsd=T') @@ -2509,6 +2519,8 @@ subroutine icepack_step_therm1(dt, & l_meltsliq = c0 l_meltsliqn = c0 + l_dsnow = c0 + if (present(dsnow)) l_dsnow = dsnow ! solid and liquid components of snow mass massicen(:,:) = c0 @@ -2589,7 +2601,8 @@ subroutine icepack_step_therm1(dt, & meltbn (n) = c0 congeln(n) = c0 snoicen(n) = c0 - dsnown (n) = c0 + l_dsnown = c0 + if (present(dsnown)) dsnown(n) = c0 Trefn = c0 Qrefn = c0 @@ -2714,8 +2727,8 @@ subroutine icepack_step_therm1(dt, & smice=smice, massice=massicen (:,n), & smliq=smliq, massliq=massliqn (:,n), & congel=congeln (n), snoice=snoicen (n), & - mlt_onset=mlt_onset, frz_onset=frz_onset, & - yday=yday, dsnow=dsnown (n), & + mlt_onset=mlt_onset, frz_onset=frz_onset , & + yday=yday, dsnow=l_dsnown , & prescribed_ice=prescribed_ice) if (icepack_warnings_aborted(subname)) then @@ -2903,7 +2916,7 @@ subroutine icepack_step_therm1(dt, & meltbn=meltbn (n), congeln=congeln(n),& meltt=meltt, melts=melts, & meltb=meltb, snoicen=snoicen(n),& - dsnow=dsnow, dsnown=dsnown(n), & + dsnow=l_dsnow, dsnown=l_dsnown, & congel=congel, snoice=snoice, & meltsliq=l_meltsliq, & meltsliqn=l_meltsliqn(n), & @@ -2919,6 +2932,8 @@ subroutine icepack_step_therm1(dt, & endif + if (present(dsnown )) dsnown(n) = l_dsnown + enddo ! ncat !----------------------------------------------------------------- @@ -2944,6 +2959,7 @@ subroutine icepack_step_therm1(dt, & if (present(meltsliqn )) meltsliqn = l_meltsliqn if (present(meltsliq )) meltsliq = l_meltsliq + if (present(dsnow )) dsnow = l_dsnow !----------------------------------------------------------------- ! Calculate ponds from the topographic scheme From 3792520561cf9419082ef41f9f0dffd03edf2e43 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Fri, 15 Nov 2024 15:15:25 -0800 Subject: [PATCH 30/30] Update version number to 1.5.0 (#507) Update interface documentation Clean up redundant dsnown line in icepack_therm_vertical, see #506. --- columnphysics/icepack_therm_vertical.F90 | 1 - columnphysics/version.txt | 2 +- doc/source/conf.py | 4 ++-- doc/source/user_guide/interfaces.include | 6 ++++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/columnphysics/icepack_therm_vertical.F90 b/columnphysics/icepack_therm_vertical.F90 index 7ec9bf47c..a0aa6b84a 100644 --- a/columnphysics/icepack_therm_vertical.F90 +++ b/columnphysics/icepack_therm_vertical.F90 @@ -2602,7 +2602,6 @@ subroutine icepack_step_therm1(dt, & congeln(n) = c0 snoicen(n) = c0 l_dsnown = c0 - if (present(dsnown)) dsnown(n) = c0 Trefn = c0 Qrefn = c0 diff --git a/columnphysics/version.txt b/columnphysics/version.txt index 7efd5d798..f46731dc6 100644 --- a/columnphysics/version.txt +++ b/columnphysics/version.txt @@ -1 +1 @@ -ICEPACK 1.4.1 +ICEPACK 1.5.0 diff --git a/doc/source/conf.py b/doc/source/conf.py index 49c6e2c42..ba2e04715 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -63,9 +63,9 @@ # built documents. # # The short X.Y version. -version = u'1.4.1' +version = u'1.5.0' # The full version, including alpha/beta/rc tags. -version = u'1.4.1' +version = u'1.5.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/user_guide/interfaces.include b/doc/source/user_guide/interfaces.include index b41f6055d..b28eff1a7 100644 --- a/doc/source/user_guide/interfaces.include +++ b/doc/source/user_guide/interfaces.include @@ -2758,12 +2758,14 @@ icepack_step_therm1 melttn , & ! top ice melt (m) meltbn , & ! bottom ice melt (m) congeln , & ! congelation ice growth (m) - snoicen , & ! snow-ice growth (m) - dsnown ! change in snow thickness (m/step-->cm/day) + snoicen ! snow-ice growth (m) real (kind=dbl_kind), dimension(:), intent(in) :: & fswthrun ! SW through ice to ocean (W/m^2) + real (kind=dbl_kind), dimension(:), intent(inout), optional :: & + dsnown ! change in snow thickness (m/step-->cm/day) + real (kind=dbl_kind), dimension(:), intent(in), optional :: & fswthrun_vdr , & ! vis dir SW through ice to ocean (W/m^2) fswthrun_vdf , & ! vis dif SW through ice to ocean (W/m^2)