From d95a4f35ee7800af0bacbd8a61359f8ebe104519 Mon Sep 17 00:00:00 2001 From: TRasmussen <33480590+TillRasmussen@users.noreply.github.com> Date: Tue, 3 Nov 2020 18:55:10 +0100 Subject: [PATCH 01/18] Add DMI Cray XC50 hpc (freya) to machines. Based on Banting (#528) * Add DMI Cray XC50 hpc (freya) to machines. Based on Banting * separation of Banting and Freya * Removed depreciated cpp and added gnu to freya --- configuration/scripts/cice.batch.csh | 8 +++ configuration/scripts/cice.launch.csh | 12 ++++ .../scripts/machines/Macros.freya_gnu | 40 +++++++++++ .../scripts/machines/Macros.freya_intel | 69 +++++++++++++++++++ configuration/scripts/machines/env.freya_gnu | 39 +++++++++++ .../scripts/machines/env.freya_intel | 38 ++++++++++ 6 files changed, 206 insertions(+) create mode 100644 configuration/scripts/machines/Macros.freya_gnu create mode 100644 configuration/scripts/machines/Macros.freya_intel create mode 100755 configuration/scripts/machines/env.freya_gnu create mode 100755 configuration/scripts/machines/env.freya_intel diff --git a/configuration/scripts/cice.batch.csh b/configuration/scripts/cice.batch.csh index 54a2be711..d6f78313f 100755 --- a/configuration/scripts/cice.batch.csh +++ b/configuration/scripts/cice.batch.csh @@ -193,6 +193,14 @@ cat >> ${jobfile} << EOFB #PBS -l walltime=${batchtime} EOFB +else if (${ICE_MACHINE} =~ freya* ) then +cat >> ${jobfile} << EOFB +#PBS -N ${ICE_CASENAME} +#PBS -j oe +#PBS -l select=${nnodes}:ncpus=${corespernode}:mpiprocs=${taskpernodelimit}:ompthreads=${nthrds} +#PBS -l walltime=${batchtime} +EOFB + else if (${ICE_MACHINE} =~ hera*) then cat >> ${jobfile} << EOFB #SBATCH -J ${ICE_CASENAME} diff --git a/configuration/scripts/cice.launch.csh b/configuration/scripts/cice.launch.csh index dfbffd6ab..a05b3a9d3 100755 --- a/configuration/scripts/cice.launch.csh +++ b/configuration/scripts/cice.launch.csh @@ -141,6 +141,18 @@ aprun -n ${ntasks} -N ${taskpernodelimit} -d ${nthrds} ./cice >&! \$ICE_RUNLOG_F EOFR endif +#======= +else if (${ICE_MACHINE} =~ freya*) then +if (${ICE_COMMDIR} =~ serial*) then +cat >> ${jobfile} << EOFR +aprun -n 1 -N 1 -d 1 ./cice >&! \$ICE_RUNLOG_FILE +EOFR +else +cat >> ${jobfile} << EOFR +aprun -n ${ntasks} -N ${taskpernodelimit} -d ${nthrds} ./cice >&! \$ICE_RUNLOG_FILE +EOFR +endif + #======= else if (${ICE_MACHINE} =~ hera*) then cat >> ${jobfile} << EOFR diff --git a/configuration/scripts/machines/Macros.freya_gnu b/configuration/scripts/machines/Macros.freya_gnu new file mode 100644 index 000000000..dafa4fd9b --- /dev/null +++ b/configuration/scripts/machines/Macros.freya_gnu @@ -0,0 +1,40 @@ +#============================================================================== +# Makefile macros for DMI freya +#============================================================================== +# For use with GNU compiler +#============================================================================== + +#INCLDIR := -I. -I/usr/include +#SLIBS := + +#--- Compiler/preprocessor --- +FC := ftn +CC := cc +CXX := CC +CPP := /usr/bin/cpp +CPPFLAGS := -P -traditional # ALLOW fortran double backslash "\\" +SCC := gcc +SFC := ftn + +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c -O2 +#-xHost + +FREEFLAGS := -ffree-form +FFLAGS := -fconvert=big-endian -fbacktrace -ffree-line-length-none +#-xHost + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -g -fcheck=bounds -finit-real=nan -fimplicit-none -ffpe-trap=invalid,zero,overflow +else + FFLAGS += -O2 #FROM BANTING + #FFLAGS := -O2 -ffloat-store -march=native -ffree-line-length-non # DMI BUILD +endif +LD:= $(FC) +LDFLAGS := $(FFLAGS) -v + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -fopenmp + CFLAGS += -fopenmp + FFLAGS += -fopenmp +endif diff --git a/configuration/scripts/machines/Macros.freya_intel b/configuration/scripts/machines/Macros.freya_intel new file mode 100644 index 000000000..f40ca4e23 --- /dev/null +++ b/configuration/scripts/machines/Macros.freya_intel @@ -0,0 +1,69 @@ +#============================================================================== +# Makefile macros for DMI Freya based on ECCC banting +#============================================================================== +# For use with intel compiler +#============================================================================== + +#INCLDIR := -I. -I/usr/include +#SLIBS := + +#--- Compiler/preprocessor --- +FC := ftn +CC := cc +CXX := CC +CPP := /usr/bin/cpp +CPPFLAGS := -P -traditional # ALLOW fortran double backslash "\\" +SCC := gcc +SFC := ftn + +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c -O2 -fp-model precise +# Additional flags +FIXEDFLAGS := -132 +FREEFLAGS := -FR +FFLAGS := -fp-model source -convert big_endian -assume byterecl -ftz -traceback -no-wrap-margin +#-xHost + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -g -check -fpe0 -ftrapuv -fp-model except -check noarg_temp_created +# -heap-arrays 1024 +else + FFLAGS += -O2 +endif +LD := $(FC) +LDFLAGS := $(FFLAGS) -v +#ifeq ($(ICE_BLDDEBUG), true) +#FFLAGS := -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created +#FFLAGS := -g -O0 -traceback -fp-model precise -fp-stack-check -fpe0 +#else +#FFLAGS := -r8 -i4 -O2 -align all -w -ftz -assume byterecl +# FFLAGS := -O2 -fp-model precise -assume byterecl -ftz -traceback -xHost +#endif +# Preprocessor flags +#CPPDEFS := -DLINUX $(ICE_CPPDEFS) + +# Linker flags + +# Additional flags + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -qopenmp + CFLAGS += -qopenmp + FFLAGS += -qopenmp +endif + +#--- NetCDF --- +#ifeq ($(IO_TYPE), netcdf) +# +#endif +# +#ifeq ($(IO_TYPE), netcdf_bin) +# CPPDEFS := $(CPPDEFS) -Dncdf +#endif + +### if using parallel I/O, load all 3 libraries. PIO must be first! +#ifeq ($(ICE_IOTYPE), pio) +# PIO_PATH:=/usr/projects/climate/SHARED_CLIMATE/software/conejo/pio/1.7.2/intel-13.0.1/openmpi-1.6.3/netcdf-3.6.3-parallel-netcdf-1.3.1/include +# INCLDIR += -I$(PIO_PATH) +# SLIBS := $(SLIBS) -L$(PIO_PATH) -lpio +#endif diff --git a/configuration/scripts/machines/env.freya_gnu b/configuration/scripts/machines/env.freya_gnu new file mode 100755 index 000000000..b655d6dd0 --- /dev/null +++ b/configuration/scripts/machines/env.freya_gnu @@ -0,0 +1,39 @@ +#!/bin/csh -f + +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source /opt/modules/default/init/csh # Initialize modules for csh + Clear environment +module rm PrgEnv-intel +module rm PrgEnv-cray +module rm PrgEnv-gnu +module add PrgEnv-gnu +#module load PrgEnv-intel # Intel compiler +#module load cray-mpich # MPI (Cray MPICH) +module add cray-netcdf # NetCDF +module add cray-hdf5 # HDF5 +#setenv HDF5_USE_FILE_LOCKING FALSE # necessary since data is on an NFS filesystem +setenv HDF5_USE_FILE_LOCKING FALSE # necessary since data is on an NFS filesystem + +endif + +setenv ICE_MACHINE_MACHNAME freya +setenv ICE_MACHINE_MACHINFO "Cray XC50, GNU Xeon Gold 6148 (Skylake) NOT SURE-TILL" +setenv ICE_MACHINE_ENVNAME gnu +setenv ICE_MACHINE_ENVINFO "gcc/7.2.0, cray-mpich/7.7.0, cray-netcdf/4.4.1.1.6" +setenv ICE_MACHINE_MAKE make +setenv ICE_MACHINE_WKDIR /data/${USER}/cice_original/run/ +setenv ICE_MACHINE_INPUTDATA /data/${USER}/cice_original/ +setenv ICE_MACHINE_BASELINE /data/${USER}/cice_original/dbaselines/ +setenv ICE_MACHINE_SUBMIT "qsub" +setenv ICE_MACHINE_TPNODE 36 # tasks per node +#setenv ICE_MACHINE_MAXRUNLENGTH 9 +setenv ICE_MACHINE_ACCT P0000000 +setenv ICE_MACHINE_QUEUE "development" +setenv ICE_MACHINE_BLDTHRDS 18 +setenv ICE_MACHINE_QSTAT "qstat " diff --git a/configuration/scripts/machines/env.freya_intel b/configuration/scripts/machines/env.freya_intel new file mode 100755 index 000000000..dcbc1f8ba --- /dev/null +++ b/configuration/scripts/machines/env.freya_intel @@ -0,0 +1,38 @@ +#!/bin/csh -f + +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source /opt/modules/default/init/csh # Initialize modules for csh +# Clear environment +module rm PrgEnv-intel +module rm PrgEnv-cray +module rm PrgEnv-gnu +module add PrgEnv-intel +#module load PrgEnv-intel # Intel compiler +#module load cray-mpich # MPI (Cray MPICH) +module add cray-netcdf # NetCDF +module add cray-hdf5 # HDF5 +#setenv HDF5_USE_FILE_LOCKING FALSE # necessary since data is on an NFS filesystem + +endif + +setenv ICE_MACHINE_MACHNAME freya +setenv ICE_MACHINE_MACHINFO "Cray XC50, Intel Xeon Gold 6148 (Skylake) NOT SURE-TILL" +setenv ICE_MACHINE_ENVNAME intel +setenv ICE_MACHINE_ENVINFO "Intel 18.0.0.128, cray-mpich/7.7.0, cray-netcdf/4.4.1.1.6" +setenv ICE_MACHINE_MAKE make +setenv ICE_MACHINE_WKDIR /data/${USER}/cice_original/run/ +setenv ICE_MACHINE_INPUTDATA /data/${USER}/cice_original/ +setenv ICE_MACHINE_BASELINE /data/${USER}/cice_original/dbaselines/ +setenv ICE_MACHINE_SUBMIT "qsub" +setenv ICE_MACHINE_TPNODE 36 # tasks per node +#setenv ICE_MACHINE_MAXRUNLENGTH 9 +setenv ICE_MACHINE_ACCT P0000000 +setenv ICE_MACHINE_QUEUE "development" +setenv ICE_MACHINE_BLDTHRDS 18 +setenv ICE_MACHINE_QSTAT "qstat " From 066070ecef5081f68313ab7b1185e4184640cef2 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Mon, 23 Nov 2020 17:49:50 -0800 Subject: [PATCH 02/18] Fix minor issues in documentation, key_ CPPs, bfbcomp return codes (#532) * Fix minor issues in documentation, key_ CPPs, bfbcomp return codes quickstart documentation points to porting (#529) check additional return codes in the bfbcomp tool (#524) fix undefined variable in ice_init output (#520) add documentation about aliases (#523) remove key_ CPPS, can be handled by passing communicator thru interface (#498) * update alias documentation --- cicecore/cicedynB/general/ice_init.F90 | 1 + .../comm/mpi/ice_communicate.F90 | 18 ------- .../scripts/tests/test_decomp.script | 10 +++- doc/source/intro/quickstart.rst | 10 ++-- doc/source/user_guide/ug_case_settings.rst | 4 -- doc/source/user_guide/ug_running.rst | 54 ++++++++++++++++--- 6 files changed, 63 insertions(+), 34 deletions(-) diff --git a/cicecore/cicedynB/general/ice_init.F90 b/cicecore/cicedynB/general/ice_init.F90 index fb9c45978..42a96ad78 100644 --- a/cicecore/cicedynB/general/ice_init.F90 +++ b/cicecore/cicedynB/general/ice_init.F90 @@ -1169,6 +1169,7 @@ subroutine input_data if (trim(grid_type) == 'tripole') then write(nu_diag,*) 'grid_type = ', & trim(grid_type),': user-defined grid with northern hemisphere zipper' + tmpstr2 = ' ' if (trim(ns_boundary_type) == 'tripole') then tmpstr2 = ' on U points (nodes)' elseif (trim(ns_boundary_type) == 'tripoleT') then diff --git a/cicecore/cicedynB/infrastructure/comm/mpi/ice_communicate.F90 b/cicecore/cicedynB/infrastructure/comm/mpi/ice_communicate.F90 index a7d186083..1c369ef93 100644 --- a/cicecore/cicedynB/infrastructure/comm/mpi/ice_communicate.F90 +++ b/cicecore/cicedynB/infrastructure/comm/mpi/ice_communicate.F90 @@ -13,18 +13,6 @@ module ice_communicate use ice_exit, only: abort_ice use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted -#if defined key_oasis3 || key_oasis3mct - use cpl_oasis3 -#endif - -#if defined key_oasis4 - use cpl_oasis4 -#endif - -#if defined key_iomput - use lib_mpp, only: mpi_comm_opa ! MPP library -#endif - implicit none private @@ -83,13 +71,7 @@ subroutine init_communicate(mpicom) if (present(mpicom)) then ice_comm = mpicom else -#if (defined key_oasis3 || defined key_oasis3mct || defined key_oasis4) - ice_comm = localComm ! communicator from NEMO/OASISn -#elif defined key_iomput - ice_comm = mpi_comm_opa ! communicator from NEMO/XIOS -#else ice_comm = MPI_COMM_WORLD ! Global communicator -#endif endif call MPI_INITIALIZED(flag,ierr) diff --git a/configuration/scripts/tests/test_decomp.script b/configuration/scripts/tests/test_decomp.script index 70d7cd24a..40b84d08e 100644 --- a/configuration/scripts/tests/test_decomp.script +++ b/configuration/scripts/tests/test_decomp.script @@ -75,10 +75,16 @@ foreach decomp (${decomps}) set bfbstatus = $status if ($bfbstatus == 0) then set grade = PASS - echo "bfb baseline and test dataset are identical" + echo "bfbcomp baseline and test dataset are identical" + else if ( ${bfbstatus} == 1 ) then + set grade = FAIL + echo "bfbcomp baseline and test dataset are different" + else if ( ${bfbstatus} == 2 ) then + set grade = FAIL + echo "bfbcomp baseline missing data" else set grade = FAIL - echo "bfbcomp and test dataset are different" + echo "bfbcomp script failed" endif echo "$grade ${ICE_TESTNAME}_${decomp} bfbcomp ${base_case}" >> ${ICE_CASEDIR}/test_output endif diff --git a/doc/source/intro/quickstart.rst b/doc/source/intro/quickstart.rst index 547d6ef20..56d19ee70 100644 --- a/doc/source/intro/quickstart.rst +++ b/doc/source/intro/quickstart.rst @@ -16,6 +16,9 @@ You will probably have to download some inputdata, see the `CICE wiki `_ environment file is available at : ``configuration/scripts/machines/environment.yml``. @@ -837,6 +835,50 @@ modify the scripts and input settings in the case directory, NOT the run directo In general, files in the run directory are overwritten by versions in the case directory when the model is built, submitted, and run. +.. _aliases: + +Use of Shell Aliases +------------------------- + +This section provides a list of some potentially useful shell aliases that leverage the CICE +scripts. These are not defined by CICE and are not required for using CICE. They +are provided as an example of what can be done by users. +The current **ice_in**, **cice.settings**, and **env.[machine]** files are copied from +the case directory into the run directory when the model is run. Users can create aliases +leveraging the variables in these files. Aliases like the following can be established +in shell startup files or otherwise at users discretion: + +.. code-block:: bash + + #!/bin/tcsh + # From a case or run directory, source the necessary environment files to run CICE + alias cice_env 'source env.*; source cice.settings' + # Go from case directory to run directory and back (see https://stackoverflow.com/a/34874698/) + alias cdrun 'set rundir=`\grep "setenv ICE_RUNDIR" cice.settings | awk "{print "\$"NF}"` && cd $rundir' + alias cdcase 'set casedir=`\grep "setenv ICE_CASEDIR" cice.settings | awk "{print "\$"NF}"` && cd $casedir' + + #!/bin/bash + # From case/test directory, go to run directory + alias cdrun='cd $(cice_var ICE_RUNDIR)' + # From run directory, go to case/test directory + alias cdcase='cd $(cice_var ICE_CASEDIR)' + # monitor current cice run (from ICE_RUNDIR directory) + alias cice_tail='tail -f $(ls -1t cice.runlog.* |head -1)' + # open log from last CICE run (from ICE_CASEDIR directory) + alias cice_lastrun='$EDITOR $(ls -1t logs/cice.runlog.* |head -1)' + # open log from last CICE build (from ICE_CASEDIR directory) + alias cice_lastbuild='$EDITOR $(ls -1t logs/cice.bldlog.* |head -1)' + # show CICE run directory when run in the case directory + alias cice_rundir='cice_var ICE_RUNDIR' + # open a tcsh shell and source env.* and cice.settings (useful for launching CICE in a debugger) + alias cice_shell='tcsh -c "cice_env; tcsh"' + + ## Functions + # Print the value of a CICE variable ($1) from cice.settings + cice_var() { + \grep "setenv $1" cice.settings | awk "{print "\$"3}" + } + .. _timeseries: Timeseries Plotting From e14b6a209288040cbe3258c968aecc103b36415b Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Wed, 2 Dec 2020 17:55:00 -0800 Subject: [PATCH 03/18] Revert "deprecate upwind advection (#508)" (#535) * Revert "deprecate upwind advection (#508)" This reverts commit 164fcfcfa4c126c9779c087dd1267b08449ddb24. * Deprecate ktransport and update advection="none" implementation Update documentation as needed ktransport still exists as a namelist only ktransport<=0 will override the advection setting, set advection='none', and print out a warning message advection can only be set to remap, upwind, or none * update documentation * update documentation * un-deprecate ktransport in update and deprecate advection=none advection valid options are only remap and upwind ktransport turns on/off advection via advection=none internally * update documentation * update documentation --- cicecore/cicedynB/dynamics/ice_dyn_shared.F90 | 1 - .../dynamics/ice_transport_driver.F90 | 142 +++++++++--------- cicecore/cicedynB/general/ice_init.F90 | 62 +++++--- cicecore/cicedynB/general/ice_step_mod.F90 | 14 +- configuration/scripts/options/set_nml.alt04 | 2 +- doc/source/developer_guide/dg_dynamics.rst | 6 +- doc/source/science_guide/sg_horiztrans.rst | 2 +- doc/source/user_guide/ug_case_settings.rst | 2 +- 8 files changed, 121 insertions(+), 110 deletions(-) diff --git a/cicecore/cicedynB/dynamics/ice_dyn_shared.F90 b/cicecore/cicedynB/dynamics/ice_dyn_shared.F90 index d9a0919e6..486efb731 100644 --- a/cicecore/cicedynB/dynamics/ice_dyn_shared.F90 +++ b/cicecore/cicedynB/dynamics/ice_dyn_shared.F90 @@ -32,7 +32,6 @@ module ice_dyn_shared integer (kind=int_kind), public :: & kdyn , & ! type of dynamics ( -1, 0 = off, 1 = evp, 2 = eap ) kridge , & ! set to "-1" to turn off ridging - ktransport , & ! set to "-1" to turn off transport ndte ! number of subcycles: ndte=dt/dte character (len=char_len), public :: & diff --git a/cicecore/cicedynB/dynamics/ice_transport_driver.F90 b/cicecore/cicedynB/dynamics/ice_transport_driver.F90 index 82e04dc71..c500e1631 100644 --- a/cicecore/cicedynB/dynamics/ice_transport_driver.F90 +++ b/cicecore/cicedynB/dynamics/ice_transport_driver.F90 @@ -1,7 +1,6 @@ !======================================================================= ! -!deprecate upwind Drivers for remapping and upwind ice transport -! Drivers for incremental remapping ice transport +! Drivers for remapping and upwind ice transport ! ! authors: Elizabeth C. Hunke and William H. Lipscomb, LANL ! @@ -10,7 +9,6 @@ ! 2006: Incorporated remap transport driver and renamed from ! ice_transport_upwind. ! 2011: ECH moved edgearea arrays into ice_transport_remap.F90 -! 2020: deprecated upwind transport module ice_transport_driver @@ -30,13 +28,12 @@ module ice_transport_driver implicit none private - public :: init_transport, transport_remap!deprecate upwind:, transport_upwind + public :: init_transport, transport_remap, transport_upwind character (len=char_len), public :: & advection ! type of advection scheme used -!deprecate upwind ! 'upwind' => 1st order donor cell scheme + ! 'upwind' => 1st order donor cell scheme ! 'remap' => remapping scheme - ! 'none' => advection off (ktransport = -1 also turns it off) logical, parameter :: & ! if true, prescribe area flux across each edge l_fixed_area = .false. @@ -72,9 +69,8 @@ module ice_transport_driver !======================================================================= ! ! This subroutine is a wrapper for init_remap, which initializes the -! remapping transport scheme. -!deprecate upwind If the model is run with upwind -!deprecate upwind! transport, no initializations are necessary. +! remapping transport scheme. If the model is run with upwind +! transport, no initializations are necessary. ! ! authors William H. Lipscomb, LANL @@ -684,12 +680,11 @@ subroutine transport_remap (dt) end subroutine transport_remap !======================================================================= -!deprecate upwind! +! ! Computes the transport equations for one timestep using upwind. Sets ! several fields into a work array and passes it to upwind routine. -!deprecate upwind - subroutine transport_upwind_deprecated (dt) + subroutine transport_upwind (dt) use ice_boundary, only: ice_HaloUpdate use ice_blocks, only: nx_block, ny_block, block, get_block, nx_block, ny_block @@ -774,52 +769,52 @@ subroutine transport_upwind_deprecated (dt) field_loc_Nface, field_type_vector) call ice_timer_stop(timer_bound) -!deprecate upwind !$OMP PARALLEL DO PRIVATE(iblk,ilo,ihi,jlo,jhi,this_block) -!deprecate upwind do iblk = 1, nblocks -!deprecate upwind this_block = get_block(blocks_ice(iblk),iblk) -!deprecate upwind ilo = this_block%ilo -!deprecate upwind ihi = this_block%ihi -!deprecate upwind jlo = this_block%jlo -!deprecate upwind jhi = this_block%jhi + !$OMP PARALLEL DO PRIVATE(iblk,ilo,ihi,jlo,jhi,this_block) + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + !----------------------------------------------------------------- ! fill work arrays with fields to be advected !----------------------------------------------------------------- -!deprecate upwind -!deprecate upwind call state_to_work (nx_block, ny_block, & -!deprecate upwind ntrcr, & -!deprecate upwind narr, trcr_depend, & -!deprecate upwind aicen (:,:, :,iblk), trcrn (:,:,:,:,iblk), & -!deprecate upwind vicen (:,:, :,iblk), vsnon (:,:, :,iblk), & -!deprecate upwind aice0 (:,:, iblk), works (:,:, :,iblk)) + call state_to_work (nx_block, ny_block, & + ntrcr, & + narr, trcr_depend, & + aicen (:,:, :,iblk), trcrn (:,:,:,:,iblk), & + vicen (:,:, :,iblk), vsnon (:,:, :,iblk), & + aice0 (:,:, iblk), works (:,:, :,iblk)) !----------------------------------------------------------------- ! advect !----------------------------------------------------------------- -!deprecate upwind call upwind_field (nx_block, ny_block, & -!deprecate upwind ilo, ihi, jlo, jhi, & -!deprecate upwind dt, & -!deprecate upwind narr, works(:,:,:,iblk), & -!deprecate upwind uee(:,:,iblk), vnn (:,:,iblk), & -!deprecate upwind HTE(:,:,iblk), HTN (:,:,iblk), & -!deprecate upwind tarea(:,:,iblk)) + call upwind_field (nx_block, ny_block, & + ilo, ihi, jlo, jhi, & + dt, & + narr, works(:,:,:,iblk), & + uee(:,:,iblk), vnn (:,:,iblk), & + HTE(:,:,iblk), HTN (:,:,iblk), & + tarea(:,:,iblk)) !----------------------------------------------------------------- ! convert work arrays back to state variables !----------------------------------------------------------------- -!deprecate upwind call work_to_state (nx_block, ny_block, & -!deprecate upwind ntrcr, narr, & -!deprecate upwind trcr_depend(:), trcr_base(:,:), & -!deprecate upwind n_trcr_strata(:), nt_strata(:,:), & -!deprecate upwind aicen(:,:, :,iblk), trcrn (:,:,:,:,iblk), & -!deprecate upwind vicen(:,:, :,iblk), vsnon (:,:, :,iblk), & -!deprecate upwind aice0(:,:, iblk), works (:,:, :,iblk)) + call work_to_state (nx_block, ny_block, & + ntrcr, narr, & + trcr_depend(:), trcr_base(:,:), & + n_trcr_strata(:), nt_strata(:,:), & + aicen(:,:, :,iblk), trcrn (:,:,:,:,iblk), & + vicen(:,:, :,iblk), vsnon (:,:, :,iblk), & + aice0(:,:, iblk), works (:,:, :,iblk)) -!deprecate upwind enddo ! iblk -!deprecate upwind !$OMP END PARALLEL DO + enddo ! iblk + !$OMP END PARALLEL DO deallocate (works) @@ -837,8 +832,7 @@ subroutine transport_upwind_deprecated (dt) call ice_timer_stop(timer_advect) ! advection - end subroutine transport_upwind_deprecated -!deprecate upwind + end subroutine transport_upwind !======================================================================= ! The next few subroutines (through check_monotonicity) are called @@ -1461,12 +1455,12 @@ subroutine check_monotonicity (nx_block, ny_block, & end subroutine check_monotonicity !======================================================================= -!deprecate upwind! The remaining subroutines are called by transport_upwind. +! The remaining subroutines are called by transport_upwind. !======================================================================= ! ! Fill work array with state variables in preparation for upwind transport -!deprecate upwind - subroutine state_to_work_deprecated (nx_block, ny_block, & + + subroutine state_to_work (nx_block, ny_block, & ntrcr, & narr, trcr_depend, & aicen, trcrn, & @@ -1607,13 +1601,13 @@ subroutine state_to_work_deprecated (nx_block, ny_block, & if (narr /= narrays) write(nu_diag,*) & "Wrong number of arrays in transport bound call" - end subroutine state_to_work_deprecated + end subroutine state_to_work !======================================================================= ! ! Convert work array back to state variables -!deprecate upwind - subroutine work_to_state_deprecated (nx_block, ny_block, & + + subroutine work_to_state (nx_block, ny_block, & ntrcr, narr, & trcr_depend, & trcr_base, & @@ -1721,13 +1715,13 @@ subroutine work_to_state_deprecated (nx_block, ny_block, & if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) - end subroutine work_to_state_deprecated + end subroutine work_to_state !======================================================================= ! ! upwind transport algorithm -!deprecate upwind - subroutine upwind_field_deprecated (nx_block, ny_block, & + + subroutine upwind_field (nx_block, ny_block, & ilo, ihi, jlo, jhi, & dt, & narrays, phi, & @@ -1770,26 +1764,26 @@ subroutine upwind_field_deprecated (nx_block, ny_block, & do n = 1, narrays -!deprecate upwind do j = 1, jhi -!deprecate upwind do i = 1, ihi -!deprecate upwind worka(i,j)= & -!deprecate upwind upwind(phi(i,j,n),phi(i+1,j,n),uee(i,j),HTE(i,j),dt) -!deprecate upwind workb(i,j)= & -!deprecate upwind upwind(phi(i,j,n),phi(i,j+1,n),vnn(i,j),HTN(i,j),dt) -!deprecate upwind enddo -!deprecate upwind enddo - -!deprecate upwind do j = jlo, jhi -!deprecate upwind do i = ilo, ihi -!deprecate upwind phi(i,j,n) = phi(i,j,n) - ( worka(i,j)-worka(i-1,j) & -!deprecate upwind + workb(i,j)-workb(i,j-1) ) & -!deprecate upwind / tarea(i,j) -!deprecate upwind enddo -!deprecate upwind enddo + do j = 1, jhi + do i = 1, ihi + worka(i,j)= & + upwind(phi(i,j,n),phi(i+1,j,n),uee(i,j),HTE(i,j),dt) + workb(i,j)= & + upwind(phi(i,j,n),phi(i,j+1,n),vnn(i,j),HTN(i,j),dt) + enddo + enddo + + do j = jlo, jhi + do i = ilo, ihi + phi(i,j,n) = phi(i,j,n) - ( worka(i,j)-worka(i-1,j) & + + workb(i,j)-workb(i,j-1) ) & + / tarea(i,j) + enddo + enddo enddo ! narrays - end subroutine upwind_field_deprecated + end subroutine upwind_field !======================================================================= @@ -1797,13 +1791,13 @@ end subroutine upwind_field_deprecated ! Define upwind function !------------------------------------------------------------------- -!deprecate upwind real(kind=dbl_kind) function upwind(y1,y2,a,h,dt) + real(kind=dbl_kind) function upwind(y1,y2,a,h,dt) -!deprecate upwind real(kind=dbl_kind), intent(in) :: y1,y2,a,h,dt + real(kind=dbl_kind), intent(in) :: y1,y2,a,h,dt -!deprecate upwind upwind = p5*dt*h*((a+abs(a))*y1+(a-abs(a))*y2) + upwind = p5*dt*h*((a+abs(a))*y1+(a-abs(a))*y2) -!deprecate upwind end function upwind + end function upwind !======================================================================= diff --git a/cicecore/cicedynB/general/ice_init.F90 b/cicecore/cicedynB/general/ice_init.F90 index 42a96ad78..981f460a4 100644 --- a/cicecore/cicedynB/general/ice_init.F90 +++ b/cicecore/cicedynB/general/ice_init.F90 @@ -99,7 +99,7 @@ subroutine input_data kevp_kernel, & basalstress, k1, k2, alphab, threshold_hw, & Ktens, e_ratio, coriolis, ssh_stress, & - kridge, ktransport, brlx, arlx + kridge, brlx, arlx use ice_dyn_vp, only: maxits_nonlin, precond, dim_fgmres, dim_pgmres, maxits_fgmres, & maxits_pgmres, monitor_nonlin, monitor_fgmres, & monitor_pgmres, reltol_nonlin, reltol_fgmres, reltol_pgmres, & @@ -127,7 +127,7 @@ subroutine input_data sw_frac, sw_dtemp integer (kind=int_kind) :: ktherm, kstrength, krdg_partic, krdg_redist, natmiter, & - kitd, kcatbound + kitd, kcatbound, ktransport character (len=char_len) :: shortwave, albedo_type, conduct, fbot_xfer_type, & tfrz_option, frzpnd, atmbndy, wave_spec_type @@ -846,11 +846,7 @@ subroutine input_data abort_list = trim(abort_list)//":1" endif -!deprecate upwind if (advection /= 'remap' .and. advection /= 'upwind' .and. advection /= 'none') then - if (advection /= 'remap' .and. advection /= 'none') then - if (trim(advection) == 'upwind') then - if (my_task == master_task) write(nu_diag,*) subname//' ERROR: upwind advection has been deprecated' - endif + if (ktransport > 0 .and. advection /= 'remap' .and. advection /= 'upwind') then if (my_task == master_task) write(nu_diag,*) subname//' ERROR: invalid advection=',trim(advection) abort_list = trim(abort_list)//":3" endif @@ -1169,11 +1165,12 @@ subroutine input_data if (trim(grid_type) == 'tripole') then write(nu_diag,*) 'grid_type = ', & trim(grid_type),': user-defined grid with northern hemisphere zipper' - tmpstr2 = ' ' if (trim(ns_boundary_type) == 'tripole') then tmpstr2 = ' on U points (nodes)' elseif (trim(ns_boundary_type) == 'tripoleT') then tmpstr2 = ' on T points (cell centers)' + else + tmpstr2 = ' ' endif write(nu_diag,*) 'ns_boundary_type = ', trim(ns_boundary_type),trim(tmpstr2) endif @@ -1200,6 +1197,8 @@ subroutine input_data tmpstr2 = ' WMO standard ITD categories' elseif (kcatbound == -1) then tmpstr2 = ' one thickness category' + else + tmpstr2 = ': unknown value' endif write(nu_diag,1022) ' kcatbound = ', kcatbound,trim(tmpstr2) if (kitd==0) then @@ -1229,6 +1228,8 @@ subroutine input_data tmpstr2 = ' viscous-plastic dynamics' elseif (kdyn < 1) then tmpstr2 = ' dynamics disabled' + else + tmpstr2 = ': unknown value' endif write(nu_diag,1022) ' kdyn = ', kdyn,trim(tmpstr2) if (kdyn >= 1) then @@ -1259,6 +1260,8 @@ subroutine input_data tmpstr2 = ' = 1.46e-4/s' elseif (trim(coriolis) == 'zero') then tmpstr2 = ' = 0.0' + else + tmpstr2 = ': unknown value' endif write(nu_diag,*) 'coriolis = ',trim(coriolis),trim(tmpstr2) @@ -1266,23 +1269,24 @@ subroutine input_data tmpstr2 = ': from ocean velocity' elseif (trim(ssh_stress) == 'coupled') then tmpstr2 = ': from coupled sea surface height gradients' + else + tmpstr2 = ': unknown value' endif write(nu_diag,*) 'ssh_stress = ',trim(ssh_stress),trim(tmpstr2) - if (ktransport == 1) then - tmpstr2 = ' transport enabled' - if (trim(advection) == 'remap') then - tmpstr2 = ': linear remapping advection' -!deprecate upwind elseif (trim(advection) == 'upwind') then -!deprecate upwind tmpstr2 = ': donor cell (upwind) advection' - elseif (trim(advection) == 'none') then - tmpstr2 = ': advection off' - endif - write(nu_diag,*) 'advection = ', trim(advection),trim(tmpstr2) + if (ktransport <= 0) then + advection = 'none' + endif + if (trim(advection) == 'remap') then + tmpstr2 = ': linear remapping advection' + elseif (trim(advection) == 'upwind') then + tmpstr2 = ': donor cell (upwind) advection' + elseif (trim(advection) == 'none') then + tmpstr2 = ': advection disabled by ktransport namelist' else - tmpstr2 = ' transport disabled' + tmpstr2 = ': unknown value' endif - write(nu_diag,1022) ' ktransport = ', ktransport,trim(tmpstr2) + write(nu_diag,*) 'advection = ', trim(advection),trim(tmpstr2) if (basalstress) then tmpstr2 = ' use basal stress parameterization for landfast ice' @@ -1330,6 +1334,8 @@ subroutine input_data tmpstr2 = ' Hibler (1979)' elseif (kstrength == 1) then tmpstr2 = ' Rothrock (1975)' + else + tmpstr2 = ': unknown value' endif write(nu_diag,1022) ' kstrength = ', kstrength,trim(tmpstr2) if (kstrength == 0) then @@ -1351,6 +1357,8 @@ subroutine input_data tmpstr2 = ' zero-layer thermo' elseif (ktherm < 0) then tmpstr2 = ' thermodynamics disabled' + else + tmpstr2 = ': unknown value' endif if (ktherm >= 0) then write(nu_diag,1022) ' ktherm = ', ktherm,trim(tmpstr2) @@ -1379,6 +1387,8 @@ subroutine input_data tmpstr2 = ': delta-Eddington multiple-scattering method' elseif (trim(shortwave) == 'ccsm3') then tmpstr2 = ': NCAR CCSM3 distribution method' + else + tmpstr2 = ': unknown value' endif write(nu_diag,*) ' shortwave = ', trim(shortwave),trim(tmpstr2) if (trim(shortwave) == 'dEdd') then @@ -1393,6 +1403,8 @@ subroutine input_data tmpstr2 = ': NCAR CCSM3 albedos' elseif (trim(albedo_type) == 'constant') then tmpstr2 = ': four constant albedos' + else + tmpstr2 = ': unknown value' endif write(nu_diag,*) 'albedo_type = ', trim(albedo_type),trim(tmpstr2) if (trim(albedo_type) == 'ccsm3') then @@ -1419,6 +1431,8 @@ subroutine input_data write(nu_diag,1006) ' atmiter_conv = ', atmiter_conv,' convergence criterion for ustar' elseif (trim(atmbndy) == 'constant') then tmpstr2 = ': boundary layer uses bulk transfer coefficients' + else + tmpstr2 = ': unknown value' endif write(nu_diag,*) 'atmbndy = ', trim(atmbndy),trim(tmpstr2) @@ -1442,6 +1456,8 @@ subroutine input_data tmpstr2 = ': linear function of salinity (use with ktherm=1)' elseif (trim(tfrz_option) == 'mushy') then tmpstr2 = ': Assur (1958) as in mushy-layer thermo (ktherm=2)' + else + tmpstr2 = ': unknown value' endif write(nu_diag,*) 'tfrz_option = ', trim(tfrz_option),trim(tmpstr2) if (update_ocn_f) then @@ -1460,6 +1476,8 @@ subroutine input_data tmpstr2 = ': ocean heat transfer coefficient is constant' elseif (trim(fbot_xfer_type) == 'Cdn_ocn') then tmpstr2 = ': variable ocean heat transfer coefficient' ! only used with form_drag=T? + else + tmpstr2 = ': unknown value' endif write(nu_diag,*) 'fbot_xfer_type = ', trim(fbot_xfer_type),trim(tmpstr2) write(nu_diag,1006) ' ustar_min = ', ustar_min,' minimum value of ocean friction velocity' @@ -1480,6 +1498,8 @@ subroutine input_data tmpstr2 = ': constant wave spectrum data file provided for testing' elseif (trim(wave_spec_type) == 'random') then tmpstr2 = ': wave data file provided, spectrum generated using random number' + else + tmpstr2 = ': unknown value' endif write(nu_diag,*) 'wave_spec_type = ', trim(wave_spec_type),trim(tmpstr2) endif @@ -1506,6 +1526,8 @@ subroutine input_data tmpstr2 = ': Stefan refreezing with pond ice thickness' elseif (trim(frzpnd) == 'cesm') then tmpstr2 = ': CESM refreezing empirical formula' + else + tmpstr2 = ': unknown value' endif write(nu_diag,*) ' frzpnd = ', trim(frzpnd),trim(tmpstr2) write(nu_diag,1007) ' hs1 = ', hs1,' snow depth of transition to pond ice' diff --git a/cicecore/cicedynB/general/ice_step_mod.F90 b/cicecore/cicedynB/general/ice_step_mod.F90 index 4b92c2a42..b31582fe8 100644 --- a/cicecore/cicedynB/general/ice_step_mod.F90 +++ b/cicecore/cicedynB/general/ice_step_mod.F90 @@ -851,10 +851,9 @@ subroutine step_dyn_horiz (dt) use ice_dyn_evp, only: evp use ice_dyn_eap, only: eap use ice_dyn_vp, only: implicit_solver - use ice_dyn_shared, only: kdyn, ktransport + use ice_dyn_shared, only: kdyn use ice_flux, only: init_history_dyn -!deprecate upwind use ice_transport_driver, only: advection, transport_upwind, transport_remap - use ice_transport_driver, only: advection, transport_remap + use ice_transport_driver, only: advection, transport_upwind, transport_remap real (kind=dbl_kind), intent(in) :: & dt ! dynamics time step @@ -875,13 +874,10 @@ subroutine step_dyn_horiz (dt) ! Horizontal ice transport !----------------------------------------------------------------- -!deprecate upwind if (ktransport > 0) then - if (ktransport > 0 .and. advection == 'remap') then -!deprecate upwind if (advection == 'upwind') then -!deprecate upwind call transport_upwind (dt) ! upwind -!deprecate upwind else + if (advection == 'upwind') then + call transport_upwind (dt) ! upwind + elseif (advection == 'remap') then call transport_remap (dt) ! incremental remapping -!deprecate upwind endif endif end subroutine step_dyn_horiz diff --git a/configuration/scripts/options/set_nml.alt04 b/configuration/scripts/options/set_nml.alt04 index e3689fe82..937704294 100644 --- a/configuration/scripts/options/set_nml.alt04 +++ b/configuration/scripts/options/set_nml.alt04 @@ -22,7 +22,7 @@ kevp_kernel = 102 fbot_xfer_type = 'Cdn_ocn' shortwave = 'dEdd' formdrag = .true. -advection = 'remap' +advection = 'upwind' kstrength = 0 krdg_partic = 0 krdg_redist = 0 diff --git a/doc/source/developer_guide/dg_dynamics.rst b/doc/source/developer_guide/dg_dynamics.rst index eac19b1f6..c94d47b35 100644 --- a/doc/source/developer_guide/dg_dynamics.rst +++ b/doc/source/developer_guide/dg_dynamics.rst @@ -50,9 +50,9 @@ abort if set. To override the abort, use value 102 for testing. Transport ----------------- -The transport (advection) methods are found in **cicecore/cicedynB/dynamics/**. Only the incremental -remapping method is supported at this time, and is set in namelist via the ``advection`` variable. -Transport can be turned off by setting ``advection = none`` or ``ktransport = -1``. +The transport (advection) methods are found in **cicecore/cicedynB/dynamics/**. Two methods are supported, +upwind and remap. These are set in namelist via the ``advection`` variable. +Transport can be disabled with the ``ktransport`` namelist variable. Infrastructure diff --git a/doc/source/science_guide/sg_horiztrans.rst b/doc/source/science_guide/sg_horiztrans.rst index 33b37564e..bafb4c72f 100644 --- a/doc/source/science_guide/sg_horiztrans.rst +++ b/doc/source/science_guide/sg_horiztrans.rst @@ -33,7 +33,7 @@ introductory comments in **ice\_transport\_remap.F90**. Prognostic equations for ice and/or snow density may be included in future model versions but have not yet been implemented. -One transport scheme is available, the incremental +Two transport schemes are available: upwind and the incremental remapping scheme of :cite:`Dukowicz00` as modified for sea ice by :cite:`Lipscomb04`. The remapping scheme has several desirable features: diff --git a/doc/source/user_guide/ug_case_settings.rst b/doc/source/user_guide/ug_case_settings.rst index 7c1252216..f06063426 100644 --- a/doc/source/user_guide/ug_case_settings.rst +++ b/doc/source/user_guide/ug_case_settings.rst @@ -356,7 +356,7 @@ dynamics_nml "", "", "", "" "``advection``", "``remap``", "linear remapping advection scheme", "``remap``" - "", "``none``", "advection off", "" + "", "``upwind``", "donor cell advection", "" "``alphab``", "real", ":math:`\alpha_{b}` factor in :cite:`Lemieux16`", "20.0" "``arlx``", "real", "revised_evp value", "300.0" "``brlx``", "real", "revised_evp value", "300.0" From f299b33bf91f8e53557a863c91f60b7e1dad7f2a Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Wed, 2 Dec 2020 18:01:08 -0800 Subject: [PATCH 04/18] Add floediam, hfrzazilmin namelist and update Icepack (#536) Add floediam and hfrazilmin as CICE namelist. Requires latest version of Icepack. Update documentation. Icepack has two non bit-for-bit changes including - a fix to multiple declarations of floeshape (https://github.com/CICE-Consortium/Icepack/pull/342) - a fix to the convergence scheme in icepack_atmo (https://github.com/CICE-Consortium/Icepack/pull/341) --- cicecore/cicedynB/general/ice_init.F90 | 15 +++++++++++---- configuration/scripts/ice_in | 2 ++ doc/source/user_guide/ug_case_settings.rst | 2 ++ icepack | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cicecore/cicedynB/general/ice_init.F90 b/cicecore/cicedynB/general/ice_init.F90 index 981f460a4..1f2a85aea 100644 --- a/cicecore/cicedynB/general/ice_init.F90 +++ b/cicecore/cicedynB/general/ice_init.F90 @@ -124,7 +124,7 @@ subroutine input_data mu_rdg, hs0, dpscale, rfracmin, rfracmax, pndaspect, hs1, hp1, & a_rapid_mode, Rac_rapid_mode, aspect_rapid_mode, dSdt_slow_mode, & phi_c_slow_mode, phi_i_mushy, kalg, atmiter_conv, Pstar, Cstar, & - sw_frac, sw_dtemp + sw_frac, sw_dtemp, floediam, hfrazilmin integer (kind=int_kind) :: ktherm, kstrength, krdg_partic, krdg_redist, natmiter, & kitd, kcatbound, ktransport @@ -190,7 +190,8 @@ subroutine input_data kitd, ktherm, conduct, ksno, & a_rapid_mode, Rac_rapid_mode, aspect_rapid_mode, & dSdt_slow_mode, phi_c_slow_mode, phi_i_mushy, & - sw_redist, sw_frac, sw_dtemp + sw_redist, sw_frac, sw_dtemp, & + floediam, hfrazilmin namelist /dynamics_nml/ & kdyn, ndte, revised_evp, yield_curve, & @@ -473,6 +474,9 @@ subroutine input_data phi_c_slow_mode = 0.05_dbl_kind ! critical liquid fraction porosity cutoff phi_i_mushy = 0.85_dbl_kind ! liquid fraction of congelation ice + floediam = 300.0_dbl_kind ! min thickness of new frazil ice (m) + hfrazilmin = 0.05_dbl_kind ! effective floe diameter (m) + ! shortwave redistribution in the thermodynamics sw_redist = .false. sw_frac = 0.9_dbl_kind @@ -777,6 +781,8 @@ subroutine input_data call broadcast_scalar(n_fed, master_task) call broadcast_scalar(n_fep, master_task) call broadcast_scalar(a_rapid_mode, master_task) + call broadcast_scalar(floediam, master_task) + call broadcast_scalar(hfrazilmin, master_task) call broadcast_scalar(Rac_rapid_mode, master_task) call broadcast_scalar(aspect_rapid_mode, master_task) call broadcast_scalar(dSdt_slow_mode, master_task) @@ -1210,7 +1216,7 @@ subroutine input_data if (tr_fsd) then tmpstr2 = ' floe size distribution is enabled' - ! write(nu_diag,1002) ' floediam = ', floediam, ' constant floe diameter' + write(nu_diag,1002) ' floediam = ', floediam, ' constant floe diameter' else tmpstr2 = ' floe size distribution is disabled' endif @@ -1378,7 +1384,7 @@ subroutine input_data write(nu_diag,1007) ' phi_i_mushy = ', phi_i_mushy,' solid fraction at lower boundary' endif endif - !write(nu_diag,1007) ' hfrazilmin = ', hfrazilmin,' minimum new frazil ice thickness' + write(nu_diag,1007) ' hfrazilmin = ', hfrazilmin,' minimum new frazil ice thickness' write(nu_diag,*) ' ' write(nu_diag,*) ' Radiation' @@ -1789,6 +1795,7 @@ subroutine input_data rfracmin_in=rfracmin, rfracmax_in=rfracmax, pndaspect_in=pndaspect, hs1_in=hs1, hp1_in=hp1, & ktherm_in=ktherm, calc_Tsfc_in=calc_Tsfc, conduct_in=conduct, & a_rapid_mode_in=a_rapid_mode, Rac_rapid_mode_in=Rac_rapid_mode, & + floediam_in=floediam, hfrazilmin_in=hfrazilmin, & aspect_rapid_mode_in=aspect_rapid_mode, dSdt_slow_mode_in=dSdt_slow_mode, & phi_c_slow_mode_in=phi_c_slow_mode, phi_i_mushy_in=phi_i_mushy, conserv_check_in=conserv_check, & wave_spec_type_in = wave_spec_type, & diff --git a/configuration/scripts/ice_in b/configuration/scripts/ice_in index 3139726f5..5516b3c51 100644 --- a/configuration/scripts/ice_in +++ b/configuration/scripts/ice_in @@ -111,6 +111,8 @@ sw_redist = .false. sw_frac = 0.9d0 sw_dtemp = 0.02d0 + hfrazilmin = 0.05d0 + floediam = 300.0d0 / &dynamics_nml diff --git a/doc/source/user_guide/ug_case_settings.rst b/doc/source/user_guide/ug_case_settings.rst index f06063426..b82afe52f 100644 --- a/doc/source/user_guide/ug_case_settings.rst +++ b/doc/source/user_guide/ug_case_settings.rst @@ -330,6 +330,8 @@ thermo_nml "``conduct``", "``bubbly``", "conductivity scheme :cite:`Pringle07`", "``bubbly``" "", "``MU71``", "conductivity :cite:`Maykut71`", "" "``dSdt_slow_mode``", "real", "slow drainage strength parameter m/s/K", "-1.5e-7" + "``floediam``", "real", "effective floe diameter for lateral melt in m", "300.0" + "``hfrazilmin``", "real", "min thickness of new frazil ice in m", "0.05" "``kitd``", "``0``", "delta function ITD approximation", "1" "", "``1``", "linear remapping ITD approximation", "" "``ksno``", "real", "snow thermal conductivity", "0.3" diff --git a/icepack b/icepack index 1e6bed9fd..77c523efc 160000 --- a/icepack +++ b/icepack @@ -1 +1 @@ -Subproject commit 1e6bed9fd44512c332d11adf6b7fcb0dd8472e58 +Subproject commit 77c523efc6515b065aad039ecd185b5f07c83783 From 40d38677992f356c5d232869dbf1fbf28a9f0ccc Mon Sep 17 00:00:00 2001 From: Matthew Turner Date: Mon, 7 Dec 2020 15:12:23 -0700 Subject: [PATCH 05/18] Update timeseries plots to resolve issue with some fields (#539) * Update the timeseries plots to accurately extract data from log files. Also add an option to plot SST from the python plotting script. This addresses issue #538 * Fix 2 typos * Remove SST and arwt tot mass from list of fields to plot --- configuration/scripts/timeseries.csh | 8 +++++--- configuration/scripts/timeseries.py | 7 ++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/configuration/scripts/timeseries.csh b/configuration/scripts/timeseries.csh index cdd025efc..b6b3fcf2e 100755 --- a/configuration/scripts/timeseries.csh +++ b/configuration/scripts/timeseries.csh @@ -13,9 +13,9 @@ endif set basename = `echo $1 | sed -e 's#/$##' | sed -e 's/^\.\///'` # Set x-axis limits - # Manuallyl set x-axis limits + # Manually set x-axis limits #set xrange = 'set xrange ["19980101":"19981231"]' - # Let gnuplot determine x-alis limits + # Let gnuplot determine x-axis limits set xrange = '' # Determine if BASELINE dataset exists @@ -59,8 +59,10 @@ endif # Loop through each field and create the plot foreach field ($fieldlist:q) + # Add backslashes before (, ), and ^ for grep searches + set search_name = "`echo '$field' | sed 's/(/\\(/' | sed 's/)/\\)/' | sed 's/\^/\\^/'`" set fieldname = `echo "$field" | sed -e 's/([^()]*)//g'` - set search = "'$fieldname'\|istep1" + set search = "'$search_name'\|istep1" rm -f data.txt foreach line ("`egrep $search $logfile`") if ("$line" =~ *"istep1"*) then diff --git a/configuration/scripts/timeseries.py b/configuration/scripts/timeseries.py index 2b50c373a..2c36cea73 100755 --- a/configuration/scripts/timeseries.py +++ b/configuration/scripts/timeseries.py @@ -53,7 +53,7 @@ def get_data(logfile,field): # Build the regular expression to extract the data field_regex = field.replace('(','\(').replace('^','\^').replace(')','\)') number_regex = '[-+]?\d+\.?\d+([eE][-+]?\d+)?' - my_regex = '{}\s+=\s+({})\s+({})'.format(field_regex,number_regex,number_regex) + my_regex = '^{}\s+=\s+({})\s+({})'.format(field_regex,number_regex,number_regex) dtg = [] arctic = [] @@ -95,9 +95,10 @@ def plot_timeseries(log, field, dtg, arctic, antarctic, expon, dtg_base=None, ar Plot the timeseries data from the CICE log file ''' - casename = os.path.abspath(log).rstrip('/').rstrip('/logs').split('/')[-1] + import re + casename = re.sub(r"/logs", "", os.path.abspath(log).rstrip('/')).split('/')[-1] if base_dir: - base_casename = os.path.abspath(base_dir).rstrip('/').rstrip('/logs').split('/')[-1] + base_casename = re.sub(r"/logs", "", os.path.abspath(base_dir).rstrip('/')).split('/')[-1] # Load the plotting libraries, but set the logging level for matplotlib # to WARNING so that matplotlib debugging info is not printed when running From 8d9352dc35da5293905d879023a4b9d0964d3837 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Fri, 11 Dec 2020 14:15:58 -0800 Subject: [PATCH 06/18] Move sw_redist, sw_frac, sw_dtemp from thermo to shortwave namelist (#540) * Move sw_redist, sw_frac, sw_dtemp from thermo to shortwave namelist Update verbose diagnostic output Update icepack to also include sw_redist, sw_frac, sw_dtemp changes in icepack driver (not required) Update version number in prep for next minor release * update verbose output in ice_init.F90 * update verbose output * update close_boundaries documentation --- cicecore/cicedynB/general/ice_init.F90 | 753 ++++++++++----------- cicecore/version.txt | 2 +- configuration/scripts/ice_in | 6 +- doc/source/conf.py | 4 +- doc/source/user_guide/ug_case_settings.rst | 7 +- icepack | 2 +- 6 files changed, 368 insertions(+), 406 deletions(-) diff --git a/cicecore/cicedynB/general/ice_init.F90 b/cicecore/cicedynB/general/ice_init.F90 index 1f2a85aea..a16cd7649 100644 --- a/cicecore/cicedynB/general/ice_init.F90 +++ b/cicecore/cicedynB/general/ice_init.F90 @@ -59,7 +59,7 @@ subroutine input_data use ice_broadcast, only: broadcast_scalar, broadcast_array use ice_diagnostics, only: diag_file, print_global, print_points, latpnt, lonpnt - use ice_domain, only: close_boundaries, ns_boundary_type, orca_halogrid + use ice_domain, only: close_boundaries, orca_halogrid use ice_domain_size, only: ncat, nilyr, nslyr, nblyr, nfsd, nfreq, & n_iso, n_aero, n_zaero, n_algae, & n_doc, n_dic, n_don, n_fed, n_fep, & @@ -190,7 +190,6 @@ subroutine input_data kitd, ktherm, conduct, ksno, & a_rapid_mode, Rac_rapid_mode, aspect_rapid_mode, & dSdt_slow_mode, phi_c_slow_mode, phi_i_mushy, & - sw_redist, sw_frac, sw_dtemp, & floediam, hfrazilmin namelist /dynamics_nml/ & @@ -213,6 +212,7 @@ subroutine input_data shortwave, albedo_type, & albicev, albicei, albsnowv, albsnowi, & ahmax, R_ice, R_pnd, R_snw, & + sw_redist, sw_frac, sw_dtemp, & dT_mlt, rsnw_mlt, kalg namelist /ponds_nml/ & @@ -1141,214 +1141,232 @@ subroutine input_data if (my_task == master_task) then write(nu_diag,*) ' Overview of model configuration with relevant parameters' - write(nu_diag,*) ' ========================================================' - write(nu_diag,*) ' For details, compare namelist output below with the' - write(nu_diag,*) ' Case Settings section in the model documentation.' + write(nu_diag,*) '=========================================================' + write(nu_diag,*) 'For details, compare namelist output below with the' + write(nu_diag,*) 'Case Settings section in the model documentation.' write(nu_diag,*) ' ' write(nu_diag,*) ' Calendar' write(nu_diag,*) '--------------------------------' - write(nu_diag,1022) ' days_per_year = ',days_per_year,' number of days in a model year' + write(nu_diag,1020) ' days_per_year = ',days_per_year,' : number of days in a model year' if (use_leap_years) then - tmpstr2 = ' leap days are included' + tmpstr2 = ' : leap days are included' else - tmpstr2 = ' leap days are not included' + tmpstr2 = ' : leap days are not included' endif - write(nu_diag,1012) ' use_leap_years = ',use_leap_years,trim(tmpstr2) - write(nu_diag,1002) ' dt = ', dt, ' model time step' + write(nu_diag,1010) ' use_leap_years = ',use_leap_years,trim(tmpstr2) + write(nu_diag,1002) ' dt = ', dt, ' : model time step' write(nu_diag,*) ' ' write(nu_diag,*) ' Grid, Discretization' write(nu_diag,*) '--------------------------------' - if (trim(grid_type) == 'rectangular') & - write(nu_diag,*) 'grid_type = ', & - trim(grid_type),': internally defined, rectangular grid' - if (trim(grid_type) == 'regional') & - write(nu_diag,*) 'grid_type = ', & - trim(grid_type),': user-defined, regional grid' - if (trim(grid_type) == 'displaced_pole') & - write(nu_diag,*) 'grid_type = ', & - trim(grid_type),': user-defined grid with rotated north pole' - if (trim(grid_type) == 'tripole') then - write(nu_diag,*) 'grid_type = ', & - trim(grid_type),': user-defined grid with northern hemisphere zipper' - if (trim(ns_boundary_type) == 'tripole') then - tmpstr2 = ' on U points (nodes)' - elseif (trim(ns_boundary_type) == 'tripoleT') then - tmpstr2 = ' on T points (cell centers)' - else - tmpstr2 = ' ' - endif - write(nu_diag,*) 'ns_boundary_type = ', trim(ns_boundary_type),trim(tmpstr2) - endif + tmpstr2 = ' ' + if (trim(grid_type) == 'rectangular') tmpstr2 = ' : internally defined, rectangular grid' + if (trim(grid_type) == 'regional') tmpstr2 = ' : user-defined, regional grid' + if (trim(grid_type) == 'displaced_pole') tmpstr2 = ' : user-defined grid with rotated north pole' + if (trim(grid_type) == 'tripole') tmpstr2 = ' : user-defined grid with northern hemisphere zipper' + write(nu_diag,1030) ' grid_type = ',trim(grid_type),trim(tmpstr2) if (trim(grid_type) /= 'rectangular') then if (use_bathymetry) then - tmpstr2 = ' bathymetric input data is used' + tmpstr2 = ' : bathymetric input data is used' else - tmpstr2 = ' bathymetric input data is not used' + tmpstr2 = ' : bathymetric input data is not used' endif - write(nu_diag,1012) ' use_bathymetry = ', use_bathymetry,trim(tmpstr2) - write(nu_diag,*) ' bathymetry_format= ', trim(bathymetry_format) + write(nu_diag,1010) ' use_bathymetry = ', use_bathymetry,trim(tmpstr2) + write(nu_diag,1030) ' bathymetry_format= ', trim(bathymetry_format) endif - write(nu_diag,1022) ' nilyr = ', nilyr, ' number of ice layers (equal thickness)' - write(nu_diag,1022) ' nslyr = ', nslyr, ' number of snow layers (equal thickness)' - write(nu_diag,1022) ' nblyr = ', nblyr, ' number of bio layers (equal thickness)' + write(nu_diag,1020) ' nilyr = ', nilyr, ' : number of ice layers (equal thickness)' + write(nu_diag,1020) ' nslyr = ', nslyr, ' : number of snow layers (equal thickness)' + write(nu_diag,1020) ' nblyr = ', nblyr, ' : number of bio layers (equal thickness)' if (trim(shortwave) == 'dEdd') & write(nu_diag,*) 'dEdd interior and sfc scattering layers are used in both ice, snow (unequal)' - write(nu_diag,1022) ' ncat = ', ncat, ' number of ice categories' + write(nu_diag,1020) ' ncat = ', ncat, ' : number of ice categories' if (kcatbound == 0) then - tmpstr2 = ' original ITD category bounds' + tmpstr2 = ' : original ITD category bounds' elseif (kcatbound == 1) then - tmpstr2 = ' round-number category bounds' + tmpstr2 = ' : round-number category bounds' elseif (kcatbound == 2) then - tmpstr2 = ' WMO standard ITD categories' + tmpstr2 = ' : WMO standard ITD categories' elseif (kcatbound == -1) then - tmpstr2 = ' one thickness category' + tmpstr2 = ' : one thickness category' else - tmpstr2 = ': unknown value' + tmpstr2 = ' : unknown value' endif - write(nu_diag,1022) ' kcatbound = ', kcatbound,trim(tmpstr2) + write(nu_diag,1020) ' kcatbound = ', kcatbound,trim(tmpstr2) if (kitd==0) then - tmpstr2 = ' delta function ITD approx' + tmpstr2 = ' : delta function ITD approx' else - tmpstr2 = ' linear remapping ITD approx' + tmpstr2 = ' : linear remapping ITD approx' endif - write(nu_diag,1022) ' kitd = ', kitd,trim(tmpstr2) + write(nu_diag,1020) ' kitd = ', kitd,trim(tmpstr2) if (tr_fsd) then - tmpstr2 = ' floe size distribution is enabled' - write(nu_diag,1002) ' floediam = ', floediam, ' constant floe diameter' + tmpstr2 = ' : floe size distribution is enabled' else - tmpstr2 = ' floe size distribution is disabled' + tmpstr2 = ' : floe size distribution is disabled' endif - write(nu_diag,1012) ' tr_fsd = ', tr_fsd,trim(tmpstr2) - write(nu_diag,1022) ' nfsd = ', nfsd, ' number of floe size categories' + write(nu_diag,1010) ' tr_fsd = ', tr_fsd,trim(tmpstr2) + write(nu_diag,1020) ' nfsd = ', nfsd, ' : number of floe size categories' write(nu_diag,*) ' ' write(nu_diag,*) ' Horizontal Dynamics' write(nu_diag,*) '--------------------------------' if (kdyn == 1) then - tmpstr2 = ' elastic-viscous-plastic dynamics' + tmpstr2 = ' : elastic-viscous-plastic dynamics' elseif (kdyn == 2) then - tmpstr2 = ' elastic-anisotropic-plastic dynamics' + tmpstr2 = ' : elastic-anisotropic-plastic dynamics' elseif (kdyn == 3) then - tmpstr2 = ' viscous-plastic dynamics' + tmpstr2 = ' : viscous-plastic dynamics' elseif (kdyn < 1) then - tmpstr2 = ' dynamics disabled' + tmpstr2 = ' : dynamics disabled' else - tmpstr2 = ': unknown value' + tmpstr2 = ' : unknown value' endif - write(nu_diag,1022) ' kdyn = ', kdyn,trim(tmpstr2) + write(nu_diag,1020) ' kdyn = ', kdyn,trim(tmpstr2) if (kdyn >= 1) then if (kdyn == 1 .or. kdyn == 2) then if (revised_evp) then - tmpstr2 = ' revised EVP formulation used' - write(nu_diag,1007) ' arlx = ', arlx, ' stress equation factor alpha' - write(nu_diag,1007) ' brlx = ', brlx, ' stress equation factor beta' + tmpstr2 = ' : revised EVP formulation used' + write(nu_diag,1002) ' arlx = ', arlx, ' : stress equation factor alpha' + write(nu_diag,1002) ' brlx = ', brlx, ' : stress equation factor beta' else - tmpstr2 = ' revised EVP formulation not used' + tmpstr2 = ' : revised EVP formulation not used' endif - write(nu_diag,1012) ' revised_evp = ', revised_evp,trim(tmpstr2) - write(nu_diag,1022) ' kevp_kernel = ', kevp_kernel,' EVP solver' + write(nu_diag,1010) ' revised_evp = ', revised_evp,trim(tmpstr2) - write(nu_diag,1022) ' ndtd = ', ndtd, ' number of dynamics/advection/ridging/steps per thermo timestep' - write(nu_diag,1022) ' ndte = ', ndte, ' number of EVP or EAP subcycles' - endif + if (kevp_kernel == 0) then + tmpstr2 = ' : original EVP solver' + elseif (kevp_kernel == 2 .or. kevp_kernel == 102) then + tmpstr2 = ' : vectorized EVP solver' + else + tmpstr2 = ' : unknown value' + endif + write(nu_diag,1020) ' kevp_kernel = ', kevp_kernel,trim(tmpstr2) + + write(nu_diag,1020) ' ndtd = ', ndtd, ' : number of dynamics/advection/ridging/steps per thermo timestep' + write(nu_diag,1020) ' ndte = ', ndte, ' : number of EVP or EAP subcycles' + endif - if (kdyn == 1 .or. kdyn == 3) then - write(nu_diag,*) 'yield_curve = ', trim(yield_curve) - if (trim(yield_curve) == 'ellipse') & - write(nu_diag,1007) ' e_ratio = ', e_ratio, ' aspect ratio of ellipse' - endif + if (kdyn == 1 .or. kdyn == 3) then + write(nu_diag,1030) ' yield_curve = ', trim(yield_curve) + if (trim(yield_curve) == 'ellipse') & + write(nu_diag,1002) ' e_ratio = ', e_ratio, ' : aspect ratio of ellipse' + endif if (trim(coriolis) == 'latitude') then - tmpstr2 = ': latitude-dependent Coriolis parameter' + tmpstr2 = ' : latitude-dependent Coriolis parameter' elseif (trim(coriolis) == 'contant') then - tmpstr2 = ' = 1.46e-4/s' + tmpstr2 = ' : = 1.46e-4/s' elseif (trim(coriolis) == 'zero') then - tmpstr2 = ' = 0.0' + tmpstr2 = ' : = 0.0' else tmpstr2 = ': unknown value' endif - write(nu_diag,*) 'coriolis = ',trim(coriolis),trim(tmpstr2) + write(nu_diag,1030) ' coriolis = ',trim(coriolis),trim(tmpstr2) if (trim(ssh_stress) == 'geostrophic') then - tmpstr2 = ': from ocean velocity' + tmpstr2 = ' : from ocean velocity' elseif (trim(ssh_stress) == 'coupled') then - tmpstr2 = ': from coupled sea surface height gradients' + tmpstr2 = ' : from coupled sea surface height gradients' else - tmpstr2 = ': unknown value' + tmpstr2 = ' : unknown value' endif - write(nu_diag,*) 'ssh_stress = ',trim(ssh_stress),trim(tmpstr2) + write(nu_diag,1030) ' ssh_stress = ',trim(ssh_stress),trim(tmpstr2) if (ktransport <= 0) then advection = 'none' endif if (trim(advection) == 'remap') then - tmpstr2 = ': linear remapping advection' + tmpstr2 = ' : linear remapping advection' elseif (trim(advection) == 'upwind') then - tmpstr2 = ': donor cell (upwind) advection' + tmpstr2 = ' : donor cell (upwind) advection' elseif (trim(advection) == 'none') then - tmpstr2 = ': advection disabled by ktransport namelist' + tmpstr2 = ' : advection disabled by ktransport namelist' else - tmpstr2 = ': unknown value' + tmpstr2 = ' : unknown value' endif - write(nu_diag,*) 'advection = ', trim(advection),trim(tmpstr2) + write(nu_diag,1030) ' advection = ', trim(advection),trim(tmpstr2) if (basalstress) then - tmpstr2 = ' use basal stress parameterization for landfast ice' + tmpstr2 = ' : use basal stress parameterization for landfast ice' else - tmpstr2 = ' basal stress not used for landfast ice' + tmpstr2 = ' : no basal stress parameterization' endif - write(nu_diag,1012) ' basalstress = ', basalstress,trim(tmpstr2) + write(nu_diag,1010) ' basalstress = ', basalstress,trim(tmpstr2) if (basalstress) then - write(nu_diag,1007) ' k1 = ', k1, ' free parameter for landfast ice' - write(nu_diag,1007) ' k2 = ', k2, ' free parameter for landfast ice' - write(nu_diag,1007) ' alphab = ', alphab, ' factor for landfast ice' - write(nu_diag,1007) ' threshold_hw = ', threshold_hw, ' max water depth for grounding ice' + write(nu_diag,1002) ' k1 = ', k1, ' : free parameter for landfast ice' + write(nu_diag,1002) ' k2 = ', k2, ' : free parameter for landfast ice' + write(nu_diag,1002) ' alphab = ', alphab, ' : factor for landfast ice' + write(nu_diag,1002) ' threshold_hw = ', threshold_hw, ' : max water depth for grounding ice' + endif + write(nu_diag,1002) ' Ktens = ', Ktens, ' : tensile strength factor' + + if (kdyn == 3) then + write(nu_diag,1020) ' maxits_nonlin = ', maxits_nonlin,' : max nb of iteration for nonlinear solver' + write(nu_diag,1030) ' precond = ', trim(precond),' : preconditioner for FGMRES' + write(nu_diag,1020) ' dim_fgmres = ', dim_fgmres,' : size of FGMRES Krylov subspace' + write(nu_diag,1020) ' dim_pgmres = ', dim_pgmres,' : size of PGMRES Krylov subspace' + write(nu_diag,1020) ' maxits_fgmres = ', maxits_fgmres,' : max nb of iteration for FGMRES' + write(nu_diag,1020) ' maxits_pgmres = ', maxits_pgmres,' : max nb of iteration for PGMRES' + write(nu_diag,1010) ' monitor_nonlin = ', monitor_nonlin,' : print nonlinear residual norm' + write(nu_diag,1010) ' monitor_fgmres = ', monitor_fgmres,' : print FGMRES residual norm' + write(nu_diag,1010) ' monitor_pgmres = ', monitor_pgmres,' : print PGMRES residual norm' + write(nu_diag,1030) ' ortho_type = ', trim(ortho_type),' : type of orthogonalization for FGMRES' + write(nu_diag,1009) ' reltol_nonlin = ', reltol_nonlin,' : nonlinear stopping criterion' + write(nu_diag,1009) ' reltol_fgmres = ', reltol_fgmres,' : FGMRES stopping criterion' + write(nu_diag,1009) ' reltol_pgmres = ', reltol_pgmres,' : PGMRES stopping criterion' + write(nu_diag,1030) ' algo_nonlin = ', trim(algo_nonlin),' : nonlinear algorithm' + write(nu_diag,1010) ' use_mean_vrel = ', use_mean_vrel,' : use mean of previous 2 iterates to compute vrel' + if (algo_nonlin == 'anderson') then + write(nu_diag,1020) ' fpfunc_andacc = ', fpfunc_andacc,' : fixed point function for Anderson acceleration' + write(nu_diag,1020) ' dim_andacc = ', dim_andacc,' : size of Anderson minimization matrix' + write(nu_diag,1009) ' reltol_andacc = ', reltol_andacc,' : relative tolerance for Anderson acceleration' + write(nu_diag,1000) ' damping_andacc = ', damping_andacc,' : damping factor for Anderson acceleration' + write(nu_diag,1020) ' start_andacc = ', start_andacc,' : nonlinear iteration at which acceleration starts' + endif endif - write(nu_diag,1007) ' Ktens = ', Ktens, ' tensile strength factor' + endif ! kdyn enabled write(nu_diag,*) ' ' write(nu_diag,*) ' Mechanical Deformation (Ridging) and Ice Strength' write(nu_diag,*) '--------------------------------------------------' if (kridge == 1) then - tmpstr2 = ' ridging enabled' + tmpstr2 = ' : ridging enabled' else - tmpstr2 = ' ridging disabled' + tmpstr2 = ' : ridging disabled' endif - write(nu_diag,1012) ' tr_lvl = ', tr_lvl,' ridging related tracers' - write(nu_diag,1022) ' kridge = ', kridge,trim(tmpstr2) + write(nu_diag,1010) ' tr_lvl = ', tr_lvl,' : ridging related tracers' + write(nu_diag,1020) ' kridge = ', kridge,trim(tmpstr2) if (kridge == 1) then if (krdg_partic == 1) then - tmpstr2 = ' new participation function' + tmpstr2 = ' : new participation function' else - tmpstr2 = ' old participation function' + tmpstr2 = ' : old participation function' endif - write(nu_diag,1022) ' krdg_partic = ', krdg_partic,trim(tmpstr2) + write(nu_diag,1020) ' krdg_partic = ', krdg_partic,trim(tmpstr2) if (krdg_partic == 1) & - write(nu_diag,1007) ' mu_rdg = ', mu_rdg,' e-folding scale of ridged ice' + write(nu_diag,1002) ' mu_rdg = ', mu_rdg,' : e-folding scale of ridged ice' if (krdg_redist == 1) then - tmpstr2 = ' new redistribution function' + tmpstr2 = ' : new redistribution function' else - tmpstr2 = ' old redistribution function' + tmpstr2 = ' : old redistribution function' endif - write(nu_diag,1022) ' krdg_redist = ', krdg_redist,trim(tmpstr2) + write(nu_diag,1020) ' krdg_redist = ', krdg_redist,trim(tmpstr2) endif if (kstrength == 0) then - tmpstr2 = ' Hibler (1979)' + tmpstr2 = ' : Hibler (1979)' elseif (kstrength == 1) then - tmpstr2 = ' Rothrock (1975)' + tmpstr2 = ' : Rothrock (1975)' else - tmpstr2 = ': unknown value' + tmpstr2 = ' : unknown value' endif - write(nu_diag,1022) ' kstrength = ', kstrength,trim(tmpstr2) + write(nu_diag,1020) ' kstrength = ', kstrength,trim(tmpstr2) if (kstrength == 0) then - write(nu_diag,1009) ' Pstar = ', Pstar, ' P* strength factor' - write(nu_diag,1007) ' Cstar = ', Cstar, ' C* strength exponent factor' + write(nu_diag,1009) ' Pstar = ', Pstar, ' : P* strength factor' + write(nu_diag,1002) ' Cstar = ', Cstar, ' : C* strength exponent factor' elseif (kstrength == 1) then - write(nu_diag,1007) ' Cf = ', Cf, ' ratio of ridging work to PE change' + write(nu_diag,1002) ' Cf = ', Cf, ' : ratio of ridging work to PE change' endif write(nu_diag,*) ' ' @@ -1356,202 +1374,206 @@ subroutine input_data write(nu_diag,*) '--------------------------------' if (ktherm == 1) then - tmpstr2 = ' Bitz and Lipscomb 1999 thermo' + tmpstr2 = ' : Bitz and Lipscomb 1999 thermo' elseif (ktherm == 2) then - tmpstr2 = ' mushy-layer thermo' + tmpstr2 = ' : mushy-layer thermo' elseif (ktherm == 0) then - tmpstr2 = ' zero-layer thermo' + tmpstr2 = ' : zero-layer thermo' elseif (ktherm < 0) then - tmpstr2 = ' thermodynamics disabled' + tmpstr2 = ' : Thermodynamics disabled' else - tmpstr2 = ': unknown value' + tmpstr2 = ' : unknown value' endif + write(nu_diag,1020) ' ktherm = ', ktherm,trim(tmpstr2) if (ktherm >= 0) then - write(nu_diag,1022) ' ktherm = ', ktherm,trim(tmpstr2) - write(nu_diag,1002) ' dt = ', dt, ' thermodynamic time step' - write(nu_diag,1007) ' ksno = ', ksno,' snow thermal conductivity' + write(nu_diag,1002) ' dt = ', dt, ' : thermodynamic time step' + write(nu_diag,1002) ' ksno = ', ksno,' : snow thermal conductivity' if (ktherm == 1) & - write(nu_diag,*) 'conduct = ', trim(conduct),' ice thermal conductivity' - write(nu_diag,1012) ' sw_redist = ', sw_redist,' redistribute internal shortwave to surface' - write(nu_diag,1002) ' sw_frac = ', sw_frac,' fraction redistributed' - write(nu_diag,1002) ' sw_dtemp = ', sw_dtemp,' temperature difference from freezing to redistribute' + write(nu_diag,1030) ' conduct = ', trim(conduct),' : ice thermal conductivity' if (ktherm == 2) then - write(nu_diag,1002) ' a_rapid_mode = ', a_rapid_mode,' brine channel diameter' - write(nu_diag,1007) ' Rac_rapid_mode = ', Rac_rapid_mode,' critical Rayleigh number' - write(nu_diag,1007) ' aspect_rapid_mode= ', aspect_rapid_mode,' brine convection aspect ratio' - write(nu_diag,*) 'dSdt_slow_mode = ', dSdt_slow_mode,' drainage strength parameter' - write(nu_diag,1007) ' phi_c_slow_mode = ', phi_c_slow_mode,' critical liquid fraction' - write(nu_diag,1007) ' phi_i_mushy = ', phi_i_mushy,' solid fraction at lower boundary' + write(nu_diag,1002) ' a_rapid_mode = ', a_rapid_mode,' : brine channel diameter' + write(nu_diag,1002) ' Rac_rapid_mode = ', Rac_rapid_mode,' : critical Rayleigh number' + write(nu_diag,1002) ' aspect_rapid_mode= ', aspect_rapid_mode,' : brine convection aspect ratio' + write(nu_diag,1009) ' dSdt_slow_mode = ', dSdt_slow_mode,' : drainage strength parameter' + write(nu_diag,1002) ' phi_c_slow_mode = ', phi_c_slow_mode,' : critical liquid fraction' + write(nu_diag,1002) ' phi_i_mushy = ', phi_i_mushy,' : solid fraction at lower boundary' endif - endif - write(nu_diag,1007) ' hfrazilmin = ', hfrazilmin,' minimum new frazil ice thickness' - - write(nu_diag,*) ' ' - write(nu_diag,*) ' Radiation' - write(nu_diag,*) '--------------------------------' - if (trim(shortwave) == 'dEdd') then - tmpstr2 = ': delta-Eddington multiple-scattering method' - elseif (trim(shortwave) == 'ccsm3') then - tmpstr2 = ': NCAR CCSM3 distribution method' - else - tmpstr2 = ': unknown value' - endif - write(nu_diag,*) ' shortwave = ', trim(shortwave),trim(tmpstr2) - if (trim(shortwave) == 'dEdd') then - write(nu_diag,1007) ' R_ice = ', R_ice,' tuning parameter for sea ice albedo' - write(nu_diag,1007) ' R_pnd = ', R_pnd,' tuning parameter for ponded sea ice albedo' - write(nu_diag,1007) ' R_snw = ', R_snw,' tuning parameter for snow broadband albedo' - write(nu_diag,1007) ' dT_mlt = ', dT_mlt,' change in temperature per change in snow grain radius' - write(nu_diag,1002) ' rsnw_mlt = ', rsnw_mlt,' maximum melting snow grain radius' - write(nu_diag,1007) ' kalg = ', kalg,' absorption coefficient for algae' - else - if (trim(albedo_type) == 'ccsm3') then - tmpstr2 = ': NCAR CCSM3 albedos' - elseif (trim(albedo_type) == 'constant') then - tmpstr2 = ': four constant albedos' + write(nu_diag,1002) ' hfrazilmin = ', hfrazilmin,' : minimum new frazil ice thickness' + + write(nu_diag,*) ' ' + write(nu_diag,*) ' Radiation' + write(nu_diag,*) '--------------------------------' + if (trim(shortwave) == 'dEdd') then + tmpstr2 = ' : delta-Eddington multiple-scattering method' + elseif (trim(shortwave) == 'ccsm3') then + tmpstr2 = ' : NCAR CCSM3 distribution method' else - tmpstr2 = ': unknown value' + tmpstr2 = ' : unknown value' + endif + write(nu_diag,1030) ' shortwave = ', trim(shortwave),trim(tmpstr2) + if (trim(shortwave) == 'dEdd') then + write(nu_diag,1002) ' R_ice = ', R_ice,' : tuning parameter for sea ice albedo' + write(nu_diag,1002) ' R_pnd = ', R_pnd,' : tuning parameter for ponded sea ice albedo' + write(nu_diag,1002) ' R_snw = ', R_snw,' : tuning parameter for snow broadband albedo' + write(nu_diag,1002) ' dT_mlt = ', dT_mlt,' : change in temperature per change in snow grain radius' + write(nu_diag,1002) ' rsnw_mlt = ', rsnw_mlt,' : maximum melting snow grain radius' + write(nu_diag,1002) ' kalg = ', kalg,' : absorption coefficient for algae' + else + if (trim(albedo_type) == 'ccsm3') then + tmpstr2 = ' : NCAR CCSM3 albedos' + elseif (trim(albedo_type) == 'constant') then + tmpstr2 = ' : four constant albedos' + else + tmpstr2 = ' : unknown value' + endif + write(nu_diag,1030) ' albedo_type = ', trim(albedo_type),trim(tmpstr2) + if (trim(albedo_type) == 'ccsm3') then + write(nu_diag,1002) ' albicev = ', albicev,' : visible ice albedo for thicker ice' + write(nu_diag,1002) ' albicei = ', albicei,' : near infrared ice albedo for thicker ice' + write(nu_diag,1002) ' albsnowv = ', albsnowv,' : visible, cold snow albedo' + write(nu_diag,1002) ' albsnowi = ', albsnowi,' : near infrared, cold snow albedo' + write(nu_diag,1002) ' ahmax = ', ahmax,' : albedo is constant above this thickness' + write(nu_diag,1002) ' ahmax = ', ahmax,' : albedo is constant above this thickness' + endif endif - write(nu_diag,*) 'albedo_type = ', trim(albedo_type),trim(tmpstr2) - if (trim(albedo_type) == 'ccsm3') then - write(nu_diag,1007) ' albicev = ', albicev,' visible ice albedo for thicker ice' - write(nu_diag,1007) ' albicei = ', albicei,' near infrared ice albedo for thicker ice' - write(nu_diag,1007) ' albsnowv = ', albsnowv,' visible, cold snow albedo' - write(nu_diag,1007) ' albsnowi = ', albsnowi,' near infrared, cold snow albedo' - write(nu_diag,1007) ' ahmax = ', ahmax,' albedo is constant above this thickness' + write(nu_diag,1002) ' emissivity = ', emissivity,' : emissivity of snow and ice' + write(nu_diag,1010) ' sw_redist = ', sw_redist,' : redistribute internal shortwave to surface' + if (sw_redist) then + write(nu_diag,1002) ' sw_frac = ', sw_frac,' : fraction redistributed' + write(nu_diag,1002) ' sw_dtemp = ', sw_dtemp,' : temperature difference from freezing to redistribute' endif endif - write(nu_diag,1007) ' emissivity = ', emissivity,' emissivity of snow and ice' write(nu_diag,*) ' ' write(nu_diag,*) ' Atmospheric Forcing / Coupling' write(nu_diag,*) '--------------------------------' - write(nu_diag,1012) ' calc_Tsfc = ', calc_Tsfc,' calculate surface temperature as part of thermo' - write(nu_diag,1012) ' calc_strair = ', calc_strair,' calculate wind stress and speed' - write(nu_diag,1012) ' rotate_wind = ', rotate_wind,' rotate wind/stress to computational grid' - write(nu_diag,1012) ' formdrag = ', formdrag,' use form drag parameterization' + write(nu_diag,1010) ' calc_Tsfc = ', calc_Tsfc,' : calculate surface temperature as part of thermo' + write(nu_diag,1010) ' calc_strair = ', calc_strair,' : calculate wind stress and speed' + write(nu_diag,1010) ' rotate_wind = ', rotate_wind,' : rotate wind/stress to computational grid' + write(nu_diag,1010) ' formdrag = ', formdrag,' : use form drag parameterization' if (trim(atmbndy) == 'default') then - tmpstr2 = ': stability-based boundary layer' - write(nu_diag,1012) ' highfreq = ', highfreq,' high-frequency atmospheric coupling' - write(nu_diag,1022) ' natmiter = ', natmiter,' number of atmo boundary layer iterations' - write(nu_diag,1006) ' atmiter_conv = ', atmiter_conv,' convergence criterion for ustar' + tmpstr2 = ' : stability-based boundary layer' + write(nu_diag,1010) ' highfreq = ', highfreq,' : high-frequency atmospheric coupling' + write(nu_diag,1020) ' natmiter = ', natmiter,' : number of atmo boundary layer iterations' + write(nu_diag,1002) ' atmiter_conv = ', atmiter_conv,' : convergence criterion for ustar' elseif (trim(atmbndy) == 'constant') then - tmpstr2 = ': boundary layer uses bulk transfer coefficients' + tmpstr2 = ' : boundary layer uses bulk transfer coefficients' else - tmpstr2 = ': unknown value' + tmpstr2 = ' : unknown value' endif - write(nu_diag,*) 'atmbndy = ', trim(atmbndy),trim(tmpstr2) + write(nu_diag,1030) ' atmbndy = ', trim(atmbndy),trim(tmpstr2) write(nu_diag,*) ' ' write(nu_diag,*) ' Oceanic Forcing / Coupling' write(nu_diag,*) '--------------------------------' if (oceanmixed_ice) then - tmpstr2 = ' ocean mixed layer calculation (SST) enabled' + tmpstr2 = ' : ocean mixed layer calculation (SST) enabled' else - tmpstr2 = ' ocean mixed layer calculation (SST) disabled' + tmpstr2 = ' : ocean mixed layer calculation (SST) disabled' endif - write(nu_diag,1012) ' oceanmixed_ice = ', oceanmixed_ice,trim(tmpstr2) + write(nu_diag,1010) ' oceanmixed_ice = ', oceanmixed_ice,trim(tmpstr2) if (oceanmixed_ice) then write(nu_diag,*) ' WARNING: ocean mixed layer ON' write(nu_diag,*) ' WARNING: will impact ocean forcing interaction' write(nu_diag,*) ' WARNING: coupled forcing will be modified by mixed layer routine' endif if (trim(tfrz_option) == 'minus1p8') then - tmpstr2 = ': constant ocean freezing temperature (-1.8C)' + tmpstr2 = ' : constant ocean freezing temperature (-1.8C)' elseif (trim(tfrz_option) == 'linear_salt') then - tmpstr2 = ': linear function of salinity (use with ktherm=1)' + tmpstr2 = ' : linear function of salinity (use with ktherm=1)' elseif (trim(tfrz_option) == 'mushy') then - tmpstr2 = ': Assur (1958) as in mushy-layer thermo (ktherm=2)' + tmpstr2 = ' : Assur (1958) as in mushy-layer thermo (ktherm=2)' else - tmpstr2 = ': unknown value' + tmpstr2 = ' : unknown value' endif - write(nu_diag,*) 'tfrz_option = ', trim(tfrz_option),trim(tmpstr2) + write(nu_diag,1030) ' tfrz_option = ', trim(tfrz_option),trim(tmpstr2) if (update_ocn_f) then - tmpstr2 = ' frazil water/salt fluxes included in ocean fluxes' + tmpstr2 = ' : frazil water/salt fluxes included in ocean fluxes' else - tmpstr2 = ' frazil water/salt fluxes not included in ocean fluxes' + tmpstr2 = ' : frazil water/salt fluxes not included in ocean fluxes' endif - write(nu_diag,1012) ' update_ocn_f = ', update_ocn_f,trim(tmpstr2) + write(nu_diag,1010) ' update_ocn_f = ', update_ocn_f,trim(tmpstr2) if (l_mpond_fresh .and. tr_pond_topo) then - tmpstr2 = ' retain (topo) pond water until ponds drain' + tmpstr2 = ' : retain (topo) pond water until ponds drain' else - tmpstr2 = ' pond water not retained on ice (virtual only)' + tmpstr2 = ' : pond water not retained on ice (virtual only)' endif - write(nu_diag,1012) ' l_mpond_fresh = ', l_mpond_fresh,trim(tmpstr2) + write(nu_diag,1010) ' l_mpond_fresh = ', l_mpond_fresh,trim(tmpstr2) if (trim(fbot_xfer_type) == 'constant') then - tmpstr2 = ': ocean heat transfer coefficient is constant' + tmpstr2 = ' : ocean heat transfer coefficient is constant' elseif (trim(fbot_xfer_type) == 'Cdn_ocn') then - tmpstr2 = ': variable ocean heat transfer coefficient' ! only used with form_drag=T? + tmpstr2 = ' : variable ocean heat transfer coefficient' ! only used with form_drag=T? else - tmpstr2 = ': unknown value' + tmpstr2 = ' : unknown value' endif - write(nu_diag,*) 'fbot_xfer_type = ', trim(fbot_xfer_type),trim(tmpstr2) - write(nu_diag,1006) ' ustar_min = ', ustar_min,' minimum value of ocean friction velocity' + write(nu_diag,1030) ' fbot_xfer_type = ', trim(fbot_xfer_type),trim(tmpstr2) + write(nu_diag,1000) ' ustar_min = ', ustar_min,' : minimum value of ocean friction velocity' if (tr_fsd) then - if (wave_spec) then - tmpstr2 = ' use wave spectrum for floe size distribution' - else - tmpstr2 = ' floe size distribution does not use wave spectrum' - endif - write(nu_diag,1012) ' wave_spec = ', wave_spec,trim(tmpstr2) - if (wave_spec) then - if (trim(wave_spec_type) == 'none') then - tmpstr2 = ': no wave data provided, no wave-ice interactions' - elseif (trim(wave_spec_type) == 'profile') then - tmpstr2 = ': use fixed dummy wave spectrum for testing' - elseif (trim(wave_spec_type) == 'constant') then - tmpstr2 = ': constant wave spectrum data file provided for testing' - elseif (trim(wave_spec_type) == 'random') then - tmpstr2 = ': wave data file provided, spectrum generated using random number' + write(nu_diag,1002) ' floediam = ', floediam, ' constant floe diameter' + if (wave_spec) then + tmpstr2 = ' : use wave spectrum for floe size distribution' else - tmpstr2 = ': unknown value' + tmpstr2 = ' : floe size distribution does not use wave spectrum' endif - write(nu_diag,*) 'wave_spec_type = ', trim(wave_spec_type),trim(tmpstr2) - endif - write(nu_diag,1022) ' nfreq = ', nfreq,' number of wave spectral forcing frequencies' + write(nu_diag,1010) ' wave_spec = ', wave_spec,trim(tmpstr2) + if (wave_spec) then + if (trim(wave_spec_type) == 'none') then + tmpstr2 = ' : no wave data provided, no wave-ice interactions' + elseif (trim(wave_spec_type) == 'profile') then + tmpstr2 = ' : use fixed dummy wave spectrum for testing' + elseif (trim(wave_spec_type) == 'constant') then + tmpstr2 = ' : constant wave spectrum data file provided for testing' + elseif (trim(wave_spec_type) == 'random') then + tmpstr2 = ' : wave data file provided, spectrum generated using random number' + else + tmpstr2 = ' : unknown value' + endif + write(nu_diag,1030) ' wave_spec_type = ', trim(wave_spec_type),trim(tmpstr2) + endif + write(nu_diag,1020) ' nfreq = ', nfreq,' : number of wave spectral forcing frequencies' endif write(nu_diag,*) ' ' write(nu_diag,*) ' Age related tracers' write(nu_diag,*) '--------------------------------' - write(nu_diag,1012) ' tr_iage = ', tr_iage,' chronological ice age' - write(nu_diag,1012) ' tr_FY = ', tr_FY,' first-year ice area' + write(nu_diag,1010) ' tr_iage = ', tr_iage,' : chronological ice age' + write(nu_diag,1010) ' tr_FY = ', tr_FY,' : first-year ice area' write(nu_diag,*) ' ' write(nu_diag,*) ' Melt ponds' write(nu_diag,*) '--------------------------------' if (tr_pond_cesm) then - write(nu_diag,1012) ' tr_pond_cesm = ', tr_pond_cesm,' CESM pond formulation' - write(nu_diag,1007) ' pndaspect = ', pndaspect + write(nu_diag,1010) ' tr_pond_cesm = ', tr_pond_cesm,' : CESM pond formulation' + write(nu_diag,1002) ' pndaspect = ', pndaspect,' : ratio of pond depth to area fraction' elseif (tr_pond_lvl) then - write(nu_diag,1012) ' tr_pond_lvl = ', tr_pond_lvl,' level-ice pond formulation' - write(nu_diag,1007) ' pndaspect = ', pndaspect - write(nu_diag,1006) ' dpscale = ', dpscale,' time scale for flushing in permeable ice' + write(nu_diag,1010) ' tr_pond_lvl = ', tr_pond_lvl,' : level-ice pond formulation' + write(nu_diag,1002) ' pndaspect = ', pndaspect,' : ratio of pond depth to area fraction' + write(nu_diag,1000) ' dpscale = ', dpscale,' : time scale for flushing in permeable ice' if (trim(frzpnd) == 'hlid') then - tmpstr2 = ': Stefan refreezing with pond ice thickness' + tmpstr2 = ' : Stefan refreezing with pond ice thickness' elseif (trim(frzpnd) == 'cesm') then - tmpstr2 = ': CESM refreezing empirical formula' + tmpstr2 = ' : CESM refreezing empirical formula' else - tmpstr2 = ': unknown value' + tmpstr2 = ' : unknown value' endif - write(nu_diag,*) ' frzpnd = ', trim(frzpnd),trim(tmpstr2) - write(nu_diag,1007) ' hs1 = ', hs1,' snow depth of transition to pond ice' + write(nu_diag,1030) ' frzpnd = ', trim(frzpnd),trim(tmpstr2) + write(nu_diag,1002) ' hs1 = ', hs1,' : snow depth of transition to pond ice' elseif (tr_pond_topo) then - write(nu_diag,1012) ' tr_pond_topo = ', tr_pond_topo,' topo pond formulation' - write(nu_diag,1007) ' hp1 = ', hp1,' critical ice lid thickness for topo ponds' + write(nu_diag,1010) ' tr_pond_topo = ', tr_pond_topo,' : topo pond formulation' + write(nu_diag,1002) ' hp1 = ', hp1,' : critical ice lid thickness for topo ponds' elseif (trim(shortwave) == 'ccsm3') then write(nu_diag,*) 'Pond effects on radiation are treated implicitly in the ccsm3 shortwave scheme' else - write(nu_diag,*) ' Using default dEdd melt pond scheme for testing only' + write(nu_diag,*) 'Using default dEdd melt pond scheme for testing only' endif if (trim(shortwave) == 'dEdd') then - write(nu_diag,1007) ' hs0 = ', hs0,' snow depth of transition to bare sea ice' + write(nu_diag,1002) ' hs0 = ', hs0,' : snow depth of transition to bare sea ice' endif - write(nu_diag,1007) ' rfracmin = ', rfracmin,' minimum fraction of melt water added to ponds' - write(nu_diag,1007) ' rfracmax = ', rfracmax,' maximum fraction of melt water added to ponds' + write(nu_diag,1002) ' rfracmin = ', rfracmin,' : minimum fraction of melt water added to ponds' + write(nu_diag,1002) ' rfracmax = ', rfracmax,' : maximum fraction of melt water added to ponds' write(nu_diag,*) ' ' write(nu_diag,*) ' Primary state variables, tracers' @@ -1560,191 +1582,135 @@ subroutine input_data write(nu_diag,*) 'Conserved properties (all tracers are conserved):' write(nu_diag,*) 'ice concentration, volume and enthalpy' write(nu_diag,*) 'snow volume and enthalpy' - if (ktherm == 2) write(nu_diag,*) 'ice salinity' - if (tr_fsd) write(nu_diag,1012) ' tr_fsd = ', tr_fsd,' floe size distribution' - if (tr_lvl) write(nu_diag,1012) ' tr_lvl = ', tr_lvl,' ridging related tracers' - if (tr_pond_lvl) write(nu_diag,1012) ' tr_pond_lvl = ', tr_pond_lvl,' level-ice pond formulation' - if (tr_pond_topo) write(nu_diag,1012) ' tr_pond_topo = ', tr_pond_topo,' topo pond formulation' - if (tr_pond_cesm) write(nu_diag,1012) ' tr_pond_cesm = ', tr_pond_cesm,' CESM pond formulation' - if (tr_iage) write(nu_diag,1012) ' tr_iage = ', tr_iage,' chronological ice age' - if (tr_FY) write(nu_diag,1012) ' tr_FY = ', tr_FY,' first-year ice area' - if (tr_iso) write(nu_diag,1012) ' tr_iso = ', tr_iso,' diagnostic isotope tracers' - if (tr_aero) write(nu_diag,1012) ' tr_aero = ', tr_aero,' CESM aerosol tracers' + if (ktherm == 2) write(nu_diag,1030) ' ice salinity' + if (tr_fsd) write(nu_diag,1010) ' tr_fsd = ', tr_fsd,' : floe size distribution' + if (tr_lvl) write(nu_diag,1010) ' tr_lvl = ', tr_lvl,' : ridging related tracers' + if (tr_pond_lvl) write(nu_diag,1010) ' tr_pond_lvl = ', tr_pond_lvl,' : level-ice pond formulation' + if (tr_pond_topo) write(nu_diag,1010) ' tr_pond_topo = ', tr_pond_topo,' : topo pond formulation' + if (tr_pond_cesm) write(nu_diag,1010) ' tr_pond_cesm = ', tr_pond_cesm,' : CESM pond formulation' + if (tr_iage) write(nu_diag,1010) ' tr_iage = ', tr_iage,' : chronological ice age' + if (tr_FY) write(nu_diag,1010) ' tr_FY = ', tr_FY,' : first-year ice area' + if (tr_iso) write(nu_diag,1010) ' tr_iso = ', tr_iso,' : diagnostic isotope tracers' + if (tr_aero) write(nu_diag,1010) ' tr_aero = ', tr_aero,' : CESM aerosol tracers' write(nu_diag,*) 'Non-conserved properties:' write(nu_diag,*) 'ice surface temperature' write(nu_diag,*) 'ice velocity components and internal stress' write(nu_diag,*) ' ' write(nu_diag,*) ' Other ice_in namelist parameters:' - write(nu_diag,*) ' ==================================== ' - write(nu_diag,*) ' ' + write(nu_diag,*) '===================================== ' if (trim(runid) /= 'unknown') & - write(nu_diag,*) ' runid = ', & - trim(runid) - write(nu_diag,1030) ' runtype = ', & - trim(runtype) - write(nu_diag,1020) ' year_init = ', year_init - write(nu_diag,1020) ' istep0 = ', istep0 - write(nu_diag,1020) ' npt = ', npt - write(nu_diag,1020) ' diagfreq = ', diagfreq - write(nu_diag,1010) ' print_global = ', print_global - write(nu_diag,1010) ' print_points = ', print_points - write(nu_diag,1030) ' bfbflag = ', bfbflag - write(nu_diag,1020) ' numin = ', numin - write(nu_diag,1020) ' numax = ', numax - write(nu_diag,1050) ' histfreq = ', histfreq(:) - write(nu_diag,1040) ' histfreq_n = ', histfreq_n(:) - write(nu_diag,1010) ' hist_avg = ', hist_avg - if (.not. hist_avg) write(nu_diag,*) ' History data will be snapshots' - write(nu_diag,*) ' history_dir = ', & - trim(history_dir) - write(nu_diag,*) ' history_file = ', & - trim(history_file) - write(nu_diag,1020) ' history_precision = ', history_precision - write(nu_diag,*) ' history_format = ', & - trim(history_format) + write(nu_diag,1031) ' runid = ', trim(runid) + write(nu_diag,1031) ' runtype = ', trim(runtype) + write(nu_diag,1021) ' year_init = ', year_init + write(nu_diag,1021) ' istep0 = ', istep0 + write(nu_diag,1021) ' npt = ', npt + write(nu_diag,1021) ' diagfreq = ', diagfreq + write(nu_diag,1011) ' print_global = ', print_global + write(nu_diag,1011) ' print_points = ', print_points + write(nu_diag,1031) ' bfbflag = ', trim(bfbflag) + write(nu_diag,1021) ' numin = ', numin + write(nu_diag,1021) ' numax = ', numax + write(nu_diag,1033) ' histfreq = ', histfreq(:) + write(nu_diag,1023) ' histfreq_n = ', histfreq_n(:) + write(nu_diag,1011) ' hist_avg = ', hist_avg + if (.not. hist_avg) write(nu_diag,1031) ' History data will be snapshots' + write(nu_diag,1031) ' history_dir = ', trim(history_dir) + write(nu_diag,1031) ' history_file = ', trim(history_file) + write(nu_diag,1021) ' history_precision= ', history_precision + write(nu_diag,1031) ' history_format = ', trim(history_format) if (write_ic) then - write(nu_diag,*) ' Initial condition will be written in ', & + write(nu_diag,1031) ' Initial condition will be written in ', & trim(incond_dir) endif - write(nu_diag,1030) ' dumpfreq = ', & - trim(dumpfreq) - write(nu_diag,1020) ' dumpfreq_n = ', dumpfreq_n - write(nu_diag,1010) ' dump_last = ', dump_last - write(nu_diag,1010) ' restart = ', restart - write(nu_diag,*) ' restart_dir = ', & - trim(restart_dir) - write(nu_diag,*) ' restart_ext = ', restart_ext - write(nu_diag,*) ' restart_coszen = ', restart_coszen - write(nu_diag,*) ' restart_format = ', & - trim(restart_format) - write(nu_diag,*) ' lcdf64 = ', & - lcdf64 - write(nu_diag,*) ' restart_file = ', & - trim(restart_file) - write(nu_diag,*) ' pointer_file = ', & - trim(pointer_file) - write(nu_diag,*) ' use_restart_time = ', use_restart_time - write(nu_diag,*) ' ice_ic = ', & - trim(ice_ic) + write(nu_diag,1031) ' dumpfreq = ', trim(dumpfreq) + write(nu_diag,1021) ' dumpfreq_n = ', dumpfreq_n + write(nu_diag,1011) ' dump_last = ', dump_last + write(nu_diag,1011) ' restart = ', restart + write(nu_diag,1031) ' restart_dir = ', trim(restart_dir) + write(nu_diag,1011) ' restart_ext = ', restart_ext + write(nu_diag,1011) ' restart_coszen = ', restart_coszen + write(nu_diag,1031) ' restart_format = ', trim(restart_format) + write(nu_diag,1011) ' lcdf64 = ', lcdf64 + write(nu_diag,1031) ' restart_file = ', trim(restart_file) + write(nu_diag,1031) ' pointer_file = ', trim(pointer_file) + write(nu_diag,1011) ' use_restart_time = ', use_restart_time + write(nu_diag,1031) ' ice_ic = ', trim(ice_ic) if (trim(grid_type) /= 'rectangular' .or. & trim(grid_type) /= 'column') then - write(nu_diag,*) ' grid_file = ', & - trim(grid_file) - write(nu_diag,*) ' gridcpl_file = ', & - trim(gridcpl_file) - write(nu_diag,*) ' bathymetry_file = ', & - trim(bathymetry_file) - write(nu_diag,*) ' kmt_file = ', & - trim(kmt_file) - endif - write(nu_diag,1010) ' close_boundaries = ', & - close_boundaries - write(nu_diag,1010) ' orca_halogrid = ', & - orca_halogrid - - if (kdyn == 3) then - write(nu_diag,1020) ' maxits_nonlin = ', maxits_nonlin - write(nu_diag,1030) ' precond = ', precond - write(nu_diag,1020) ' dim_fgmres = ', dim_fgmres - write(nu_diag,1020) ' dim_pgmres = ', dim_pgmres - write(nu_diag,1020) ' maxits_fgmres = ', maxits_fgmres - write(nu_diag,1020) ' maxits_pgmres = ', maxits_pgmres - write(nu_diag,1010) ' monitor_nonlin = ', monitor_nonlin - write(nu_diag,1010) ' monitor_fgmres = ', monitor_fgmres - write(nu_diag,1010) ' monitor_pgmres = ', monitor_pgmres - write(nu_diag,1030) ' ortho_type = ', ortho_type - write(nu_diag,1008) ' reltol_nonlin = ', reltol_nonlin - write(nu_diag,1008) ' reltol_fgmres = ', reltol_fgmres - write(nu_diag,1008) ' reltol_pgmres = ', reltol_pgmres - write(nu_diag,1030) ' algo_nonlin = ', algo_nonlin - write(nu_diag,1010) ' use_mean_vrel = ', use_mean_vrel - if (algo_nonlin == 'anderson') then - write(nu_diag,1020) ' fpfunc_andacc = ', fpfunc_andacc - write(nu_diag,1020) ' dim_andacc = ', dim_andacc - write(nu_diag,1008) ' reltol_andacc = ', reltol_andacc - write(nu_diag,1005) ' damping_andacc = ', damping_andacc - write(nu_diag,1020) ' start_andacc = ', start_andacc - endif + write(nu_diag,1031) ' grid_file = ', trim(grid_file) + write(nu_diag,1031) ' gridcpl_file = ', trim(gridcpl_file) + write(nu_diag,1031) ' bathymetry_file = ', trim(bathymetry_file) + write(nu_diag,1031) ' kmt_file = ', trim(kmt_file) endif + write(nu_diag,1011) ' orca_halogrid = ', orca_halogrid - write(nu_diag,1010) ' conserv_check = ', conserv_check + write(nu_diag,1011) ' conserv_check = ', conserv_check - write(nu_diag,1020) ' fyear_init = ', & - fyear_init - write(nu_diag,1020) ' ycycle = ', ycycle - write(nu_diag,*) ' atm_data_type = ', & - trim(atm_data_type) + write(nu_diag,1021) ' fyear_init = ', fyear_init + write(nu_diag,1021) ' ycycle = ', ycycle + write(nu_diag,1031) ' atm_data_type = ', trim(atm_data_type) if (trim(atm_data_type) /= 'default') then - write(nu_diag,*) ' atm_data_dir = ', & - trim(atm_data_dir) - write(nu_diag,*) ' precip_units = ', & - trim(precip_units) + write(nu_diag,1031) ' atm_data_dir = ', trim(atm_data_dir) + write(nu_diag,1031) ' precip_units = ', trim(precip_units) elseif (trim(atm_data_type)=='default') then - write(nu_diag,*) ' default_season = ', trim(default_season) + write(nu_diag,1031) ' default_season = ', trim(default_season) endif if (wave_spec) then - write(nu_diag,*) ' wave_spec_file = ', trim(wave_spec_file) + write(nu_diag,1031) ' wave_spec_file = ', trim(wave_spec_file) endif if (trim(bgc_data_type) == 'ncar' .or. & trim(ocn_data_type) == 'ncar') then - write(nu_diag,*) ' oceanmixed_file = ', & - trim(oceanmixed_file) + write(nu_diag,1031) ' oceanmixed_file = ', trim(oceanmixed_file) endif if (cpl_bgc) then - write(nu_diag,1000) ' BGC coupling is switched ON' + write(nu_diag,*) 'BGC coupling is switched ON' else - write(nu_diag,1000) ' BGC coupling is switched OFF' - endif - write(nu_diag,*) ' bgc_data_type = ', & - trim(bgc_data_type) - write(nu_diag,*) ' fe_data_type = ', & - trim(fe_data_type) - write(nu_diag,*) ' ice_data_type = ', & - trim(ice_data_type) - write(nu_diag,*) ' bgc_data_dir = ', & - trim(bgc_data_dir) - write(nu_diag,*) ' ocn_data_type = ', & - trim(ocn_data_type) + write(nu_diag,*) 'BGC coupling is switched OFF' + endif + write(nu_diag,1031) ' bgc_data_type = ', trim(bgc_data_type) + write(nu_diag,1031) ' fe_data_type = ', trim(fe_data_type) + write(nu_diag,1031) ' ice_data_type = ', trim(ice_data_type) + write(nu_diag,1031) ' bgc_data_dir = ', trim(bgc_data_dir) + write(nu_diag,1031) ' ocn_data_type = ', trim(ocn_data_type) if (trim(bgc_data_type) /= 'default' .or. & trim(ocn_data_type) /= 'default') then - write(nu_diag,*) ' ocn_data_dir = ', & - trim(ocn_data_dir) - write(nu_diag,1010) ' restore_ocn = ', & - restore_ocn + write(nu_diag,1031) ' ocn_data_dir = ', trim(ocn_data_dir) + write(nu_diag,1011) ' restore_ocn = ', restore_ocn endif - write(nu_diag,1010) ' restore_ice = ', & - restore_ice + write(nu_diag,1011) ' restore_ice = ', restore_ice if (restore_ice .or. restore_ocn) & - write(nu_diag,1020) ' trestore = ', trestore + write(nu_diag,1021) ' trestore = ', trestore write(nu_diag,*) ' ' - write(nu_diag,'(a30,2f8.2)') 'Diagnostic point 1: lat, lon =', & + write(nu_diag,'(a31,2f8.2)') 'Diagnostic point 1: lat, lon =', & latpnt(1), lonpnt(1) - write(nu_diag,'(a30,2f8.2)') 'Diagnostic point 2: lat, lon =', & + write(nu_diag,'(a31,2f8.2)') 'Diagnostic point 2: lat, lon =', & latpnt(2), lonpnt(2) + write(nu_diag,*) ' ' ! tracer restarts - write(nu_diag,1010) ' restart_age = ', restart_age - write(nu_diag,1010) ' restart_FY = ', restart_FY - write(nu_diag,1010) ' restart_lvl = ', restart_lvl - write(nu_diag,1010) ' restart_pond_cesm = ', restart_pond_cesm - write(nu_diag,1010) ' restart_pond_lvl = ', restart_pond_lvl - write(nu_diag,1010) ' restart_pond_topo = ', restart_pond_topo - write(nu_diag,1010) ' restart_iso = ', restart_iso - write(nu_diag,1010) ' restart_aero = ', restart_aero - write(nu_diag,1010) ' restart_fsd = ', restart_fsd - - write(nu_diag,1020) ' n_iso = ', n_iso - write(nu_diag,1020) ' n_aero = ', n_aero - write(nu_diag,1020) ' n_zaero = ', n_zaero - write(nu_diag,1020) ' n_algae = ', n_algae - write(nu_diag,1020) ' n_doc = ', n_doc - write(nu_diag,1020) ' n_dic = ', n_dic - write(nu_diag,1020) ' n_don = ', n_don - write(nu_diag,1020) ' n_fed = ', n_fed - write(nu_diag,1020) ' n_fep = ', n_fep + write(nu_diag,1011) ' restart_age = ', restart_age + write(nu_diag,1011) ' restart_FY = ', restart_FY + write(nu_diag,1011) ' restart_lvl = ', restart_lvl + write(nu_diag,1011) ' restart_pond_cesm= ', restart_pond_cesm + write(nu_diag,1011) ' restart_pond_lvl = ', restart_pond_lvl + write(nu_diag,1011) ' restart_pond_topo= ', restart_pond_topo + write(nu_diag,1011) ' restart_iso = ', restart_iso + write(nu_diag,1011) ' restart_aero = ', restart_aero + write(nu_diag,1011) ' restart_fsd = ', restart_fsd + + write(nu_diag,1021) ' n_iso = ', n_iso + write(nu_diag,1021) ' n_aero = ', n_aero + write(nu_diag,1021) ' n_zaero = ', n_zaero + write(nu_diag,1021) ' n_algae = ', n_algae + write(nu_diag,1021) ' n_doc = ', n_doc + write(nu_diag,1021) ' n_dic = ', n_dic + write(nu_diag,1021) ' n_don = ', n_don + write(nu_diag,1021) ' n_fed = ', n_fed + write(nu_diag,1021) ' n_fep = ', n_fep + write(nu_diag,*) ' ' endif ! my_task = master_task @@ -1815,20 +1781,17 @@ subroutine input_data if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) - 1000 format (a30,2x,f9.2) ! a30 to align formatted, unformatted statements - 1002 format (a20,1x,f7.2,a) - 1005 format (a30,2x,f12.6) ! float - 1006 format (a20,2x,f10.6,a) - 1007 format (a20,2x,f6.2,a) - 1008 format (a30,2x,d13.6) ! float, exponential notation - 1009 format (a20,2x,d13.6,a) ! float, exponential notation - 1010 format (a30,2x,l6) ! logical - 1012 format (a20,2x,l3,1x,a) ! logical - 1020 format (a30,2x,i6) ! integer - 1022 format (a20,2x,i3,1x,a) ! integer - 1030 format (a30, a8) ! character - 1040 format (a30,2x,6i6) ! integer - 1050 format (a30,2x,6a6) ! character + 1000 format (a20,1x,f13.6,1x,a) ! float + 1002 format (a20,5x,f9.2,1x,a) + 1009 format (a20,1x,d13.6,1x,a) + 1010 format (a20,8x,l6,1x,a) ! logical + 1011 format (a20,1x,l6) + 1020 format (a20,8x,i6,1x,a) ! integer + 1021 format (a20,1x,i6) + 1023 format (a20,1x,6i6) + 1030 format (a20,a14,1x,a) ! character + 1031 format (a20,1x,a,a) + 1033 format (a20,1x,6a6) end subroutine input_data diff --git a/cicecore/version.txt b/cicecore/version.txt index 83a606cb9..e16cf8bfe 100644 --- a/cicecore/version.txt +++ b/cicecore/version.txt @@ -1 +1 @@ -CICE 6.1.3 +CICE 6.1.4 diff --git a/configuration/scripts/ice_in b/configuration/scripts/ice_in index 5516b3c51..64060d245 100644 --- a/configuration/scripts/ice_in +++ b/configuration/scripts/ice_in @@ -108,9 +108,6 @@ dSdt_slow_mode = -5.0e-8 phi_c_slow_mode = 0.05 phi_i_mushy = 0.85 - sw_redist = .false. - sw_frac = 0.9d0 - sw_dtemp = 0.02d0 hfrazilmin = 0.05d0 floediam = 300.0d0 / @@ -172,6 +169,9 @@ dT_mlt = 1.5 rsnw_mlt = 1500. kalg = 0.6 + sw_redist = .false. + sw_frac = 0.9d0 + sw_dtemp = 0.02d0 / &ponds_nml diff --git a/doc/source/conf.py b/doc/source/conf.py index 8d0df9777..a7c6aa400 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -62,9 +62,9 @@ # built documents. # # The short X.Y version. -version = u'6.1.3' +version = u'6.1.4' # The full version, including alpha/beta/rc tags. -version = u'6.1.3' +version = u'6.1.4' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/user_guide/ug_case_settings.rst b/doc/source/user_guide/ug_case_settings.rst index b82afe52f..3cf271386 100644 --- a/doc/source/user_guide/ug_case_settings.rst +++ b/doc/source/user_guide/ug_case_settings.rst @@ -212,7 +212,6 @@ grid_nml "``bathymetry_file``", "string", "name of bathymetry file to be read", "‘unknown_bathymetry_file’" "``bathymetry_format``", "``default``", "NetCDF depth field", "‘default’" "", "``pop``", "pop thickness file in cm in ascii format", "" - "``close_boundaries``", "logical", "set land on edges of grid", "``.false.``" "``dxrect``", "real", "x-direction grid spacing for rectangular grid in cm", "0.0" "``dyrect``", "real", "y-direction grid spacing for rectangular grid in cm", "0.0" "``gridcpl_file``", "string", "input file for coupling grid info", "'unknown_gridcpl_file'" @@ -342,9 +341,6 @@ thermo_nml "``phi_c_slow_mode``", ":math:`0<\phi_c < 1`", "critical liquid fraction", "0.05" "``phi_i_mushy``", ":math:`0<\phi_i < 1`", "solid fraction at lower boundary", "0.85" "``Rac_rapid_mode``", "real", "critical Rayleigh number", "10.0" - "``sw_redist``", "logical", "redistribute internal shortwave to surface", "``.false.``" - "``sw_frac``", "real", "fraction redistributed", "0.9" - "``sw_dtemp``", "real", "temperature difference from melt to start redistributing", "0.02" "", "", "", "" .. _dynamics_nml: @@ -438,6 +434,9 @@ shortwave_nml "``R_snw``", "real", "tuning parameter for snow (broadband albedo) from Delta-Eddington shortwave", "1.5" "``shortwave``", "``ccsm3``", "NCAR CCSM3 shortwave distribution method", "``ccsm3``" "", "``dEdd``", "Delta-Eddington method", "" + "``sw_dtemp``", "real", "temperature difference from melt to start redistributing", "0.02" + "``sw_frac``", "real", "fraction redistributed", "0.9" + "``sw_redist``", "logical", "redistribute internal shortwave to surface", "``.false.``" "", "", "", "" ponds_nml diff --git a/icepack b/icepack index 77c523efc..3ca0dda63 160000 --- a/icepack +++ b/icepack @@ -1 +1 @@ -Subproject commit 77c523efc6515b065aad039ecd185b5f07c83783 +Subproject commit 3ca0dda63ccb60d1d9329fc37173210d03dc19a1 From a45765d8ddbc103bd9b43965fd16773dad28d53f Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Fri, 18 Dec 2020 13:04:06 -0800 Subject: [PATCH 07/18] update readthedocs requirements to deal with failing doc build (#545) --- doc/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/requirements.txt b/doc/requirements.txt index 8788d6ac3..218e06d1f 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,5 +1,5 @@ # # -sphinxcontrib-bibtex +sphinxcontrib-bibtex<2.0.0 # # From 2b10c11bc0e4ce06797626c9a1c071c61154be89 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Wed, 23 Dec 2020 15:06:40 -0800 Subject: [PATCH 08/18] Make JRA55 default forcing dataset (#533) * Update test suite, add complete set of jra55 tests. jra55 tests for different grids gx3 uses jra55_gx3 gx1 uses jra55_gx1 tx1 is already using jra55 by default (no changes to tests required) gbox* uses internal forcing, no jra55 data (no changes to tests required) remove ocn_data_dir='default' and bgc_data_dir='default' in set_nml.jra55* files because it causes the bgc tests to fail. the bgc tests work with WOA bgc forcing data with jra55 physics forcing data. iobinary tests must use the old gx3 binary forcing, the jra55_gx3 netcdf data causes an abort because iobinary is tested with netcdf turned off. the old gx3 data is NCAR_bulk in binary format. alt01 with jra55 uses the alt01a setting. the difference is that use_leap_years is set to false in alt01a. It's set to true by default in the jra55 datasets. * add wget of JRA55_gx3 forcing to travis yml * add set_nml.alt01a * Update options and tests to make JRA55 the default set_nml.gx3 and set_nml.gx1 are now JRA55 by default get rid of set_nml.jra55* files add set_nml.gx3ncarbulk and set_nml.gx1coreii which invokes prior forcing datasets modify the test suites to do identical tests but with new options, compare to prior implementation by creating a renamed regression baseline via a script and links to generate the new names. Use zz* for the new set_nml options temporarily just to make it easy to generate the new links (the zz ensures the new options are last in the list by alphabet) chmod -x all set_* files for consistency * rename zz test options this is done as a clean separate step so new baselines can be established to continue to evolve the test cases and allow regression testing * remove most old forcing test cases * rename alt01a to alt01 in test options and suite --- .travis.yml | 6 ++++- configuration/scripts/options/set_env.box2001 | 0 configuration/scripts/options/set_nml.alt01 | 1 + configuration/scripts/options/set_nml.box2001 | 0 configuration/scripts/options/set_nml.gbox80 | 0 configuration/scripts/options/set_nml.gx1 | 13 ++++++----- .../scripts/options/set_nml.gx1coreii | 9 ++++++++ configuration/scripts/options/set_nml.gx3 | 13 ++++++----- .../scripts/options/set_nml.gx3ncarbulk | 9 ++++++++ configuration/scripts/options/set_nml.jra55 | 17 -------------- .../scripts/options/set_nml.jra55_2008 | 17 -------------- .../scripts/options/set_nml.jra55_gx1 | 17 -------------- .../scripts/options/set_nml.jra55_gx1_2008 | 17 -------------- .../scripts/options/set_nml.jra55_gx3 | 17 -------------- .../scripts/options/set_nml.jra55_gx3_2008 | 17 -------------- configuration/scripts/options/set_nml.yi2008 | 3 +++ configuration/scripts/tests/base_suite.ts | 22 +++++++++++-------- configuration/scripts/tests/decomp_suite.ts | 2 +- configuration/scripts/tests/first_suite.ts | 6 ++--- configuration/scripts/tests/io_suite.ts | 21 +++++++++--------- .../scripts/tests/nothread_quicksuite.ts | 1 - configuration/scripts/tests/nothread_suite.ts | 12 +++++----- configuration/scripts/tests/quick_suite.ts | 4 ++-- configuration/scripts/tests/reprosum_suite.ts | 8 +++---- configuration/scripts/tests/travis_suite.ts | 4 ++-- 25 files changed, 84 insertions(+), 152 deletions(-) mode change 100755 => 100644 configuration/scripts/options/set_env.box2001 mode change 100755 => 100644 configuration/scripts/options/set_nml.box2001 mode change 100755 => 100644 configuration/scripts/options/set_nml.gbox80 create mode 100644 configuration/scripts/options/set_nml.gx1coreii create mode 100644 configuration/scripts/options/set_nml.gx3ncarbulk delete mode 100755 configuration/scripts/options/set_nml.jra55 delete mode 100755 configuration/scripts/options/set_nml.jra55_2008 delete mode 100755 configuration/scripts/options/set_nml.jra55_gx1 delete mode 100755 configuration/scripts/options/set_nml.jra55_gx1_2008 delete mode 100755 configuration/scripts/options/set_nml.jra55_gx3 delete mode 100755 configuration/scripts/options/set_nml.jra55_gx3_2008 create mode 100644 configuration/scripts/options/set_nml.yi2008 diff --git a/.travis.yml b/.travis.yml index f8f5aeadc..994079e98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,11 @@ install: # Fetch forcing data - "wget https://zenodo.org/record/3728362/files/CICE_data_gx3_forcing_NCAR_bulk-20200320.tar.gz && - tar xvfz CICE_data_gx3_forcing_NCAR_bulk-20200320.tar.gz -C ~" + tar xvfz CICE_data_gx3_forcing_NCAR_bulk-20200320.tar.gz -C ~" + + # Fetch jra55_gx3 forcing data + - "wget https://zenodo.org/record/3728364/files/CICE_data_gx3_forcing_JRA55-20200320.tar.gz && + tar xvfz CICE_data_gx3_forcing_JRA55-20200320.tar.gz -C ~" # Mirror entire data folder #- "lftp ftp://anonymous:travis@travis-ci.org@ftp.cgd.ucar.edu diff --git a/configuration/scripts/options/set_env.box2001 b/configuration/scripts/options/set_env.box2001 old mode 100755 new mode 100644 diff --git a/configuration/scripts/options/set_nml.alt01 b/configuration/scripts/options/set_nml.alt01 index 8b66913c6..ceec17ddf 100644 --- a/configuration/scripts/options/set_nml.alt01 +++ b/configuration/scripts/options/set_nml.alt01 @@ -1,4 +1,5 @@ nilyr = 1 +use_leap_years = .false. ice_ic = 'default' restart = .false. distribution_type = 'roundrobin' diff --git a/configuration/scripts/options/set_nml.box2001 b/configuration/scripts/options/set_nml.box2001 old mode 100755 new mode 100644 diff --git a/configuration/scripts/options/set_nml.gbox80 b/configuration/scripts/options/set_nml.gbox80 old mode 100755 new mode 100644 diff --git a/configuration/scripts/options/set_nml.gx1 b/configuration/scripts/options/set_nml.gx1 index df6e2cd2b..e1d18dc8b 100644 --- a/configuration/scripts/options/set_nml.gx1 +++ b/configuration/scripts/options/set_nml.gx1 @@ -1,5 +1,8 @@ dt = 3600.0 runtype = 'initial' +year_init = 2005 +use_leap_years = .true. +use_restart_time = .false. ice_ic = 'ICE_MACHINE_INPUTDATA/CICE_data/ic/gx1/iced_gx1_v5.nc' grid_format = 'bin' grid_type = 'displaced_pole' @@ -10,11 +13,9 @@ maskhalo_dyn = .true. maskhalo_remap = .true. maskhalo_bound = .true. fyear_init = 2005 -ycycle = 1 -atm_data_format = 'bin' -atm_data_type = 'LYq' -atm_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx1/COREII' -precip_units = 'mm_per_sec' +atm_data_format = 'nc' +atm_data_type = 'JRA55_gx1' +atm_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx1/JRA55' +precip_units = 'mks' ocn_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx1/COREII' bgc_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx1/WOA/MONTHLY' - diff --git a/configuration/scripts/options/set_nml.gx1coreii b/configuration/scripts/options/set_nml.gx1coreii new file mode 100644 index 000000000..44b334194 --- /dev/null +++ b/configuration/scripts/options/set_nml.gx1coreii @@ -0,0 +1,9 @@ +year_init = 1997 +use_leap_years = .false. +use_restart_time = .true. +fyear_init = 2005 +ycycle = 1 +atm_data_format = 'bin' +atm_data_type = 'LYq' +atm_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx1/COREII' +precip_units = 'mm_per_sec' diff --git a/configuration/scripts/options/set_nml.gx3 b/configuration/scripts/options/set_nml.gx3 index 8cdb7e40a..1a2fe62a5 100644 --- a/configuration/scripts/options/set_nml.gx3 +++ b/configuration/scripts/options/set_nml.gx3 @@ -1,15 +1,18 @@ dt = 3600.0 runtype = 'initial' +year_init = 2005 +use_leap_years = .true. +use_restart_time = .false. ice_ic = 'ICE_MACHINE_INPUTDATA/CICE_data/ic/gx3/iced_gx3_v5.nc' grid_format = 'bin' grid_type = 'displaced_pole' grid_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx3/grid_gx3.bin' kmt_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx3/kmt_gx3.bin' bathymetry_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx3/global_gx3.bathy.nc' -fyear_init = 1997 -atm_data_format = 'bin' -atm_data_type = 'ncar' -atm_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx3/NCAR_bulk' +fyear_init = 2005 +atm_data_format = 'nc' +atm_data_type = 'JRA55_gx3' +atm_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx3/JRA55' +precip_units = 'mks' ocn_data_format = 'bin' ocn_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx3/' - diff --git a/configuration/scripts/options/set_nml.gx3ncarbulk b/configuration/scripts/options/set_nml.gx3ncarbulk new file mode 100644 index 000000000..fbe0f7ae7 --- /dev/null +++ b/configuration/scripts/options/set_nml.gx3ncarbulk @@ -0,0 +1,9 @@ +year_init = 1997 +use_leap_years = .false. +use_restart_time = .true. +fyear_init = 1997 +atm_data_format = 'bin' +atm_data_type = 'ncar' +atm_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx3/NCAR_bulk' +precip_units = 'mm_per_month' + diff --git a/configuration/scripts/options/set_nml.jra55 b/configuration/scripts/options/set_nml.jra55 deleted file mode 100755 index b35e99a6d..000000000 --- a/configuration/scripts/options/set_nml.jra55 +++ /dev/null @@ -1,17 +0,0 @@ -year_init = 2005 -ice_ic = 'ICE_MACHINE_INPUTDATA/CICE_data/ic/gx1/iced_gx1_v5.nc' -grid_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx1/grid_gx1.bin' -kmt_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx1/kmt_gx1.bin' -bathymetry_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx1/global_gx1.bathy.nc' -use_leap_years = .true. -use_restart_time = .false. -maskhalo_dyn = .true. -maskhalo_remap = .true. -maskhalo_bound = .true. -fyear_init = 2005 -atm_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx1/JRA55' -atm_data_format = 'nc' -atm_data_type = 'JRA55_gx1' -precip_units = 'mks' -ocn_data_dir = 'default' -bgc_data_dir = 'default' diff --git a/configuration/scripts/options/set_nml.jra55_2008 b/configuration/scripts/options/set_nml.jra55_2008 deleted file mode 100755 index 042431fc0..000000000 --- a/configuration/scripts/options/set_nml.jra55_2008 +++ /dev/null @@ -1,17 +0,0 @@ -year_init = 2008 -ice_ic = 'ICE_MACHINE_INPUTDATA/CICE_data/ic/gx1/iced_gx1_v5.nc' -grid_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx1/grid_gx1.bin' -kmt_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx1/kmt_gx1.bin' -bathymetry_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx1/global_gx1.bathy.nc' -use_leap_years = .true. -use_restart_time = .false. -maskhalo_dyn = .true. -maskhalo_remap = .true. -maskhalo_bound = .true. -fyear_init = 2008 -atm_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx1/JRA55' -atm_data_format = 'nc' -atm_data_type = 'JRA55' -precip_units = 'mks' -ocn_data_dir = 'default' -bgc_data_dir = 'default' diff --git a/configuration/scripts/options/set_nml.jra55_gx1 b/configuration/scripts/options/set_nml.jra55_gx1 deleted file mode 100755 index b35e99a6d..000000000 --- a/configuration/scripts/options/set_nml.jra55_gx1 +++ /dev/null @@ -1,17 +0,0 @@ -year_init = 2005 -ice_ic = 'ICE_MACHINE_INPUTDATA/CICE_data/ic/gx1/iced_gx1_v5.nc' -grid_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx1/grid_gx1.bin' -kmt_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx1/kmt_gx1.bin' -bathymetry_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx1/global_gx1.bathy.nc' -use_leap_years = .true. -use_restart_time = .false. -maskhalo_dyn = .true. -maskhalo_remap = .true. -maskhalo_bound = .true. -fyear_init = 2005 -atm_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx1/JRA55' -atm_data_format = 'nc' -atm_data_type = 'JRA55_gx1' -precip_units = 'mks' -ocn_data_dir = 'default' -bgc_data_dir = 'default' diff --git a/configuration/scripts/options/set_nml.jra55_gx1_2008 b/configuration/scripts/options/set_nml.jra55_gx1_2008 deleted file mode 100755 index bf92e93d1..000000000 --- a/configuration/scripts/options/set_nml.jra55_gx1_2008 +++ /dev/null @@ -1,17 +0,0 @@ -year_init = 2008 -ice_ic = 'ICE_MACHINE_INPUTDATA/CICE_data/ic/gx1/iced_gx1_v5.nc' -grid_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx1/grid_gx1.bin' -kmt_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx1/kmt_gx1.bin' -bathymetry_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx1/global_gx1.bathy.nc' -use_leap_years = .true. -use_restart_time = .false. -maskhalo_dyn = .true. -maskhalo_remap = .true. -maskhalo_bound = .true. -fyear_init = 2008 -atm_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx1/JRA55' -atm_data_format = 'nc' -atm_data_type = 'JRA55_gx1' -precip_units = 'mks' -ocn_data_dir = 'default' -bgc_data_dir = 'default' diff --git a/configuration/scripts/options/set_nml.jra55_gx3 b/configuration/scripts/options/set_nml.jra55_gx3 deleted file mode 100755 index c2d1eefdc..000000000 --- a/configuration/scripts/options/set_nml.jra55_gx3 +++ /dev/null @@ -1,17 +0,0 @@ -year_init = 2005 -ice_ic = 'ICE_MACHINE_INPUTDATA/CICE_data/ic/gx3/iced_gx3_v5.nc' -grid_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx3/grid_gx3.bin' -kmt_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx3/kmt_gx3.bin' -bathymetry_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx3/global_gx3.bathy.nc' -use_leap_years = .true. -use_restart_time = .false. -maskhalo_dyn = .true. -maskhalo_remap = .true. -maskhalo_bound = .true. -fyear_init = 2005 -atm_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx3/JRA55' -atm_data_format = 'nc' -atm_data_type = 'JRA55_gx3' -precip_units = 'mks' -ocn_data_dir = 'default' -bgc_data_dir = 'default' diff --git a/configuration/scripts/options/set_nml.jra55_gx3_2008 b/configuration/scripts/options/set_nml.jra55_gx3_2008 deleted file mode 100755 index 89c7dc55d..000000000 --- a/configuration/scripts/options/set_nml.jra55_gx3_2008 +++ /dev/null @@ -1,17 +0,0 @@ -year_init = 2008 -ice_ic = 'ICE_MACHINE_INPUTDATA/CICE_data/ic/gx3/iced_gx3_v5.nc' -grid_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx3/grid_gx3.bin' -kmt_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx3/kmt_gx3.bin' -bathymetry_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx3/global_gx3.bathy.nc' -use_leap_years = .true. -use_restart_time = .false. -maskhalo_dyn = .true. -maskhalo_remap = .true. -maskhalo_bound = .true. -fyear_init = 2008 -atm_data_dir = 'ICE_MACHINE_INPUTDATA/CICE_data/forcing/gx3/JRA55' -atm_data_format = 'nc' -atm_data_type = 'JRA55_gx3' -precip_units = 'mks' -ocn_data_dir = 'default' -bgc_data_dir = 'default' diff --git a/configuration/scripts/options/set_nml.yi2008 b/configuration/scripts/options/set_nml.yi2008 new file mode 100644 index 000000000..ab7a0ecee --- /dev/null +++ b/configuration/scripts/options/set_nml.yi2008 @@ -0,0 +1,3 @@ +year_init = 2008 +fyear_init = 2008 + diff --git a/configuration/scripts/tests/base_suite.ts b/configuration/scripts/tests/base_suite.ts index 386c29e41..818a6abdb 100755 --- a/configuration/scripts/tests/base_suite.ts +++ b/configuration/scripts/tests/base_suite.ts @@ -5,9 +5,9 @@ smoke gx3 1x4 debug,diag1,run2day smoke gx3 4x1 debug,diag1,run5day restart gx3 8x2 debug smoke gx3 8x2 diag24,run1year,medium -decomp gx3 4x2x25x29x5 -smoke gx3 4x2 diag1,run5day smoke_gx3_8x2_diag1_run5day -smoke gx3 4x1 diag1,run5day,thread smoke_gx3_8x2_diag1_run5day +decomp gx3 4x2x25x29x5 none +smoke gx3 4x2 diag1,run5day smoke_gx3_8x2_diag1_run5day +smoke gx3 4x1 diag1,run5day,thread smoke_gx3_8x2_diag1_run5day restart gx1 40x4 droundrobin,medium restart tx1 40x4 dsectrobin,medium restart gx3 4x4 none @@ -33,21 +33,25 @@ smoke gbox80 1x1 boxslotcyl smoke gx3 8x2 bgcz smoke gx3 8x2 bgcz,debug smoke gx3 8x1 bgcskl,debug -#smoke gx3 4x1 bgcz,thread smoke_gx3_8x2_bgcz +#smoke gx3 4x1 bgcz,thread smoke_gx3_8x2_bgcz restart gx1 4x2 bgcsklclim,medium restart gx1 8x1 bgczclim,medium -smoke gx1 24x1 jra55_gx1_2008,medium,run90day -smoke gx3 8x1 jra55_gx3_2008,medium,run90day -restart gx1 24x1 jra55_gx1,short -restart gx3 8x1 jra55_gx3,short +smoke gx1 24x1 medium,run90day,yi2008 +smoke gx3 8x1 medium,run90day,yi2008 +restart gx1 24x1 short +restart gx3 8x1 short smoke gx3 4x2 fsd1,diag24,run5day,debug smoke gx3 8x2 fsd12,diag24,run5day,short restart gx3 4x2 fsd12,debug,short smoke gx3 8x2 fsd12ww3,diag24,run1day,medium smoke gx3 4x1 isotope,debug restart gx3 8x2 isotope -restart gx3 4x4 iobinary +restart gx3 4x4 gx3ncarbulk,iobinary restart gx3 4x4 histall,precision8,cdf64 smoke gx3 30x1 bgcz,histall smoke gx3 14x2 fsd12,histall smoke gx3 4x1 dynpicard,medium + +restart gx3 8x2 gx3ncarbulk,debug +restart gx3 4x4 gx3ncarbulk,diag1 +restart gx1 24x1 gx1coreii,short diff --git a/configuration/scripts/tests/decomp_suite.ts b/configuration/scripts/tests/decomp_suite.ts index 1e1ae3112..4eb5394d9 100644 --- a/configuration/scripts/tests/decomp_suite.ts +++ b/configuration/scripts/tests/decomp_suite.ts @@ -1,6 +1,6 @@ # Test Grid PEs Sets BFB-compare restart gx3 4x2x25x29x4 dslenderX2 -decomp gx3 4x2x25x29x5 +decomp gx3 4x2x25x29x5 none sleep 30 restart gx3 1x1x50x58x4 droundrobin,thread restart_gx3_4x2x25x29x4_dslenderX2 restart gx3 4x1x25x116x1 dslenderX1,thread restart_gx3_4x2x25x29x4_dslenderX2 diff --git a/configuration/scripts/tests/first_suite.ts b/configuration/scripts/tests/first_suite.ts index b06ee7e0b..bf6c813f6 100644 --- a/configuration/scripts/tests/first_suite.ts +++ b/configuration/scripts/tests/first_suite.ts @@ -1,5 +1,5 @@ -# Test Grid PEs Sets BFB-compare -smoke gx3 8x2 diag1,run5day +# Test Grid PEs Sets BFB-compare +smoke gx3 8x2 diag1,run5day restart gx3 4x2x25x29x4 dslenderX2 logbfb gx3 4x2x25x29x4 dslenderX2,diag1,reprosum -smoke gx3 1x2 run2day +smoke gx3 1x2 run2day diff --git a/configuration/scripts/tests/io_suite.ts b/configuration/scripts/tests/io_suite.ts index 3e98642e9..a17e3f625 100755 --- a/configuration/scripts/tests/io_suite.ts +++ b/configuration/scripts/tests/io_suite.ts @@ -1,15 +1,16 @@ # Test Grid PEs Sets BFB-compare # some iobinary configurations fail due to bathymetry netcdf file requirement, remove them -restart gx3 8x4 debug,histall,iobinary,precision8 -#restart gx3 12x2 alt01,histall,iobinary -restart gx3 16x2 alt02,histall,iobinary,precision8 -#restart gx3 4x2 alt03,histall,iobinary -restart gx3 8x4 alt04,histall,iobinary,precision8 -restart gx3 4x4 alt05,histall,iobinary -restart gx3 32x1 bgcz,histall,iobinary,precision8 -restart gx3 16x2 bgcskl,histall,iobinary -restart gx3 14x2 isotope,histall,iobinary,precision8 -restart gx3 16x2 fsd12,histall,iobinary +# iobinary cannot work with JRA55 because netcdf is turned off +restart gx3 8x4 gx3ncarbulk,debug,histall,iobinary,precision8 +#restart gx3 12x2 gx3ncarbulk,alt01,histall,iobinary +restart gx3 16x2 gx3ncarbulk,alt02,histall,iobinary,precision8 +#restart gx3 4x2 gx3ncarbulk,alt03,histall,iobinary +restart gx3 8x4 gx3ncarbulk,alt04,histall,iobinary,precision8 +restart gx3 4x4 gx3ncarbulk,alt05,histall,iobinary +restart gx3 32x1 gx3ncarbulk,bgcz,histall,iobinary,precision8 +restart gx3 16x2 gx3ncarbulk,bgcskl,histall,iobinary +restart gx3 14x2 gx3ncarbulk,isotope,histall,iobinary,precision8 +restart gx3 16x2 gx3ncarbulk,fsd12,histall,iobinary restart gx3 32x1 debug,histall,ionetcdf restart gx3 15x2 alt01,histall,ionetcdf,precision8,cdf64 diff --git a/configuration/scripts/tests/nothread_quicksuite.ts b/configuration/scripts/tests/nothread_quicksuite.ts index 535347438..997b59b28 100644 --- a/configuration/scripts/tests/nothread_quicksuite.ts +++ b/configuration/scripts/tests/nothread_quicksuite.ts @@ -1,5 +1,4 @@ # Test Grid PEs Sets BFB-compare - restart gx3 16x1 diag1 smoke gx3 1x1 debug,diag1,run2day smoke gx3 4x1 debug,diag1,run2day,thread diff --git a/configuration/scripts/tests/nothread_suite.ts b/configuration/scripts/tests/nothread_suite.ts index 49f834a98..afe1963b3 100644 --- a/configuration/scripts/tests/nothread_suite.ts +++ b/configuration/scripts/tests/nothread_suite.ts @@ -14,7 +14,7 @@ smoke gx3 16x1 diag24,run1year,medium #restart tx1 160x1 dsectrobin,medium restart gx3 16x1 none -restart gx3 16x1 iobinary +restart gx3 16x1 gx3ncarbulk,iobinary restart gx3 12x1 alt01 restart gx3 16x1 alt02 @@ -43,11 +43,11 @@ smoke gbox128 24x1 boxrestore,short,debug restart gbox80 1x1 box2001 smoke gbox80 1x1 boxslotcyl -smoke gx3 16x1 jra55_gx3_2008,medium,run90day -restart gx3 12x1 jra55_gx3,short +smoke gx3 16x1 medium,run90day,yi2008 +restart gx3 12x1 short #tcraig, hangs nodes intermittently on izumi -#smoke gx1 24x1 jra55_gx1_2008,medium,run90day -#restart gx1 24x1 jra55_gx1,short +#smoke gx1 24x1 medium,run90day,yi2008 +#restart gx1 24x1 short smoke gx3 16x1 bgcz smoke gx3 16x1 bgcz,debug @@ -56,7 +56,7 @@ smoke gx3 24x1 bgcskl,debug #restart gx1 128x1 bgcsklclim,medium #restart gx1 256x1 bgczclim,medium -decomp gx3 8x1x5x29x20 +decomp gx3 8x1x5x29x20 none restart gx3 1x1x50x58x4 droundrobin restart_gx3_8x1x25x29x2_dslenderX2 restart gx3 4x1x25x116x1 dslenderX1 restart_gx3_8x1x25x29x2_dslenderX2 restart gx3 12x1x4x29x9 dspacecurve restart_gx3_8x1x25x29x2_dslenderX2 diff --git a/configuration/scripts/tests/quick_suite.ts b/configuration/scripts/tests/quick_suite.ts index 10595e9ad..9384f0333 100644 --- a/configuration/scripts/tests/quick_suite.ts +++ b/configuration/scripts/tests/quick_suite.ts @@ -1,6 +1,6 @@ # Test Grid PEs Sets BFB-compare -smoke gx3 8x2 diag1,run5day -smoke gx3 1x1 diag1,run1day +smoke gx3 8x2 diag1,run5day +smoke gx3 1x1 diag1,run1day restart gbox128 8x1 diag1 restart gx3 4x2 debug,diag1,run5day smoke gx3 4x1 diag1,run5day,thread smoke_gx3_8x2_diag1_run5day diff --git a/configuration/scripts/tests/reprosum_suite.ts b/configuration/scripts/tests/reprosum_suite.ts index 34cf51a80..d65370e0a 100644 --- a/configuration/scripts/tests/reprosum_suite.ts +++ b/configuration/scripts/tests/reprosum_suite.ts @@ -4,8 +4,8 @@ logbfb gx3 4x2x25x29x4 dslenderX2,diag1,reprosum sleep 60 logbfb gx3 1x1x50x58x4 droundrobin,diag1,thread,maskhalo,reprosum logbfb_gx3_4x2x25x29x4_diag1_dslenderX2_reprosum logbfb gx3 4x1x25x116x1 dslenderX1,diag1,thread,maskhalo,reprosum logbfb_gx3_4x2x25x29x4_diag1_dslenderX2_reprosum -logbfb gx3 1x20x5x29x80 dsectrobin,diag1,short,reprosum logbfb_gx3_4x2x25x29x4_diag1_dslenderX2_reprosum -logbfb gx3 8x2x8x10x20 droundrobin,diag1,reprosum logbfb_gx3_4x2x25x29x4_diag1_dslenderX2_reprosum -logbfb gx3 6x2x50x58x1 droundrobin,diag1,reprosum logbfb_gx3_4x2x25x29x4_diag1_dslenderX2_reprosum +logbfb gx3 1x20x5x29x80 dsectrobin,diag1,short,reprosum logbfb_gx3_4x2x25x29x4_diag1_dslenderX2_reprosum +logbfb gx3 8x2x8x10x20 droundrobin,diag1,reprosum logbfb_gx3_4x2x25x29x4_diag1_dslenderX2_reprosum +logbfb gx3 6x2x50x58x1 droundrobin,diag1,reprosum logbfb_gx3_4x2x25x29x4_diag1_dslenderX2_reprosum logbfb gx3 6x2x4x29x18 dspacecurve,diag1,maskhalo,reprosum logbfb_gx3_4x2x25x29x4_diag1_dslenderX2_reprosum -#logbfb gx3 8x2x8x10x20 droundrobin,diag1 logbfb_gx3_4x2x25x29x4_diag1_dslenderX2 +#logbfb gx3 8x2x8x10x20 droundrobin,diag1 logbfb_gx3_4x2x25x29x4_diag1_dslenderX2 diff --git a/configuration/scripts/tests/travis_suite.ts b/configuration/scripts/tests/travis_suite.ts index 6f475f4c5..b452bae0f 100644 --- a/configuration/scripts/tests/travis_suite.ts +++ b/configuration/scripts/tests/travis_suite.ts @@ -3,5 +3,5 @@ smoke gx3 1x2 run2day smoke gx3 1x1 debug,run1day smoke gx3 2x2 debug,run1day smoke gx3 2x1 run2day,thread smoke_gx3_1x2_run2day -restart gx3 2x1 -restart gx3 1x2 +restart gx3 2x1 +restart gx3 1x2 From f5f487f973309ec1cd162afad9b073728e469d89 Mon Sep 17 00:00:00 2001 From: Elizabeth Hunke Date: Wed, 23 Dec 2020 16:49:48 -0700 Subject: [PATCH 09/18] zsal option for testing zsalinity code (#548) * zsal option for testing zsalinity code * add zsal tests to base_suite * fix history conditionals for fields outside main namelist; adjust zsal tests in base_suite --- .../cicedynB/analysis/ice_history_bgc.F90 | 46 ++++++++++++------- .../cicedynB/analysis/ice_history_mechred.F90 | 13 +++++- .../cicedynB/analysis/ice_history_pond.F90 | 13 +++++- configuration/scripts/options/set_nml.zsal | 9 ++++ configuration/scripts/tests/base_suite.ts | 3 +- 5 files changed, 63 insertions(+), 21 deletions(-) create mode 100644 configuration/scripts/options/set_nml.zsal diff --git a/cicecore/cicedynB/analysis/ice_history_bgc.F90 b/cicecore/cicedynB/analysis/ice_history_bgc.F90 index 1ae572b30..67b23904e 100644 --- a/cicecore/cicedynB/analysis/ice_history_bgc.F90 +++ b/cicecore/cicedynB/analysis/ice_history_bgc.F90 @@ -267,7 +267,7 @@ module ice_history_bgc subroutine init_hist_bgc_2D use ice_broadcast, only: broadcast_scalar - use ice_calendar, only: nstreams + use ice_calendar, only: nstreams, histfreq use ice_communicate, only: my_task, master_task use ice_history_shared, only: tstr2D, tcstr, define_hist_field, & f_fsalt, f_fsalt_ai, f_sice @@ -781,6 +781,7 @@ subroutine init_hist_bgc_2D if (tr_iso .or. tr_aero .or. tr_brine .or. solve_zsal .or. skl_bgc) then do ns = 1, nstreams + if (histfreq(ns) /= 'x') then if (f_iso(1:1) /= 'x') then do n=1,n_iso @@ -1780,6 +1781,7 @@ subroutine init_hist_bgc_2D "distance from ice bottom to brine surface", c1, c0, & ns, f_hbri) + endif ! histfreq(ns) /= 'x' enddo ! nstreams endif ! tr_aero, etc @@ -1790,7 +1792,7 @@ end subroutine init_hist_bgc_2D subroutine init_hist_bgc_3Dc - use ice_calendar, only: nstreams + use ice_calendar, only: nstreams, histfreq use ice_history_shared, only: tstr3Dc, tcstr, define_hist_field integer (kind=int_kind) :: ns @@ -1802,18 +1804,19 @@ subroutine init_hist_bgc_3Dc if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) - if (tr_brine) then + if (tr_brine) then ! 3D (category) variables must be looped separately do ns = 1, nstreams - if (f_fbri(1:1) /= 'x') & - call define_hist_field(n_fbri,"fbrine","1",tstr3Dc, tcstr, & + if (histfreq(ns) /= 'x') then + if (f_fbri(1:1) /= 'x') & + call define_hist_field(n_fbri,"fbrine","1",tstr3Dc, tcstr, & "brine tracer fraction of ice volume, cat", & - "none", c1, c0, & - ns, f_fbri) + "none", c1, c0, ns, f_fbri) + endif ! histfreq /= 'x' enddo ! ns - endif + endif ! tr_brine end subroutine init_hist_bgc_3Dc @@ -1821,7 +1824,7 @@ end subroutine init_hist_bgc_3Dc subroutine init_hist_bgc_3Db - use ice_calendar, only: nstreams + use ice_calendar, only: nstreams,histfreq use ice_history_shared, only: tstr3Db, tcstr, define_hist_field integer (kind=int_kind) :: ns @@ -1841,6 +1844,7 @@ subroutine init_hist_bgc_3Db if (z_tracers .or. solve_zsal) then do ns = 1, nstreams + if (histfreq(ns) /= 'x') then if (f_bTin(1:1) /= 'x') & call define_hist_field(n_bTin,"bTizn","C",tstr3Db, tcstr, & @@ -1873,6 +1877,7 @@ subroutine init_hist_bgc_3Db "internal ice PAR", "on bio interface grid", c1, c0, & ns, f_zfswin) + endif ! histfreq(ns) /= 'x' enddo ! ns endif ! z_tracers or solve_zsal @@ -2012,9 +2017,10 @@ subroutine accum_hist_bgc (iblk) ! increment field !--------------------------------------------------------------- - if (tr_iso .or. tr_aero .or. tr_brine .or. solve_zsal .or. skl_bgc) then - ! 2d bgc fields + ! 2d bgc fields + if (allocated(a2D)) then + if (tr_iso .or. tr_aero .or. tr_brine .or. solve_zsal .or. skl_bgc) then ! zsalinity if (f_fzsal (1:1) /= 'x') & @@ -2635,11 +2641,12 @@ subroutine accum_hist_bgc (iblk) call accum_hist_field(n_hbri, iblk, & hbri(:,:,iblk), a2D) - endif ! 2d bgc tracers, tr_aero, tr_brine, solve_zsal, skl_bgc - + endif ! 2d bgc tracers, tr_aero, tr_brine, solve_zsal, skl_bgc + endif ! allocated(a2D) ! 3D category fields + if (allocated(a3Dc)) then if (tr_brine) then ! 3Dc bgc category fields @@ -2647,7 +2654,9 @@ subroutine accum_hist_bgc (iblk) call accum_hist_field(n_fbri-n2D, iblk, ncat_hist, & trcrn(:,:,nt_fbri,1:ncat_hist,iblk), a3Dc) endif + endif ! allocated(a3Dc) + if (allocated(a3Db)) then if (z_tracers .or. solve_zsal) then ! 3Db category fields @@ -2754,8 +2763,10 @@ subroutine accum_hist_bgc (iblk) workz(:,:,1:nzblyr), a3Db) endif - endif ! 3Db fields + endif ! 3Db fields + endif ! allocated(a3Db) + if (allocated(a3Da)) then if (z_tracers) then ! 3Da category fields @@ -3189,7 +3200,8 @@ subroutine accum_hist_bgc (iblk) workz2(:,:,1:nzalyr), a3Da) endif - endif ! z_tracers, 3Da tracers + endif ! z_tracers, 3Da tracers + endif ! allocated(a3Da) end subroutine accum_hist_bgc @@ -3197,7 +3209,7 @@ end subroutine accum_hist_bgc subroutine init_hist_bgc_3Da - use ice_calendar, only: nstreams + use ice_calendar, only: nstreams, histfreq use ice_history_shared, only: tstr3Da, tcstr, define_hist_field integer (kind=int_kind) :: ns, n @@ -3216,6 +3228,7 @@ subroutine init_hist_bgc_3Da if (z_tracers) then do ns = 1, nstreams + if (histfreq(ns) /= 'x') then !---------------------------------------------------------------------------- ! snow+bio grid ==> @@ -3439,6 +3452,7 @@ subroutine init_hist_bgc_3Da "other bulk nitrogen pool in cat 1", "snow+bio grid", c1, c0, & ns, f_bgc_PON_cat1) + endif ! histfreq(ns) /= 'x' enddo !ns endif ! z_tracers diff --git a/cicecore/cicedynB/analysis/ice_history_mechred.F90 b/cicecore/cicedynB/analysis/ice_history_mechred.F90 index 78edd7a31..a20df5fb0 100644 --- a/cicecore/cicedynB/analysis/ice_history_mechred.F90 +++ b/cicecore/cicedynB/analysis/ice_history_mechred.F90 @@ -81,7 +81,7 @@ module ice_history_mechred subroutine init_hist_mechred_2D use ice_broadcast, only: broadcast_scalar - use ice_calendar, only: nstreams + use ice_calendar, only: nstreams, histfreq use ice_communicate, only: my_task, master_task use ice_history_shared, only: tstr2D, tcstr, define_hist_field @@ -157,6 +157,7 @@ subroutine init_hist_mechred_2D ! 2D variables do ns = 1, nstreams + if (histfreq(ns) /= 'x') then if (f_alvl(1:1) /= 'x') & call define_hist_field(n_alvl,"alvl","1",tstr2D, tcstr, & @@ -203,6 +204,7 @@ subroutine init_hist_mechred_2D "none", secday*c100, c0, & ns, f_opening) + endif ! histfreq(ns) /= 'x' enddo ! nstreams end subroutine init_hist_mechred_2D @@ -211,7 +213,7 @@ end subroutine init_hist_mechred_2D subroutine init_hist_mechred_3Dc - use ice_calendar, only: nstreams + use ice_calendar, only: nstreams, histfreq use ice_history_shared, only: tstr3Dc, tcstr, define_hist_field integer (kind=int_kind) :: ns @@ -228,6 +230,7 @@ subroutine init_hist_mechred_3Dc file=__FILE__, line=__LINE__) do ns = 1, nstreams + if (histfreq(ns) /= 'x') then if (f_ardgn(1:1) /= 'x') & call define_hist_field(n_ardgn,"ardgn","1",tstr3Dc, tcstr, & @@ -295,6 +298,7 @@ subroutine init_hist_mechred_3Dc "none", c1, c0, & ns, f_vraftn) + endif ! histfreq(ns) /= 'x' enddo ! ns end subroutine init_hist_mechred_3Dc @@ -332,6 +336,7 @@ subroutine accum_hist_mechred (iblk) !--------------------------------------------------------------- ! 2D fields + if (allocated(a2D)) then if (f_alvl(1:1)/= 'x') & call accum_hist_field(n_alvl, iblk, & @@ -354,7 +359,10 @@ subroutine accum_hist_mechred (iblk) if (f_opening(1:1) /= 'x') & call accum_hist_field(n_opening, iblk, opening(:,:,iblk), a2D) + endif ! allocated(a2D) + ! 3D category fields + if (allocated(a3Dc)) then if (f_ardgn(1:1)/= 'x') & call accum_hist_field(n_ardgn-n2D, iblk, ncat_hist, & @@ -391,6 +399,7 @@ subroutine accum_hist_mechred (iblk) if (f_vraftn(1:1)/= 'x') & call accum_hist_field(n_vraftn-n2D, iblk, ncat_hist, & vraftn(:,:,1:ncat_hist,iblk), a3Dc) + endif ! allocated(a3Dc) end subroutine accum_hist_mechred diff --git a/cicecore/cicedynB/analysis/ice_history_pond.F90 b/cicecore/cicedynB/analysis/ice_history_pond.F90 index ebef84483..de10eb9fb 100644 --- a/cicecore/cicedynB/analysis/ice_history_pond.F90 +++ b/cicecore/cicedynB/analysis/ice_history_pond.F90 @@ -66,7 +66,7 @@ module ice_history_pond subroutine init_hist_pond_2D use ice_broadcast, only: broadcast_scalar - use ice_calendar, only: nstreams + use ice_calendar, only: nstreams, histfreq use ice_communicate, only: my_task, master_task use ice_history_shared, only: tstr2D, tcstr, define_hist_field @@ -135,6 +135,7 @@ subroutine init_hist_pond_2D ! 2D variables do ns = 1, nstreams + if (histfreq(ns) /= 'x') then if (f_apond(1:1) /= 'x') & call define_hist_field(n_apond,"apond","1",tstr2D, tcstr, & @@ -184,6 +185,7 @@ subroutine init_hist_pond_2D "weighted by ice area", c1, c0, & ns, f_apeff_ai) + endif ! histfreq(ns) /= 'x' enddo ! nstreams endif ! tr_pond @@ -194,7 +196,7 @@ end subroutine init_hist_pond_2D subroutine init_hist_pond_3Dc - use ice_calendar, only: nstreams + use ice_calendar, only: nstreams, histfreq use ice_history_shared, only: tstr3Dc, tcstr, define_hist_field integer (kind=int_kind) :: ns @@ -210,6 +212,7 @@ subroutine init_hist_pond_3Dc ! 3D (category) variables must be looped separately do ns = 1, nstreams + if (histfreq(ns) /= 'x') then if (f_apondn(1:1) /= 'x') & call define_hist_field(n_apondn,"apondn","1",tstr3Dc, tcstr, & @@ -227,6 +230,7 @@ subroutine init_hist_pond_3Dc "none", c1, c0, & ns, f_apeffn) + endif ! histfreq(ns) /= 'x' enddo ! ns endif ! tr_pond @@ -286,6 +290,7 @@ subroutine accum_hist_pond (iblk) if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) + if (allocated(a2D)) then if (tr_pond_cesm) then if (f_apond(1:1)/= 'x') & call accum_hist_field(n_apond, iblk, & @@ -374,7 +379,10 @@ subroutine accum_hist_pond (iblk) if (f_apeff_ai(1:1) /= 'x') & call accum_hist_field(n_apeff_ai, iblk, apeff_ai(:,:,iblk), a2D) + endif ! allocated(a2D) + ! 3D category fields + if (allocated(a3Dc)) then if (f_apondn (1:1) /= 'x') & call accum_hist_field(n_apondn-n2D, iblk, ncat_hist, & trcrn(:,:,nt_apnd,1:ncat_hist,iblk), a3Dc) @@ -385,6 +393,7 @@ subroutine accum_hist_pond (iblk) call accum_hist_field(n_hpondn-n2D, iblk, ncat_hist, & trcrn(:,:,nt_apnd,1:ncat_hist,iblk) & * trcrn(:,:,nt_hpnd,1:ncat_hist,iblk), a3Dc) + endif ! allocated(a3Dc) end subroutine accum_hist_pond diff --git a/configuration/scripts/options/set_nml.zsal b/configuration/scripts/options/set_nml.zsal new file mode 100644 index 000000000..782a31ddc --- /dev/null +++ b/configuration/scripts/options/set_nml.zsal @@ -0,0 +1,9 @@ +ktherm = 1 +sw_redist = .true. +tfrz_option = 'linear_salt' +tr_brine = .true. +solve_zsal = .true. +z_tracers = .true. +ice_ic = 'default' +restart = .false. + diff --git a/configuration/scripts/tests/base_suite.ts b/configuration/scripts/tests/base_suite.ts index 818a6abdb..1ed489730 100755 --- a/configuration/scripts/tests/base_suite.ts +++ b/configuration/scripts/tests/base_suite.ts @@ -51,7 +51,8 @@ restart gx3 4x4 histall,precision8,cdf64 smoke gx3 30x1 bgcz,histall smoke gx3 14x2 fsd12,histall smoke gx3 4x1 dynpicard,medium - +smoke gx3 8x2 diag24,run5day,zsal,debug +restart gx3 8x2 zsal restart gx3 8x2 gx3ncarbulk,debug restart gx3 4x4 gx3ncarbulk,diag1 restart gx1 24x1 gx1coreii,short From d0084ddf5697fdae6e22bb798c7ece19088dd72d Mon Sep 17 00:00:00 2001 From: Elizabeth Hunke Date: Mon, 18 Jan 2021 16:51:19 -0700 Subject: [PATCH 10/18] solve_zsal bug fix and update zsal test option (#549) * solve_zsal bug fix and update to zsal test option * update icepack include zsal changes (not required) Co-authored-by: apcraig --- cicecore/cicedynB/analysis/ice_diagnostics.F90 | 15 +++++++++++---- cicecore/cicedynB/general/ice_step_mod.F90 | 9 +++++---- .../drivers/standalone/cice/CICE_RunMod.F90 | 2 +- .../standalone/cice/CICE_RunMod.F90_debug | 17 +++++++++-------- configuration/scripts/options/set_nml.zsal | 1 - icepack | 2 +- 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/cicecore/cicedynB/analysis/ice_diagnostics.F90 b/cicecore/cicedynB/analysis/ice_diagnostics.F90 index 40da6cb64..cff544cd4 100644 --- a/cicecore/cicedynB/analysis/ice_diagnostics.F90 +++ b/cicecore/cicedynB/analysis/ice_diagnostics.F90 @@ -1561,11 +1561,11 @@ subroutine print_state(plabel,i,j,iblk) real (kind=dbl_kind) :: & eidebug, esdebug, & - qi, qs, Tsnow, & + qi, qs, Tsnow, si, & rad_to_deg, puny, rhoi, lfresh, rhos, cp_ice integer (kind=int_kind) :: n, k, nt_Tsfc, nt_qice, nt_qsno, nt_fsd, & - nt_isosno, nt_isoice + nt_isosno, nt_isoice, nt_sice logical (kind=log_kind) :: tr_fsd, tr_iso @@ -1576,7 +1576,7 @@ subroutine print_state(plabel,i,j,iblk) call icepack_query_tracer_flags(tr_fsd_out=tr_fsd, tr_iso_out=tr_iso) call icepack_query_tracer_indices(nt_Tsfc_out=nt_Tsfc, nt_qice_out=nt_qice, & - nt_qsno_out=nt_qsno, nt_fsd_out=nt_fsd, & + nt_qsno_out=nt_qsno, nt_sice_out=nt_sice, nt_fsd_out=nt_fsd, & nt_isosno_out=nt_isosno, nt_isoice_out=nt_isoice) call icepack_query_parameters( & rad_to_deg_out=rad_to_deg, puny_out=puny, rhoi_out=rhoi, lfresh_out=lfresh, & @@ -1621,7 +1621,6 @@ subroutine print_state(plabel,i,j,iblk) enddo ! n - eidebug = c0 do n = 1,ncat do k = 1,nilyr @@ -1654,6 +1653,14 @@ subroutine print_state(plabel,i,j,iblk) write(nu_diag,*) 'qsnow(i,j)',esdebug write(nu_diag,*) ' ' + do n = 1,ncat + do k = 1,nilyr + si = trcrn(i,j,nt_sice+k-1,n,iblk) + write(nu_diag,*) 'sice, cat ',n,' layer ',k, si + enddo + enddo + write(nu_diag,*) ' ' + write(nu_diag,*) 'uvel(i,j)',uvel(i,j,iblk) write(nu_diag,*) 'vvel(i,j)',vvel(i,j,iblk) diff --git a/cicecore/cicedynB/general/ice_step_mod.F90 b/cicecore/cicedynB/general/ice_step_mod.F90 index b31582fe8..b21908e77 100644 --- a/cicecore/cicedynB/general/ice_step_mod.F90 +++ b/cicecore/cicedynB/general/ice_step_mod.F90 @@ -550,22 +550,23 @@ subroutine step_therm2 (dt, iblk) logical (kind=log_kind) :: & tr_fsd, & ! floe size distribution tracers - z_tracers + z_tracers, & ! vertical biogeochemistry + solve_zsal ! zsalinity type (block) :: & this_block ! block information for current block character(len=*), parameter :: subname = '(step_therm2)' - call icepack_query_parameters(z_tracers_out=z_tracers) + call icepack_query_parameters(z_tracers_out=z_tracers,solve_zsal_out=solve_zsal) call icepack_query_tracer_sizes(ntrcr_out=ntrcr, nbtrcr_out=nbtrcr) call icepack_query_tracer_flags(tr_fsd_out=tr_fsd) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) - ! tcraig, nltrcr used to be the number of zbgc tracers, but it's used as a zbgc flag in icepack - if (z_tracers) then + ! nltrcr is only used as a zbgc flag in icepack (number of zbgc tracers > 0) + if (z_tracers .or. solve_zsal) then nltrcr = 1 else nltrcr = 0 diff --git a/cicecore/drivers/standalone/cice/CICE_RunMod.F90 b/cicecore/drivers/standalone/cice/CICE_RunMod.F90 index bd818211e..9f6f42f28 100644 --- a/cicecore/drivers/standalone/cice/CICE_RunMod.F90 +++ b/cicecore/drivers/standalone/cice/CICE_RunMod.F90 @@ -548,7 +548,7 @@ subroutine coupling_prep (iblk) Tref (:,:,iblk), Qref (:,:,iblk), & fresh (:,:,iblk), fsalt (:,:,iblk), & fhocn (:,:,iblk), & - fswthru (:,:,iblk), & + fswthru (:,:,iblk), & fswthru_vdr (:,:,iblk), & fswthru_vdf (:,:,iblk), & fswthru_idr (:,:,iblk), & diff --git a/cicecore/drivers/standalone/cice/CICE_RunMod.F90_debug b/cicecore/drivers/standalone/cice/CICE_RunMod.F90_debug index 8f5de17ea..5f7eebe31 100644 --- a/cicecore/drivers/standalone/cice/CICE_RunMod.F90_debug +++ b/cicecore/drivers/standalone/cice/CICE_RunMod.F90_debug @@ -247,7 +247,7 @@ plabeld = 'post step_therm2' call debug_ice (iblk, plabeld) - endif + endif ! ktherm > 0 enddo ! iblk !$OMP END PARALLEL DO @@ -394,8 +394,8 @@ albpnd, albcnt, apeff_ai, fpond, fresh, l_mpond_fresh, & alvdf_ai, alidf_ai, alvdr_ai, alidr_ai, fhocn_ai, & fresh_ai, fsalt_ai, fsalt, & - fswthru_ai, fhocn, fswthru, scale_factor, snowfrac, & - fswthru_vdr, fswthru_vdf, fswthru_idr, fswthru_idf, & + fswthru_ai, fhocn, scale_factor, snowfrac, & + fswthru, fswthru_vdr, fswthru_vdf, fswthru_idr, fswthru_idf, & swvdr, swidr, swvdf, swidf, Tf, Tair, Qa, strairxT, strairyT, & fsens, flat, fswabs, flwout, evap, Tref, Qref, & scale_fluxes, frzmlt_init, frzmlt @@ -589,11 +589,12 @@ evap (:,:,iblk), & Tref (:,:,iblk), Qref (:,:,iblk), & fresh (:,:,iblk), fsalt (:,:,iblk), & - fhocn (:,:,iblk), fswthru (:,:,iblk), & - fswthru_vdr(:,:,iblk), & - fswthru_vdf(:,:,iblk), & - fswthru_idr(:,:,iblk), & - fswthru_idf(:,:,iblk), & + fhocn (:,:,iblk), & + fswthru (:,:,iblk), & + fswthru_vdr (:,:,iblk), & + fswthru_vdf (:,:,iblk), & + fswthru_idr (:,:,iblk), & + fswthru_idf (:,:,iblk), & faero_ocn(:,:,:,iblk), & alvdr (:,:,iblk), alidr (:,:,iblk), & alvdf (:,:,iblk), alidf (:,:,iblk), & diff --git a/configuration/scripts/options/set_nml.zsal b/configuration/scripts/options/set_nml.zsal index 782a31ddc..7e8ed47ff 100644 --- a/configuration/scripts/options/set_nml.zsal +++ b/configuration/scripts/options/set_nml.zsal @@ -3,7 +3,6 @@ sw_redist = .true. tfrz_option = 'linear_salt' tr_brine = .true. solve_zsal = .true. -z_tracers = .true. ice_ic = 'default' restart = .false. diff --git a/icepack b/icepack index 3ca0dda63..af7e38f81 160000 --- a/icepack +++ b/icepack @@ -1 +1 @@ -Subproject commit 3ca0dda63ccb60d1d9329fc37173210d03dc19a1 +Subproject commit af7e38f8107b2ec8680cf5a49d7274b43fe34248 From 078c49ab1f46c78dbbcfc50ff9e7f9e1d59e4d29 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Thu, 21 Jan 2021 09:36:40 -0800 Subject: [PATCH 11/18] Add Github Actions test-cice.yml script (#555) * add Github Actions test-cice.yml script * Update README.md Co-authored-by: Philippe Blain --- .github/workflows/test-cice.yml | 135 +++++++++++++++++++++++++++ .github/workflows/write_logfiles.csh | 10 ++ README.md | 3 +- 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/test-cice.yml create mode 100755 .github/workflows/write_logfiles.csh diff --git a/.github/workflows/test-cice.yml b/.github/workflows/test-cice.yml new file mode 100644 index 000000000..1fdd8188d --- /dev/null +++ b/.github/workflows/test-cice.yml @@ -0,0 +1,135 @@ +name: GHActions + +# This workflow is triggered on pushes, pull-requeust, and releases +# ghactions* branch names will trigger this to support development testing +# To Do: get it working with bash and ubuntu + +on: + push: + branches: + - master + - 'CICE*' + - 'ghactions*' + pull_request: + release: + types: + - created + +defaults: + run: + shell: /bin/csh {0} + +jobs: + build: + name: "CICETesting" + runs-on: ${{ matrix.os }} + strategy: + matrix: +# os: [macos-latest, ubuntu-latest] + os: [macos-latest] +# os: [ubuntu-latest] + include: + - os: macos-latest + envdef: macos + minicond: Miniconda3-latest-MacOSX-x86_64.sh +# - os: ubuntu-latest +# envdef: linux +# minicond: Miniconda3-latest-Linux-x86_64.sh + steps: + - name: reset macos toolchain to commandlinetools + shell: /bin/bash {0} + if: contains( matrix.envdef, 'macos') + run: | + sudo xcode-select -r + sudo xcode-select -s /Library/Developer/CommandLineTools + echo "xcrun --show-sdk-path: $(xcrun --show-sdk-path)" + echo "xcode-select -p: $(xcode-select -p)" + - name: system info + shell: /bin/bash {0} + run: | + type wget + type curl + type csh + echo "readlink \$(which csh): $(python -c 'import os, sys; print os.path.realpath(sys.argv[1])' $(which csh))" + echo "csh --version: $(csh --version)" + echo "uname -a: $(uname -a)" + echo "sw_vers: $(sw_vers)" + echo "HOME: $HOME" + echo "GITHUB_WORKSPACE: $GITHUB_WORKSPACE" + echo "OS: ${{ matrix.os }}" + echo "ENVDEF: ${{ matrix.envdef }}" + echo "MINICOND: ${{ matrix.minicond }}" + - name : install miniconda + shell: /bin/bash {0} + run: | + wget https://repo.anaconda.com/miniconda/${{ matrix.minicond }} -O ~/miniconda.sh + bash ~/miniconda.sh -b -p $HOME/miniconda + - name: clone + uses: actions/checkout@v2 + with: + submodules: 'recursive' + - name: link + run: | + ln -s ${GITHUB_WORKSPACE}/../CICE ${HOME}/cice +# ls -al ${HOME}/ +# ls -al ${GITHUB_WORKSPACE}/ + - name: setup conda env + shell: /bin/bash {0} + run: | + cd $HOME && mkdir -p cice-dirs/runs cice-dirs/baseline cice-dirs/input + source $HOME/miniconda/bin/activate + conda init tcsh + cd $HOME/cice + conda env create -f configuration/scripts/machines/environment.yml + - name: check conda env + run: | + conda activate cice && which mpicc && which mpifort && which make + mpifort --version + mpicc --version + make --version + - name: check setup case + run: | + cd $HOME/cice + ./cice.setup -m conda -e ${{ matrix.envdef }} -c case0 --pes 1x1 -s diag1 + - name: check setup test + run: | + cd $HOME/cice + ./cice.setup -m conda -e ${{ matrix.envdef }} --test smoke --testid c0 +# - name: compile case +# run: | +# cd $HOME/cice +# ./cice.setup -m conda -e ${{ matrix.envdef }} -c case1 +# cd case1 +# ./cice.build + - name: download input data + run: | + cd $HOME/cice-dirs/input + wget https://zenodo.org/record/3728358/files/CICE_data_gx3_grid_ic-20200320.tar.gz && tar xvfz CICE_data_gx3_grid_ic-20200320.tar.gz + wget https://zenodo.org/record/3728362/files/CICE_data_gx3_forcing_NCAR_bulk-20200320.tar.gz && tar xvfz CICE_data_gx3_forcing_NCAR_bulk-20200320.tar.gz + wget https://zenodo.org/record/3728364/files/CICE_data_gx3_forcing_JRA55-20200320.tar.gz && tar xvfz CICE_data_gx3_forcing_JRA55-20200320.tar.gz + pwd + ls -alR +# - name: run case +# run: | +# cd $HOME/cice +# cd case1 +# ./cice.run + - name: run suite + run: | + cd $HOME/cice + ./cice.setup -m conda -e ${{ matrix.envdef }} --suite travis_suite --testid ${{ matrix.os }} + - name: write output + run: | + cd $HOME/cice + ./.github/workflows/write_logfiles.csh + cd testsuite.${{ matrix.os }} + ./results.csh + - name: successful run + if: ${{ success() }} + run: | + echo "${{ job.name }} PASSED" + - name: trap failure + if: ${{ failure() }} + run: | + echo "${{ job.name }} FAILED" + exit 99 diff --git a/.github/workflows/write_logfiles.csh b/.github/workflows/write_logfiles.csh new file mode 100755 index 000000000..a6777dec6 --- /dev/null +++ b/.github/workflows/write_logfiles.csh @@ -0,0 +1,10 @@ +#!/bin/csh + +#echo "hello" + +foreach logfile (case*/logs/cice.runlog* testsuite.*/*/logs/cice.runlog*) + echo "### ${logfile} ###" + tail -20 $logfile + echo " " +end + diff --git a/README.md b/README.md index a584e8ac9..457714b8a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -[![Build Status](https://travis-ci.org/CICE-Consortium/CICE.svg?branch=master)](https://travis-ci.org/CICE-Consortium/CICE) +[![Travis-CI](https://travis-ci.org/CICE-Consortium/CICE.svg?branch=master)](https://travis-ci.org/CICE-Consortium/CICE) +[![GHActions](https://github.com/CICE-Consortium/CICE/workflows/GHActions/badge.svg)](https://github.com/CICE-Consortium/CICE/actions) [![Documentation Status](https://readthedocs.org/projects/cice-consortium-cice/badge/?version=master)](http://cice-consortium-cice.readthedocs.io/en/master/?badge=master) [![lcov](https://img.shields.io/endpoint?url=https://apcraig.github.io/coverage.json)](https://apcraig.github.io) From 792c23a0c73f808760938750b927e191c17b26d1 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Mon, 25 Jan 2021 15:06:06 -0800 Subject: [PATCH 12/18] Update emissivity to 0.985 and set nblyr default to 1 (#553) Change emissivity default to 0.985 (from 0.95) Change nblyr default to 1 (from 7) Add nblyr=7 to set_nml.zsal Update Icepack to include emissivity default changes Update documentation as needed --- cicecore/cicedynB/general/ice_init.F90 | 4 ++-- configuration/scripts/ice_in | 4 ++-- configuration/scripts/options/set_nml.zsal | 1 + doc/source/cice_index.rst | 2 +- doc/source/user_guide/ug_case_settings.rst | 2 +- icepack | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cicecore/cicedynB/general/ice_init.F90 b/cicecore/cicedynB/general/ice_init.F90 index a16cd7649..3670e174d 100644 --- a/cicecore/cicedynB/general/ice_init.F90 +++ b/cicecore/cicedynB/general/ice_init.F90 @@ -368,7 +368,7 @@ subroutine input_data calc_Tsfc = .true. ! calculate surface temperature update_ocn_f = .false. ! include fresh water and salt fluxes for frazil ustar_min = 0.005 ! minimum friction velocity for ocean heat flux (m/s) - emissivity = 0.95 ! emissivity of snow and ice + emissivity = 0.985 ! emissivity of snow and ice l_mpond_fresh = .false. ! logical switch for including meltpond freshwater ! flux feedback to ocean model fbot_xfer_type = 'constant' ! transfer coefficient type for ocn heat flux @@ -1436,7 +1436,7 @@ subroutine input_data write(nu_diag,1002) ' ahmax = ', ahmax,' : albedo is constant above this thickness' endif endif - write(nu_diag,1002) ' emissivity = ', emissivity,' : emissivity of snow and ice' + write(nu_diag,1000) ' emissivity = ', emissivity,' : emissivity of snow and ice' write(nu_diag,1010) ' sw_redist = ', sw_redist,' : redistribute internal shortwave to surface' if (sw_redist) then write(nu_diag,1002) ' sw_frac = ', sw_frac,' : fraction redistributed' diff --git a/configuration/scripts/ice_in b/configuration/scripts/ice_in index 64060d245..1721541d4 100644 --- a/configuration/scripts/ice_in +++ b/configuration/scripts/ice_in @@ -63,7 +63,7 @@ nfsd = 1 nilyr = 7 nslyr = 1 - nblyr = 7 + nblyr = 1 orca_halogrid = .false. / @@ -195,7 +195,7 @@ natmiter = 5 atmiter_conv = 0.0d0 ustar_min = 0.0005 - emissivity = 0.95 + emissivity = 0.985 fbot_xfer_type = 'constant' update_ocn_f = .false. l_mpond_fresh = .false. diff --git a/configuration/scripts/options/set_nml.zsal b/configuration/scripts/options/set_nml.zsal index 7e8ed47ff..c099fed8c 100644 --- a/configuration/scripts/options/set_nml.zsal +++ b/configuration/scripts/options/set_nml.zsal @@ -1,3 +1,4 @@ +nblyr = 7 ktherm = 1 sw_redist = .true. tfrz_option = 'linear_salt' diff --git a/doc/source/cice_index.rst b/doc/source/cice_index.rst index 8ea16261d..caaf87d5a 100644 --- a/doc/source/cice_index.rst +++ b/doc/source/cice_index.rst @@ -188,7 +188,7 @@ either Celsius or Kelvin units). "e11, e12, e22", "strain rate tensor components", "" "ecci", "yield curve minor/major axis ratio, squared", "1/4" "eice(n)", "energy of melting of ice per unit area (in category n)", "J/m\ :math:`^2`" - "emissivity", "emissivity of snow and ice", "0.95" + "emissivity", "emissivity of snow and ice", "0.985" "eps13", "a small number", "10\ :math:`^{-13}`" "eps16", "a small number", "10\ :math:`^{-16}`" "esno(n)", "energy of melting of snow per unit area (in category n)", "J/m\ :math:`^2`" diff --git a/doc/source/user_guide/ug_case_settings.rst b/doc/source/user_guide/ug_case_settings.rst index 3cf271386..a14e571dc 100644 --- a/doc/source/user_guide/ug_case_settings.rst +++ b/doc/source/user_guide/ug_case_settings.rst @@ -492,7 +492,7 @@ forcing_nml "``calc_Tsfc``", "logical", "calculate surface temperature", "``.true.``" "``default_season``", "``summer``", "forcing initial summer values", "``winter``" "", "``winter``", "forcing initial winter values", "" - "``emissivity``", "real", "emissivity of snow and ice", "0.95" + "``emissivity``", "real", "emissivity of snow and ice", "0.985" "``fbot_xfer_type``", "``Cdn_ocn``", "variabler ocean heat transfer coefficient scheme", "``constant``" "", "``constant``", "constant ocean heat transfer coefficient", "" "``fe_data_type``", "``clim``", "ocean climatology forcing value for iron", "``default``" diff --git a/icepack b/icepack index af7e38f81..349b3f49a 160000 --- a/icepack +++ b/icepack @@ -1 +1 @@ -Subproject commit af7e38f8107b2ec8680cf5a49d7274b43fe34248 +Subproject commit 349b3f49af407be06f9f37014883ecae0daed5d1 From 6bf09ec40be3200c21c9aff5446093faac2b34d2 Mon Sep 17 00:00:00 2001 From: TRasmussen <33480590+TillRasmussen@users.noreply.github.com> Date: Thu, 4 Feb 2021 23:51:06 +0100 Subject: [PATCH 13/18] OMP loop removal of unused private variables and added 1d evp teest (#561) * Add DMI Cray XC50 hpc (freya) to machines. Based on Banting * Removed depreciated cpp and added gnu to freya * added flag to test evp1d * OMP private variables are not used in this loop. should be removed --- cicecore/cicedynB/infrastructure/ice_grid.F90 | 2 +- configuration/scripts/cice.batch.csh | 2 +- configuration/scripts/options/set_nml.kevp102 | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 configuration/scripts/options/set_nml.kevp102 diff --git a/cicecore/cicedynB/infrastructure/ice_grid.F90 b/cicecore/cicedynB/infrastructure/ice_grid.F90 index 67129c911..c14811075 100644 --- a/cicecore/cicedynB/infrastructure/ice_grid.F90 +++ b/cicecore/cicedynB/infrastructure/ice_grid.F90 @@ -1663,7 +1663,7 @@ subroutine makemask field_loc_center, field_type_scalar) call ice_timer_stop(timer_bound) - !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) + !$OMP PARALLEL DO PRIVATE(iblk,i,j) do iblk = 1, nblocks do j = 1, ny_block do i = 1, nx_block diff --git a/configuration/scripts/cice.batch.csh b/configuration/scripts/cice.batch.csh index d6f78313f..6d1f735a4 100755 --- a/configuration/scripts/cice.batch.csh +++ b/configuration/scripts/cice.batch.csh @@ -185,7 +185,7 @@ cat >> ${jobfile} << EOFB #SBATCH --qos=standby EOFB -else if (${ICE_MACHINE} =~ daley* || ${ICE_MACHINE} =~ banting*) then +else if (${ICE_MACHINE} =~ daley* || ${ICE_MACHINE} =~ banting* ) then cat >> ${jobfile} << EOFB #PBS -N ${ICE_CASENAME} #PBS -j oe diff --git a/configuration/scripts/options/set_nml.kevp102 b/configuration/scripts/options/set_nml.kevp102 new file mode 100644 index 000000000..3a5dc3dbd --- /dev/null +++ b/configuration/scripts/options/set_nml.kevp102 @@ -0,0 +1 @@ +kevp_kernel = 102 From d9a9f6d3f2f076c438c3271b984787a5dd70dc10 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Thu, 11 Feb 2021 20:54:20 -0800 Subject: [PATCH 14/18] Update JRA55 forcing implementation (#562) * Update JRA55 forcing implementation Several bug fixes addressed - Reading two timesteps instead of 1 now (was reading the same timestep into both slots) - Advancing files by year (was just cycling the initial year in a multi-year run) - Time interpolation updated (was not working in multi-year runs) - Interpolate 4 input states in time, but hold 3 input fluxes constant over 3 hour forcing period - Additional output diagnosing forcing filename as it evolves * Add forcing documentation to user guide * add jra55data schematic figure * update forcing documentation, add Hunke07 reference --- cicecore/cicedynB/general/ice_forcing.F90 | 244 +++++++++--------- doc/source/developer_guide/dg_forcing.rst | 217 ++++++++++++++++ .../developer_guide/figures/jra55data.png | Bin 0 -> 48906 bytes doc/source/developer_guide/index.rst | 1 + doc/source/master_list.bib | 9 + 5 files changed, 354 insertions(+), 117 deletions(-) mode change 100755 => 100644 cicecore/cicedynB/general/ice_forcing.F90 create mode 100644 doc/source/developer_guide/dg_forcing.rst create mode 100644 doc/source/developer_guide/figures/jra55data.png diff --git a/cicecore/cicedynB/general/ice_forcing.F90 b/cicecore/cicedynB/general/ice_forcing.F90 old mode 100755 new mode 100644 index 43cf92a48..edbba8101 --- a/cicecore/cicedynB/general/ice_forcing.F90 +++ b/cicecore/cicedynB/general/ice_forcing.F90 @@ -533,17 +533,21 @@ subroutine get_forcing_atmo integer (kind=int_kind) :: & iblk, & ! block index ilo,ihi,jlo,jhi, & ! beginning and end of physical domain + fyear_old, & ! prior fyear value nt_Tsfc type (block) :: & this_block ! block information for current block character(len=*), parameter :: subname = '(get_forcing_atmo)' - + + fyear_old = fyear fyear = fyear_init + mod(nyr-1,ycycle) ! current year - if (trim(atm_data_type) /= 'default' .and. istep <= 1 & - .and. my_task == master_task) then - write (nu_diag,*) ' Current forcing data year = ',fyear + if (trim(atm_data_type) /= 'default' .and. & + (istep <= 1 .or. fyear /= fyear_old)) then + if (my_task == master_task) then + write (nu_diag,*) ' Current forcing data year = ',fyear + endif endif call icepack_query_tracer_indices(nt_Tsfc_out=nt_Tsfc) @@ -2322,162 +2326,174 @@ subroutine JRA55_data (yr) use ice_state, only: aice use ice_calendar, only: days_per_year, use_leap_years + integer (kind=int_kind), intent(in) :: & + yr ! current forcing year + integer (kind=int_kind) :: & ncid , & ! netcdf file id - i, j , & - ixm,ixx,ixp , & ! record numbers for neighboring months + i, j, n1, iblk, & + yrp , & ! year after yr in forcing cycle recnum , & ! record number maxrec , & ! maximum record number recslot , & ! spline slot for current record - midmonth , & ! middle day of month - dataloc , & ! = 1 for data located in middle of time interval + dataloc ! = 1 for data located in middle of time interval ! = 2 for date located at end of time interval - iblk , & ! block index - ilo,ihi,jlo,jhi, & ! beginning and end of physical domain - yr ! current forcing year real (kind=dbl_kind) :: & sec3hr , & ! number of seconds in 3 hours secday , & ! number of seconds in day + eps, tt , & ! interpolation coeff calc Tffresh , & vmin, vmax - logical (kind=log_kind) :: readm, read6,debug_n_d - - type (block) :: & - this_block ! block information for current block + logical (kind=log_kind) :: debug_n_d = .false. + character (char_len_long) :: uwind_file_old character(len=64) :: fieldname !netcdf field name character(len=*), parameter :: subname = '(JRA55_data)' - debug_n_d = .false. !usually false - call icepack_query_parameters(Tffresh_out=Tffresh) call icepack_query_parameters(secday_out=secday) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) - !------------------------------------------------------------------- - ! 3-hourly data - ! - ! Assume that the 3-hourly value is located at the end of the - ! 3-hour period. This is the convention for NCEP reanalysis data. - ! E.g. record 1 gives conditions at 3 am GMT on 1 January. - !------------------------------------------------------------------- - - dataloc = 2 ! data located at end of interval sec3hr = secday/c8 ! seconds in 3 hours - !maxrec = 2920 ! 365*8; for leap years = 366*8 - - if (use_leap_years) days_per_year = 366 !overrides setting of 365 in ice_calendar maxrec = days_per_year*8 - if(days_per_year == 365 .and. (mod(yr, 4) == 0)) then - call abort_ice('days_per_year should be set to 366 for leap years') - end if + if (debug_n_d .and. my_task == master_task) then + write (nu_diag,*) subname,'recnum',recnum + write (nu_diag,*) subname,'maxrec',maxrec + write (nu_diag,*) subname,'days_per_year', days_per_year + endif - ! current record number - recnum = 8*int(yday) - 7 + int(real(sec,kind=dbl_kind)/sec3hr) + !------------------------------------------------------------------- + ! 3-hourly data + ! states are instantaneous, 1st record is 00z Jan 1 + ! fluxes are 3 hour averages, 1st record is 00z-03z Jan 1 + ! Both states and fluxes have 1st record defined as 00z Jan 1 + ! interpolate states, do not interpolate fluxes + ! fluxes are held constant from [init period, end period) + !------------------------------------------------------------------- + ! File is NETCDF with winds in NORTH and EAST direction + ! file variable names are: + ! glbrad (shortwave W/m^2) + ! dlwsfc (longwave W/m^2) + ! wndewd (eastward wind m/s) + ! wndnwd (northward wind m/s) + ! airtmp (air temperature K) + ! spchmd (specific humidity kg/kg) + ! ttlpcp (precipitation kg/m s-1) + !------------------------------------------------------------------- - ! Compute record numbers for surrounding data (2 on each side) + uwind_file_old = uwind_file + call file_year(uwind_file,yr) + if (uwind_file /= uwind_file_old .and. my_task == master_task) then + write(nu_diag,*) subname,' reading forcing file = ',trim(uwind_file) + endif - ixm = mod(recnum+maxrec-2,maxrec) + 1 - ixx = mod(recnum-1, maxrec) + 1 + call ice_open_nc(uwind_file,ncid) - ! Compute interpolation coefficients - ! If data is located at the end of the time interval, then the - ! data value for the current record goes in slot 2 + do n1 = 1,2 - recslot = 2 - ixp = -99 - call interp_coeff (recnum, recslot, sec3hr, dataloc) + if (n1 == 1) then + recnum = 8*int(yday) - 7 + int(real(sec,kind=dbl_kind)/sec3hr) + if (my_task == master_task .and. (recnum <= 2 .or. recnum >= maxrec-1)) then + write(nu_diag,*) subname,' reading forcing file 1st ts = ',trim(uwind_file) + endif + elseif (n1 == 2) then + recnum = 8*int(yday) - 7 + int(real(sec,kind=dbl_kind)/sec3hr) + 1 + if (recnum > maxrec) then + yrp = fyear_init + mod(nyr,ycycle) ! next year + recnum = 1 + call file_year(uwind_file,yrp) + if (my_task == master_task) then + write(nu_diag,*) subname,' reading forcing file 2nd ts = ',trim(uwind_file) + endif + call ice_close_nc(ncid) + call ice_open_nc(uwind_file,ncid) + endif + endif - ! Read - read6 = .false. - if (istep==1 .or. oldrecnum .ne. recnum) read6 = .true. - !------------------------------------------------------------------- - ! File is NETCDF with winds in NORTH and EAST direction - ! file variable names are: - ! glbrad (shortwave W/m^2) - ! dlwsfc (longwave W/m^2) - ! wndewd (eastward wind m/s) - ! wndnwd (northward wind m/s) - ! airtmp (air temperature K) - ! spchmd (specific humidity kg/kg) - ! ttlpcp (precipitation kg/m s-1) - !------------------------------------------------------------------- - call ice_open_nc(uwind_file,ncid) - - fieldname = 'airtmp' - call ice_read_nc(ncid,recnum,fieldname,Tair_data(:,:,1,:),debug_n_d, & - field_loc=field_loc_center, & - field_type=field_type_scalar) - call ice_read_nc(ncid,recnum,fieldname,Tair_data(:,:,2,:),debug_n_d, & - field_loc=field_loc_center, & - field_type=field_type_scalar) + if (debug_n_d .and. my_task == master_task) then + write(nu_diag,*) subname,' read recnum = ',recnum,n1 + endif - fieldname = 'wndewd' - call ice_read_nc(ncid,recnum,fieldname,uatm_data(:,:,1,:),debug_n_d, & - field_loc=field_loc_center, & - field_type=field_type_scalar) - call ice_read_nc(ncid,recnum,fieldname,uatm_data(:,:,2,:),debug_n_d, & + fieldname = 'airtmp' + call ice_read_nc(ncid,recnum,fieldname,Tair_data(:,:,n1,:),debug_n_d, & field_loc=field_loc_center, & field_type=field_type_scalar) - fieldname = 'wndnwd' - call ice_read_nc(ncid,recnum,fieldname,vatm_data(:,:,1,:),debug_n_d, & - field_loc=field_loc_center, & - field_type=field_type_scalar) - call ice_read_nc(ncid,recnum,fieldname,vatm_data(:,:,2,:),debug_n_d, & + fieldname = 'wndewd' + call ice_read_nc(ncid,recnum,fieldname,uatm_data(:,:,n1,:),debug_n_d, & field_loc=field_loc_center, & field_type=field_type_scalar) - fieldname = 'spchmd' - call ice_read_nc(ncid,recnum,fieldname,Qa_data(:,:,1,:),debug_n_d, & - field_loc=field_loc_center, & - field_type=field_type_scalar) - call ice_read_nc(ncid,recnum,fieldname,Qa_data(:,:,2,:),debug_n_d, & + fieldname = 'wndnwd' + call ice_read_nc(ncid,recnum,fieldname,vatm_data(:,:,n1,:),debug_n_d, & field_loc=field_loc_center, & field_type=field_type_scalar) - fieldname = 'glbrad' - call ice_read_nc(ncid,recnum,fieldname,fsw_data(:,:,1,:),debug_n_d, & - field_loc=field_loc_center, & - field_type=field_type_scalar) - call ice_read_nc(ncid,recnum,fieldname,fsw_data(:,:,2,:),debug_n_d, & + fieldname = 'spchmd' + call ice_read_nc(ncid,recnum,fieldname,Qa_data(:,:,n1,:),debug_n_d, & field_loc=field_loc_center, & field_type=field_type_scalar) - fieldname = 'dlwsfc' - call ice_read_nc(ncid,recnum,fieldname,flw_data(:,:,1,:),debug_n_d, & - field_loc=field_loc_center, & - field_type=field_type_scalar) - call ice_read_nc(ncid,recnum,fieldname,flw_data(:,:,2,:),debug_n_d, & + ! only read one timestep for fluxes, 3 hr average, no interpolation + if (n1 == 1) then + fieldname = 'glbrad' + call ice_read_nc(ncid,recnum,fieldname,fsw_data(:,:,n1,:),debug_n_d, & field_loc=field_loc_center, & field_type=field_type_scalar) - fieldname = 'ttlpcp' - call ice_read_nc(ncid,recnum,fieldname,fsnow_data(:,:,1,:),debug_n_d, & + fieldname = 'dlwsfc' + call ice_read_nc(ncid,recnum,fieldname,flw_data(:,:,n1,:),debug_n_d, & field_loc=field_loc_center, & field_type=field_type_scalar) - call ice_read_nc(ncid,recnum,fieldname,fsnow_data(:,:,2,:),debug_n_d, & + + fieldname = 'ttlpcp' + call ice_read_nc(ncid,recnum,fieldname,fsnow_data(:,:,n1,:),debug_n_d, & field_loc=field_loc_center, & field_type=field_type_scalar) + endif + + enddo + + call ice_close_nc(ncid) - call ice_close_nc(ncid) + ! reset uwind_file to original year + call file_year(uwind_file,yr) + ! Compute interpolation coefficients + eps = 1.0e-6 + tt = real(mod(sec,nint(sec3hr)),kind=dbl_kind) + c2intp = tt / sec3hr + if (c2intp < c0 .and. c2intp > c0-eps) c2intp = c0 + if (c2intp > c1 .and. c2intp < c1+eps) c2intp = c1 + c1intp = 1.0_dbl_kind - c2intp + if (c2intp < c0 .or. c2intp > c1) then + write(nu_diag,*) subname,' ERROR: c2intp = ',c2intp + call abort_ice (error_message=subname//' ERROR: c2intp out of range', & + file=__FILE__, line=__LINE__) + endif + if (debug_n_d .and. my_task == master_task) then + write(nu_diag,*) subname,' c12intp = ',c1intp,c2intp + endif ! Interpolate call interpolate_data (Tair_data, Tair) call interpolate_data (uatm_data, uatm) call interpolate_data (vatm_data, vatm) call interpolate_data (Qa_data, Qa) - call interpolate_data (fsw_data, fsw) - call interpolate_data (flw_data, flw) - call interpolate_data (fsnow_data, fsnow) + ! use 3 hr average for heat flux and precip fields + ! call interpolate_data (fsw_data, fsw) + ! call interpolate_data (flw_data, flw) + ! call interpolate_data (fsnow_data, fsnow) + fsw(:,:,:) = fsw_data(:,:,1,:) + flw(:,:,:) = flw_data(:,:,1,:) + fsnow(:,:,:) = fsnow_data(:,:,1,:) - !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) + !$OMP PARALLEL DO PRIVATE(iblk,i,j) do iblk = 1, nblocks ! limit summer Tair values where ice is present do j = 1, ny_block @@ -2501,43 +2517,37 @@ subroutine JRA55_data (yr) enddo ! iblk !$OMP END PARALLEL DO - ! Save record number - oldrecnum = recnum - - if (dbug) then - if (my_task == master_task) write (nu_diag,*) 'JRA55_bulk_data' + if (debug_n_d .or. dbug) then + if (my_task.eq.master_task) & + write (nu_diag,*) subname,'JRA55_bulk_data' vmin = global_minval(fsw,distrb_info,tmask) - vmax = global_maxval(fsw,distrb_info,tmask) - if (my_task.eq.master_task) & - write (nu_diag,*) 'fsw',vmin,vmax + if (my_task.eq.master_task) & + write (nu_diag,*) subname,'fsw',vmin,vmax vmin = global_minval(flw,distrb_info,tmask) vmax = global_maxval(flw,distrb_info,tmask) if (my_task.eq.master_task) & - write (nu_diag,*) 'flw',vmin,vmax + write (nu_diag,*) subname,'flw',vmin,vmax vmin =global_minval(fsnow,distrb_info,tmask) vmax =global_maxval(fsnow,distrb_info,tmask) if (my_task.eq.master_task) & - write (nu_diag,*) 'fsnow',vmin,vmax + write (nu_diag,*) subname,'fsnow',vmin,vmax vmin = global_minval(Tair,distrb_info,tmask) vmax = global_maxval(Tair,distrb_info,tmask) if (my_task.eq.master_task) & - write (nu_diag,*) 'Tair',vmin,vmax + write (nu_diag,*) subname,'Tair',vmin,vmax vmin = global_minval(uatm,distrb_info,umask) vmax = global_maxval(uatm,distrb_info,umask) if (my_task.eq.master_task) & - write (nu_diag,*) 'uatm',vmin,vmax + write (nu_diag,*) subname,'uatm',vmin,vmax vmin = global_minval(vatm,distrb_info,umask) vmax = global_maxval(vatm,distrb_info,umask) if (my_task.eq.master_task) & - write (nu_diag,*) 'vatm',vmin,vmax + write (nu_diag,*) subname,'vatm',vmin,vmax vmin = global_minval(Qa,distrb_info,tmask) vmax = global_maxval(Qa,distrb_info,tmask) - if (my_task.eq.master_task) & - write (nu_diag,*) 'Qa',vmin,vmax - if (my_task.eq.master_task) & - write (nu_diag,*) 'maxrec',maxrec - write (nu_diag,*) 'days_per_year', days_per_year + if (my_task.eq.master_task) & + write (nu_diag,*) subname,'Qa',vmin,vmax endif ! dbug diff --git a/doc/source/developer_guide/dg_forcing.rst b/doc/source/developer_guide/dg_forcing.rst new file mode 100644 index 000000000..90ef843b0 --- /dev/null +++ b/doc/source/developer_guide/dg_forcing.rst @@ -0,0 +1,217 @@ +:tocdepth: 3 + +.. _forcing: + +Standalone Forcing +====================== + +Users are strongly encouraged to run CICE in a coupled system (see :ref:`coupl`) to improve +quality of science. The standalone mode is best used for technical testing +and only preliminary science testing. Several different input forcing datasets have +been implemented over the history of CICE. Some have become obsolete, others +have been supplanted by newer forcing data options, and others have been implemented +by outside users and are not testable by the Consortium. The forcing code has +generally not been maintained by the Consortium and only a subset of the code is +tested by the Consortium. + +The forcing implementation can be found in the file +**cicecore/cicedynB/general/ice_forcing.F90**. As noted above, only a subset of the +forcing modes are tested and supported. In many ways, the implemetation is fairly +primitive, in part due to historical reasons and in part because standalone runs +are discouraged for evaluating complex science. In general, most implementations +use aspects of the following approach, + +- Input files are organized by year. +- Namelist inputs ``fyear`` and ``ycycle`` specify the forcing year dataset. +- The forcing year is computed on the fly and is assumed to be cyclical over the forcing dataset length defined by ``ycycle``. +- The namelist ``atm_dat_dir`` specifies the directory of the atmosphere input data files and the namelist ``atm_data_type`` defines the atmospheric forcing mode. +- The namelist ``ocn_dat_dir`` specifies the directory of the ocean input data files and the namelist ``ocn_data_type`` defines the ocean forcing mode. +- The filenames follow a particular naming convention that is defined in the source code (ie. subroutine **JRA55_gx1_files**). The forcing year is typically found just before the **.nc** part of the filename and there are tools (subroutine **file_year**) to update the filename based on the model year and appropriate forcing year. +- The input data time axis is generally NOT read by the forcing subroutine. The forcing frequency is hardwired into the model and the file record number is computed based on the forcing frequency and model time. Mixing leap year input data and noleap model calendars (and vice versa) is not handled particularly gracefully. The CICE model does not read or check against the input data time axis. +- Data is read on the model grid, no spatial interpolation exists. +- Data is often time interpolated linearly between two input timestamps to the model time each model timestep. + +In general, the following variables need to be defined by the forcing module, + +From Atmosphere: + +- zlvl = atmosphere level height (m) +- uatm = model grid i-direction wind velocity component (m/s) +- vatm = model grid j-direction wind velocity component (m/s) +- strax = model grid i-direction wind stress (N/m^2) +- stray = model grid j-direction wind stress (N/m^2) +- potT = air potential temperature (K) +- Tair = air temperature (K) +- Qa = specific humidity (kg/kg) +- rhoa = air density (kg/m^3) +- flw = incoming longwave radiation (W/m^2) +- fsw = incoming shortwave radiation (W/m^2) +- swvdr = sw down, visible, direct (W/m^2) +- swvdf = sw down, visible, diffuse (W/m^2) +- swidr = sw down, near IR, direct (W/m^2) +- swidf = sw down, near IR, diffuse (W/m^2) +- frain = rainfall rate (kg/m^2 s) +- fsnow = snowfall rate (kg/m^2 s) + +From Ocean: + +- uocn = ocean current, x-direction (m/s) +- vocn = ocean current, y-direction (m/s) +- ss_tltx = sea surface slope, x-direction (m/m) +- ss_tlty = sea surface slope, y-direction (m/m) +- hwater = water depth for basal stress calc (landfast ice) +- sss = sea surface salinity (ppt) +- sst = sea surface temperature (C) +- frzmlt = freezing/melting potential (W/m^2) +- frzmlt_init= frzmlt used in current time step (W/m^2) +- Tf = freezing temperature (C) +- qdp = deep ocean heat flux (W/m^2), negative upward +- hmix = mixed layer depth (m) +- daice_da= data assimilation concentration increment rate (concentration s-1)(only used in hadgem drivers) + +All variables have reasonable but static defaults and these will be used in ``default`` mode. + +To advance the forcing, the subroutines **get_forcing_atmo** and +**get_forcing_ocn** are called each timestep from the step +loop. That subroutine computes the forcing year (``fyear``), calls the appropriate +forcing data method, and then calls **prepare_forcing** which converts the +input data fields to model forcing fields. + +.. _JRA55forcing: + +JRA55 Atmosphere Forcing +------------------------- + +The current default atmosphere forcing for gx3, gx1, and tx1 standalone grids for +Consortium testing is the JRA55 forcing +dataset :cite:`Tsujino18`. The Consortium has released 5 years of forcing data, +2005-2009 for gx3, gx1, and tx1 grids. Each year is a separate file and +the dataset is on a gregorian time axis which includes leap days. + +.. _fig-jra55data: + +.. figure:: ./figures/jra55data.png + :align: center + :scale: 100% + + Schematic of JRA55 CICE forcing file generation. + +The forcing is read and interpolated in subroutine **JRA55_data**. In particular, +air temperature (``airtmp``), east and north wind speed (``wndewd`` and ``wndnwd``), +specific humidity (``spchmd``), incoming short and longwave radiation (``glbrad`` and ``dswsfc``), +and precipitation (``ttlpcp``) are read from the input files. The JRA55 reanalysis is +run with updated initial conditions every 6 hours and output is written every 3 hours. +The four state fields (air temperature, winds, specific humidity) +are instantaneous data, while the three flux fields (radition, precipitation) are 3 +hour averages. In the JRA55 forcing files provided by the Consortium, the time +defined for 3 hour average fields is shifted 3 hours to the start time of the 3 +hour interval. **NOTE that this is different +from the implementation on the original JRA55 files and also different from how models +normally define time on an accumulated/averaged field**. This is all shown +schematically in Figure :ref:`fig-jra55data`. + +The state fields are linearly +time interpolated between input timestamps +while the flux fields are read and held constant during each 3 hour model period. +The forcing frequency is hardwired to 3 hours in the implementation, +and the record number is computed based on the time of the current model year. +Time interpolation coefficients are computed in the **JRA55_data** subroutine. + +The forcing data is converted to model inputs in the subroutine **prepare_forcing** +called in **get_forcing_atmo**. To clarify, the JRA55 input data includes + +- uatm = model grid i-direction wind velocity component (m/s) +- vatm = model grid j-direction wind velocity component (m/s) +- Tair = air temperature (K) +- Qa = specific humidity (kg/kg) +- flw = incoming longwave radiation (W/m^2) +- fsw = incoming shortwave radiation (W/m^2) +- fsnow = snowfall rate (kg/m^2 s) + +and model forcing inputs are derived from those fields and the defaults. + +Because the input files are on the gregorian time axis, the model can run with the regular +365 day (noleap) calendar, but in that case, the Feb 29 input data will be used on +March 1, and all data +after March 1 will be shifted one day. December 31 in leap years will be skipped when +running with a CICE calendar with no leap days. + + +.. _NCARforcing: + +NCAR Atmosphere Forcing +------------------------- + +The NCAR atmospheric forcing was used in earlier standalone runs on the gx3 grid, and the +Consortium continues to do some limited testing with this forcing dataset. +Monthly average data for fsw, cldf, fsnow are read. 6-hourly data for +Tair, uatm, vatm, rhoa, and Qa are also read. +Users are encouraged to switch to the JRA55 (see :ref:`JRA55forcing`) dataset. This +atmosphere forcing dataset may be deprecated in the future. + + +.. _LYqforcing: + +LYq Atmosphere Forcing +------------------------- + +The LYq (:cite:`Hunke07`) forcing was used in earlier standalone +runs on the gx1 grid, and the +Consortium continues to do some very limited testing with this forcing dataset. +This dataset is largely based on the CORE II data. +Monthly average data for cldf and fsnow is read while 6-hourly data for Qa, Tair, +uatm, and vatm are read with other fields derived or set by default. +Users are encouraged to switch to the JRA55 (see :ref:`JRA55forcing`) dataset. This +atmosphere forcing dataset may be deprecated in the future. + + +.. _defaultforcing: + +Default Atmosphere Forcing +---------------------------- + +The default atmosphere forcing option sets the atmosphere forcing +internally. No files are read. Values for forcing fields are defined +at initialization in subroutine **init_coupler_flux** and held +constant thereafter. Different conditions can be specified thru the +``default_season`` namelist variable. + + +.. _box2001forcing: + +Box2001 Atmosphere Forcing +------------------------- + +The box2001 forcing dataset in generated internally. No files are read. The +dataset is used to test an idealized box case as defined in :cite:`Hunke01`. + + +.. _otheratmforcing: + +Other Atmosphere Forcing +------------------------- + +There are a few other atmospheric forcing modes, as defined by ``atm_data_type``, but +they are not tested by the Consortium on a regular basis. + + +.. _defaultocnforcing: + +Default Ocean Forcing +------------------------- + +The ``default`` ocean setting is the standard setting used in standalone CICE runs. +In this mode, the sea surface salinity is set to 34 ppt and the sea surface +temperature is set to the freezing temperature at all grid points and +held constant unless the mixed layer parameterization is turned on, in which +case the SST evolves. Other ocean coupling fields are set to zero. No files are read. + + +.. _otherocnforcing: + +Other Ocean Forcing +------------------------- + +There are a few other ocean forcing modes, as defined by ``ocn_data_type``, but +they are not tested by the Consortium on a regular basis. + diff --git a/doc/source/developer_guide/figures/jra55data.png b/doc/source/developer_guide/figures/jra55data.png new file mode 100644 index 0000000000000000000000000000000000000000..5fee7b062a84247558566f8dbb391ff1f625e3e8 GIT binary patch literal 48906 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 literal 0 HcmV?d00001 diff --git a/doc/source/developer_guide/index.rst b/doc/source/developer_guide/index.rst index 1b016f6d9..ab5b2d1e6 100644 --- a/doc/source/developer_guide/index.rst +++ b/doc/source/developer_guide/index.rst @@ -14,6 +14,7 @@ Developer Guide dg_about.rst dg_dynamics.rst dg_driver.rst + dg_forcing.rst dg_icepack.rst dg_scripts.rst dg_other.rst diff --git a/doc/source/master_list.bib b/doc/source/master_list.bib index 0b928d012..7c2a45a35 100644 --- a/doc/source/master_list.bib +++ b/doc/source/master_list.bib @@ -660,6 +660,15 @@ @Article{Golden07 issue = {16}, url = {http://dx.doi.org/10.1029/2007GL030447} } +@Article{Hunke07 + author = "E. Hunke and M.M. Holland", + title = "{Global atmospheric forcing data for Arctic ice-ocean modeling}", + journal = JGRO, + year = {2007}, + volume = {112}, + number = {C4}, + url = {http://dx.doi.org/10.1029/2006JC003640} +} @Article{Lipscomb07 author = "W.H. Lipscomb and E.C. Hunke and W. Maslowski and J. Jakacki", title = "{Ridging, strength, and stability in high-resolution sea ice models}", From 3c516c89552376b2a3903979b0296e31a2b6691c Mon Sep 17 00:00:00 2001 From: JFLemieux73 <31927797+JFLemieux73@users.noreply.github.com> Date: Mon, 22 Feb 2021 18:38:33 -0500 Subject: [PATCH 15/18] Add probabilistic grounding scheme for landfast ice (#565) * In the process of adding seabed2 parameterization * Added calls foe icepack_query_parameters * Modified modules used in subroutine to match latest code (it now compiles) * Changed expression basal stress to seabed stress * Replaced basal by better expression seabed at many places * seabed everywhere...basalstress logical replaced by seabedstress * Added kseabed in namelist for choosing seabed stress method * Changed gacc to gravit (from icepack) and use of alphab from ice_in * Cleaned up the seabed2 code, added comments * Changing the doc for new grounding scheme * Almost done with the doc * Minor changes to the doc * Modifs to the doc * Value of sigmab was not the right one with respect to Dupont et el in prep * For some rebase did not work completely...replced basalstress logical by seabedstress * Other issue with the rebase for ice_init...fixed * Minor mistake corrected...it compiles * changed basalstress to seabedstress in options for tests * Addressed some of the changes required for the PR * Replace kseabed by character string for choice of method * Updated the doc * Cosmetic change ice_init * Update doc/source/user_guide/ug_testing.rst Co-authored-by: Philippe Blain * Cosmetic changes to ice_init to align prints * Some modifs requested for PR: same taub after 4 months (gx1) * Done with requested changes to new grounding method: same taub after 4 months (gx1) * Modifs to doc and new test of prob method Co-authored-by: Philippe Blain --- cicecore/cicedynB/analysis/ice_history.F90 | 4 +- cicecore/cicedynB/dynamics/ice_dyn_eap.F90 | 31 +- cicecore/cicedynB/dynamics/ice_dyn_evp.F90 | 35 +- cicecore/cicedynB/dynamics/ice_dyn_evp_1d.F90 | 10 +- cicecore/cicedynB/dynamics/ice_dyn_shared.F90 | 261 ++++++++-- cicecore/cicedynB/dynamics/ice_dyn_vp.F90 | 44 +- cicecore/cicedynB/general/ice_flux.F90 | 16 +- cicecore/cicedynB/general/ice_init.F90 | 464 +++++++++--------- cicecore/cicedynB/infrastructure/ice_grid.F90 | 16 +- .../drivers/direct/hadgem3/CICE_InitMod.F90 | 2 +- configuration/scripts/ice_in | 3 +- configuration/scripts/options/set_nml.alt01 | 3 +- configuration/scripts/options/set_nml.alt03 | 2 +- .../scripts/options/set_nml.boxrestore | 2 +- doc/source/cice_index.rst | 2 + doc/source/science_guide/sg_dynamics.rst | 90 +++- doc/source/user_guide/ug_case_settings.rst | 6 +- doc/source/user_guide/ug_testing.rst | 2 +- 18 files changed, 658 insertions(+), 335 deletions(-) diff --git a/cicecore/cicedynB/analysis/ice_history.F90 b/cicecore/cicedynB/analysis/ice_history.F90 index 660676a64..1aa2515a4 100644 --- a/cicecore/cicedynB/analysis/ice_history.F90 +++ b/cicecore/cicedynB/analysis/ice_history.F90 @@ -925,12 +925,12 @@ subroutine init_hist (dt) ns1, f_strinty) call define_hist_field(n_taubx,"taubx","N/m^2",ustr2D, ucstr, & - "basal (seabed) stress (x)", & + "seabed (basal) stress (x)", & "positive is x direction on U grid", c1, c0, & ns1, f_taubx) call define_hist_field(n_tauby,"tauby","N/m^2",ustr2D, ucstr, & - "basal (seabed) stress (y)", & + "seabed (basal) stress (y)", & "positive is y direction on U grid", c1, c0, & ns1, f_tauby) diff --git a/cicecore/cicedynB/dynamics/ice_dyn_eap.F90 b/cicecore/cicedynB/dynamics/ice_dyn_eap.F90 index e6bb86bff..2face07c2 100644 --- a/cicecore/cicedynB/dynamics/ice_dyn_eap.F90 +++ b/cicecore/cicedynB/dynamics/ice_dyn_eap.F90 @@ -122,7 +122,8 @@ subroutine eap (dt) use ice_dyn_shared, only: fcor_blk, ndte, dtei, & denom1, uvel_init, vvel_init, arlx1i, & dyn_prep1, dyn_prep2, stepu, dyn_finish, & - basal_stress_coeff, basalstress, & + seabed_stress_factor_LKD, seabed_stress_factor_prob, & + seabed_stress_method, seabed_stress, & stack_velocity_field, unstack_velocity_field use ice_flux, only: rdg_conv, strairxT, strairyT, & strairx, strairy, uocn, vocn, ss_tltx, ss_tlty, iceumask, fm, & @@ -383,17 +384,31 @@ subroutine eap (dt) endif !----------------------------------------------------------------- - ! basal stress coefficients (landfast ice) + ! seabed stress factor Tbu (Tbu is part of Cb coefficient) !----------------------------------------------------------------- - if (basalstress) then + if (seabed_stress) then + !$OMP PARALLEL DO PRIVATE(iblk) do iblk = 1, nblocks - call basal_stress_coeff (nx_block, ny_block, & - icellu (iblk), & - indxui(:,iblk), indxuj(:,iblk), & - vice(:,:,iblk), aice(:,:,iblk), & - hwater(:,:,iblk), Tbu(:,:,iblk)) + + if ( seabed_stress_method == 'LKD' ) then + + call seabed_stress_factor_LKD (nx_block, ny_block, & + icellu (iblk), & + indxui(:,iblk), indxuj(:,iblk), & + vice(:,:,iblk), aice(:,:,iblk), & + hwater(:,:,iblk), Tbu(:,:,iblk)) + + elseif ( seabed_stress_method == 'probabilistic' ) then + + call seabed_stress_factor_prob (nx_block, ny_block, & + icellt(iblk), indxti(:,iblk), indxtj(:,iblk), & + icellu(iblk), indxui(:,iblk), indxuj(:,iblk), & + aicen(:,:,:,iblk), vicen(:,:,:,iblk), & + hwater(:,:,iblk), Tbu(:,:,iblk)) + endif + enddo !$OMP END PARALLEL DO endif diff --git a/cicecore/cicedynB/dynamics/ice_dyn_evp.F90 b/cicecore/cicedynB/dynamics/ice_dyn_evp.F90 index 5846cf143..d8ce42681 100644 --- a/cicecore/cicedynB/dynamics/ice_dyn_evp.F90 +++ b/cicecore/cicedynB/dynamics/ice_dyn_evp.F90 @@ -40,8 +40,9 @@ module ice_dyn_evp use ice_constants, only: c0, p027, p055, p111, p166, & p222, p25, p333, p5, c1 use ice_dyn_shared, only: stepu, dyn_prep1, dyn_prep2, dyn_finish, & - ndte, yield_curve, ecci, denom1, arlx1i, fcor_blk, uvel_init, & - vvel_init, basal_stress_coeff, basalstress, Ktens, revp + ndte, yield_curve, ecci, denom1, arlx1i, fcor_blk, uvel_init, vvel_init, & + seabed_stress_factor_LKD, seabed_stress_factor_prob, seabed_stress_method, & + seabed_stress, Ktens, revp use ice_fileunits, only: nu_diag use ice_exit, only: abort_ice use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted @@ -325,17 +326,31 @@ subroutine evp (dt) endif !----------------------------------------------------------------- - ! basal stress coefficients (landfast ice) + ! seabed stress factor Tbu (Tbu is part of Cb coefficient) !----------------------------------------------------------------- - if (basalstress) then + if (seabed_stress) then + !$OMP PARALLEL DO PRIVATE(iblk) - do iblk = 1, nblocks - call basal_stress_coeff (nx_block, ny_block, & - icellu (iblk), & - indxui(:,iblk), indxuj(:,iblk), & - vice(:,:,iblk), aice(:,:,iblk), & - hwater(:,:,iblk), Tbu(:,:,iblk)) + do iblk = 1, nblocks + + if ( seabed_stress_method == 'LKD' ) then + + call seabed_stress_factor_LKD (nx_block, ny_block, & + icellu (iblk), & + indxui(:,iblk), indxuj(:,iblk), & + vice(:,:,iblk), aice(:,:,iblk), & + hwater(:,:,iblk), Tbu(:,:,iblk)) + + elseif ( seabed_stress_method == 'probabilistic' ) then + + call seabed_stress_factor_prob (nx_block, ny_block, & + icellt(iblk), indxti(:,iblk), indxtj(:,iblk), & + icellu(iblk), indxui(:,iblk), indxuj(:,iblk), & + aicen(:,:,:,iblk), vicen(:,:,:,iblk), & + hwater(:,:,iblk), Tbu(:,:,iblk)) + endif + enddo !$OMP END PARALLEL DO endif diff --git a/cicecore/cicedynB/dynamics/ice_dyn_evp_1d.F90 b/cicecore/cicedynB/dynamics/ice_dyn_evp_1d.F90 index 9fac97a89..78469cc86 100644 --- a/cicecore/cicedynB/dynamics/ice_dyn_evp_1d.F90 +++ b/cicecore/cicedynB/dynamics/ice_dyn_evp_1d.F90 @@ -818,7 +818,7 @@ subroutine stepu_iter(NA_len,rhow, & real (kind=dbl_kind) :: tmp_str2_nw,tmp_str3_se,tmp_str4_sw, tmp_strintx real (kind=dbl_kind) :: tmp_str6_se,tmp_str7_nw,tmp_str8_sw, tmp_strinty real (kind=dbl_kind) :: waterx,watery - real (kind=dbl_kind) :: u0 = 5.e-5_dbl_kind ! residual velocity for basal stress (m/s) + real (kind=dbl_kind) :: u0 = 5.e-5_dbl_kind ! residual velocity for seabed stress (m/s) character(len=*), parameter :: subname = '(stepu_iter)' !--------------------------------------- @@ -881,7 +881,7 @@ subroutine stepu_last(NA_len, rhow, & use ice_kinds_mod use ice_constants, only: c0, c1 - use ice_dyn_shared, only: brlx, revp, basalstress + use ice_dyn_shared, only: brlx, revp, seabed_stress implicit none @@ -908,7 +908,7 @@ subroutine stepu_last(NA_len, rhow, & real (kind=dbl_kind) :: tmp_str2_nw,tmp_str3_se,tmp_str4_sw real (kind=dbl_kind) :: tmp_str6_se,tmp_str7_nw,tmp_str8_sw real (kind=dbl_kind) :: waterx,watery - real (kind=dbl_kind) :: u0 = 5.e-5_dbl_kind ! residual velocity for basal stress (m/s) + real (kind=dbl_kind) :: u0 = 5.e-5_dbl_kind ! residual velocity for seabed stress (m/s) character(len=*), parameter :: subname = '(stepu_last)' !--------------------------------------- @@ -954,8 +954,8 @@ subroutine stepu_last(NA_len, rhow, & + umassdti(iw)*(brlx*vold + revp*vvel_init(iw)) uvel(iw) = (cca*cc1 + ccb*cc2) / ab2 vvel(iw) = (cca*cc2 - ccb*cc1) / ab2 - ! calculate basal stress component for outputs - if ( basalstress ) then + ! calculate seabed stress component for outputs + if ( seabed_stress ) then taubx(iw) = -uvel(iw)*Tbu(iw) / (sqrt(uold**2 + vold**2) + u0) tauby(iw) = -vvel(iw)*Tbu(iw) / (sqrt(uold**2 + vold**2) + u0) endif diff --git a/cicecore/cicedynB/dynamics/ice_dyn_shared.F90 b/cicecore/cicedynB/dynamics/ice_dyn_shared.F90 index 486efb731..f3685ed61 100644 --- a/cicecore/cicedynB/dynamics/ice_dyn_shared.F90 +++ b/cicecore/cicedynB/dynamics/ice_dyn_shared.F90 @@ -11,8 +11,8 @@ module ice_dyn_shared use ice_kinds_mod use ice_communicate, only: my_task, master_task - use ice_constants, only: c0, c1, c2, p01, p001 - use ice_constants, only: omega, spval_dbl, p5, c4 + use ice_constants, only: c0, c1, c2, c3, c4, c6 + use ice_constants, only: omega, spval_dbl, p01, p001, p5 use ice_blocks, only: nx_block, ny_block use ice_domain_size, only: max_blocks use ice_fileunits, only: nu_diag @@ -23,7 +23,8 @@ module ice_dyn_shared implicit none private public :: init_dyn, set_evp_parameters, stepu, principal_stress, & - dyn_prep1, dyn_prep2, dyn_finish, basal_stress_coeff, & + dyn_prep1, dyn_prep2, dyn_finish, & + seabed_stress_factor_LKD, seabed_stress_factor_prob, & alloc_dyn_shared, deformations, strain_rates, & stack_velocity_field, unstack_velocity_field @@ -49,8 +50,10 @@ module ice_dyn_shared ! other EVP parameters character (len=char_len), public :: & - yield_curve ! 'ellipse' ('teardrop' needs further testing) - ! + yield_curve , & ! 'ellipse' ('teardrop' needs further testing) + seabed_stress_method ! method for seabed stress calculation + ! LKD: Lemieux et al. 2015, probabilistic: Dupont et al. in prep. + real (kind=dbl_kind), parameter, public :: & eyc = 0.36_dbl_kind, & ! coefficient for calculating the parameter E @@ -81,19 +84,19 @@ module ice_dyn_shared ! ice isotropic tensile strength parameter real (kind=dbl_kind), public :: & - Ktens ! T=Ktens*P (tensile strength: see Konig and Holland, 2010) + Ktens ! T=Ktens*P (tensile strength: see Konig and Holland, 2010) + ! seabed (basal) stress parameters and settings logical (kind=log_kind), public :: & - basalstress ! if true, basal stress for landfast on + seabed_stress ! if true, seabed stress for landfast on - ! basal stress parameters real (kind=dbl_kind), public :: & - k1, & ! 1st free parameter for landfast parameterization - k2, & ! second free parameter (N/m^3) for landfast parametrization + k1, & ! 1st free parameter for seabed1 grounding parameterization + k2, & ! second free parameter (N/m^3) for seabed1 grounding parametrization alphab, & ! alphab=Cb factor in Lemieux et al 2015 threshold_hw, & ! max water depth for grounding ! see keel data from Amundrud et al. 2004 (JGR) - u0 = 5e-5_dbl_kind ! residual velocity for basal stress (m/s) + u0 = 5e-5_dbl_kind ! residual velocity for seabed stress (m/s) !======================================================================= @@ -446,7 +449,7 @@ subroutine dyn_prep2 (nx_block, ny_block, & dt ! time step real (kind=dbl_kind), dimension (nx_block,ny_block), intent(out) :: & - Tbu, & ! coefficient for basal stress (N/m^2) + Tbu, & ! seabed stress factor (N/m^2) uvel_init,& ! x-component of velocity (m/s), beginning of time step vvel_init,& ! y-component of velocity (m/s), beginning of time step umassdti, & ! mass of U-cell/dt (kg/m^2 s) @@ -468,8 +471,8 @@ subroutine dyn_prep2 (nx_block, ny_block, & strocny , & ! ice-ocean stress, y-direction strintx , & ! divergence of internal ice stress, x (N/m^2) strinty , & ! divergence of internal ice stress, y (N/m^2) - taubx , & ! basal stress, x-direction (N/m^2) - tauby ! basal stress, y-direction (N/m^2) + taubx , & ! seabed stress, x-direction (N/m^2) + tauby ! seabed stress, y-direction (N/m^2) ! local variables @@ -647,7 +650,7 @@ subroutine stepu (nx_block, ny_block, & indxuj ! compressed index in j-direction real (kind=dbl_kind), dimension (nx_block,ny_block), intent(in) :: & - Tbu, & ! coefficient for basal stress (N/m^2) + Tbu, & ! seabed stress factor (N/m^2) uvel_init,& ! x-component of velocity (m/s), beginning of timestep vvel_init,& ! y-component of velocity (m/s), beginning of timestep aiu , & ! ice fraction on u-grid @@ -671,8 +674,8 @@ subroutine stepu (nx_block, ny_block, & real (kind=dbl_kind), dimension (nx_block,ny_block), intent(inout) :: & strintx , & ! divergence of internal ice stress, x (N/m^2) strinty , & ! divergence of internal ice stress, y (N/m^2) - taubx , & ! basal stress, x-direction (N/m^2) - tauby ! basal stress, y-direction (N/m^2) + taubx , & ! seabed stress, x-direction (N/m^2) + tauby ! seabed stress, y-direction (N/m^2) real (kind=dbl_kind), dimension (nx_block,ny_block), intent(inout) :: & Cw ! ocean-ice neutral drag coefficient @@ -687,7 +690,7 @@ subroutine stepu (nx_block, ny_block, & vrel , & ! relative ice-ocean velocity cca,ccb,ab2,cc1,cc2,& ! intermediate variables taux, tauy , & ! part of ocean stress term - Cb , & ! complete basal stress coeff + Cb , & ! complete seabed (basal) stress coeff rhow ! character(len=*), parameter :: subname = '(stepu)' @@ -715,7 +718,7 @@ subroutine stepu (nx_block, ny_block, & taux = vrel*waterx(i,j) ! NOTE this is not the entire tauy = vrel*watery(i,j) ! ocn stress term - Cb = Tbu(i,j) / (sqrt(uold**2 + vold**2) + u0) ! for basal stress + Cb = Tbu(i,j) / (sqrt(uold**2 + vold**2) + u0) ! for seabed stress ! revp = 0 for classic evp, 1 for revised evp cca = (brlx + revp)*umassdti(i,j) + vrel * cosw + Cb ! kg/m^2 s @@ -738,9 +741,9 @@ subroutine stepu (nx_block, ny_block, & uvel(i,j) = (cca*cc1 + ccb*cc2) / ab2 ! m/s vvel(i,j) = (cca*cc2 - ccb*cc1) / ab2 - ! calculate basal stress component for outputs + ! calculate seabed stress component for outputs if (ksub == ndte) then ! on last subcycling iteration - if ( basalstress ) then + if ( seabed_stress ) then taubx(i,j) = -uvel(i,j)*Tbu(i,j) / (sqrt(uold**2 + vold**2) + u0) tauby(i,j) = -vvel(i,j)*Tbu(i,j) / (sqrt(uold**2 + vold**2) + u0) endif @@ -853,7 +856,10 @@ subroutine dyn_finish (nx_block, ny_block, & end subroutine dyn_finish !======================================================================= -! Computes basal stress Tbu coefficients (landfast ice) +! Computes seabed (basal) stress factor Tbu (landfast ice) based on mean +! thickness and bathymetry data. LKD refers to linear keel draft. This +! parameterization assumes that the largest keel draft varies linearly +! with the mean thickness. ! ! Lemieux, J. F., B. Tremblay, F. Dupont, M. Plante, G.C. Smith, D. Dumont (2015). ! A basal stress parameterization form modeling landfast ice, J. Geophys. Res. @@ -865,13 +871,14 @@ end subroutine dyn_finish ! ! author: JF Lemieux, Philippe Blain (ECCC) ! -! note: Tbu is a part of the Cb as defined in Lemieux et al. 2015 and 2016. -! - subroutine basal_stress_coeff (nx_block, ny_block, & - icellu, & - indxui, indxuj, & - vice, aice, & - hwater, Tbu) +! note1: Tbu is a part of the Cb as defined in Lemieux et al. 2015 and 2016. +! note2: Seabed stress (better name) was called basal stress in Lemieux et al. 2015 + + subroutine seabed_stress_factor_LKD (nx_block, ny_block, & + icellu, & + indxui, indxuj, & + vice, aice, & + hwater, Tbu) integer (kind=int_kind), intent(in) :: & nx_block, ny_block, & ! block dimensions @@ -883,23 +890,23 @@ subroutine basal_stress_coeff (nx_block, ny_block, & real (kind=dbl_kind), dimension (nx_block,ny_block), intent(in) :: & aice , & ! concentration of ice at tracer location - vice , & ! volume per unit area of ice at tracer location - hwater ! water depth at tracer location + vice , & ! volume per unit area of ice at tracer location (m) + hwater ! water depth at tracer location (m) real (kind=dbl_kind), dimension (nx_block,ny_block), intent(inout) :: & - Tbu ! coefficient for basal stress (N/m^2) + Tbu ! seabed stress factor (N/m^2) real (kind=dbl_kind) :: & au, & ! concentration of ice at u location - hu, & ! volume per unit area of ice at u location (mean thickness) - hwu, & ! water depth at u location - hcu ! critical thickness at u location + hu, & ! volume per unit area of ice at u location (mean thickness, m) + hwu, & ! water depth at u location (m) + hcu ! critical thickness at u location (m) integer (kind=int_kind) :: & i, j, ij - character(len=*), parameter :: subname = '(basal_stress_coeff)' - + character(len=*), parameter :: subname = '(seabed1_stress_coeff)' + do ij = 1, icellu i = indxui(ij) j = indxuj(ij) @@ -916,15 +923,189 @@ subroutine basal_stress_coeff (nx_block, ny_block, & ! 1- calculate critical thickness hcu = au * hwu / k1 - ! 2- calculate basal stress factor + ! 2- calculate seabed stress factor Tbu(i,j) = k2 * max(c0,(hu - hcu)) * exp(-alphab * (c1 - au)) - + endif enddo ! ij - end subroutine basal_stress_coeff + end subroutine seabed_stress_factor_LKD + +!======================================================================= +! Computes seabed (basal) stress factor Tbu (landfast ice) based on +! probability of contact between the ITD and the seabed. The water depth +! could take into account variations of the SSH. In the simplest +! formulation, hwater is simply the value of the bathymetry. To calculate +! the probability of contact, it is assumed that the bathymetry follows +! a normal distribution with sigma_b = 2.5d0. An improvement would +! be to provide the distribution based on high resolution data. +! +! Dupont, F. Dumont, D., Lemieux, J.F., Dumas-Lefebvre, E., Caya, A. +! in prep. +! +! authors: D. Dumont, J.F. Lemieux, E. Dumas-Lefebvre, F. Dupont +! + subroutine seabed_stress_factor_prob (nx_block, ny_block, & + icellt, indxti, indxtj, & + icellu, indxui, indxuj, & + aicen, vicen, & + hwater, Tbu) +! use modules + + use ice_arrays_column, only: hin_max + use ice_domain_size, only: ncat + + integer (kind=int_kind), intent(in) :: & + nx_block, ny_block, & ! block dimensions + icellt, icellu ! no. of cells where icetmask = 1 + + integer (kind=int_kind), dimension (nx_block*ny_block), & + intent(in) :: & + indxti , & ! compressed index in i-direction + indxtj , & ! compressed index in j-direction + indxui , & ! compressed index in i-direction + indxuj ! compressed index in j-direction + + real (kind=dbl_kind), dimension (nx_block,ny_block), intent(in) :: & + hwater ! water depth at tracer location (m) + + real (kind=dbl_kind), dimension (nx_block,ny_block,ncat), intent(in) :: & + aicen, & ! partial concentration for last thickness category in ITD + vicen ! partial volume for last thickness category in ITD (m) + + real (kind=dbl_kind), dimension (nx_block,ny_block), intent(inout) :: & + Tbu ! seabed stress factor (N/m^2) + +! local variables + + integer (kind=int_kind) :: & + i, j, ij, ii, n + + integer, parameter :: & + ncat_b = 100, & ! number of bathymetry categories + ncat_i = 100 ! number of ice thickness categories (log-normal) + + real (kind=dbl_kind), parameter :: & + max_depth = 50.0_dbl_kind, & ! initial range of log-normal distribution + mu_s = 0.1_dbl_kind, & ! friction coefficient + sigma_b = 2.5d0 ! Standard deviation of bathymetry + + real (kind=dbl_kind), dimension(ncat_i) :: & ! log-normal for ice thickness + x_k, & ! center of thickness categories (m) + g_k, & ! probability density function (thickness, 1/m) + P_x ! probability for each thickness category + + real (kind=dbl_kind), dimension(ncat_b) :: & ! normal dist for bathymetry + y_n, & ! center of bathymetry categories (m) + b_n, & ! probability density function (bathymetry, 1/m) + P_y ! probability for each bathymetry category + + real (kind=dbl_kind), dimension(ncat) :: & + vcat, acat + + integer, dimension(ncat_b) :: & + tmp ! Temporary vector tmp = merge(1,0,gt) + + logical, dimension (ncat_b) :: & + gt + + real (kind=dbl_kind) :: wid_i, wid_b, mu_i, sigma_i, mu_b, m_i, v_i ! parameters for PDFs + real (kind=dbl_kind), dimension(ncat_i):: tb_tmp + real (kind=dbl_kind), dimension (nx_block,ny_block):: Tbt ! seabed stress factor at t point (N/m^2) + real (kind=dbl_kind) :: atot, x_kmax + real (kind=dbl_kind) :: cut, rhoi, rhow, gravit, pi, puny + + character(len=*), parameter :: subname = '(seabed2_stress_coeff)' + call icepack_query_parameters(rhow_out=rhow, rhoi_out=rhoi) + call icepack_query_parameters(gravit_out=gravit) + call icepack_query_parameters(pi_out=pi) + call icepack_query_parameters(puny_out=puny) + + Tbt=c0 + + do ij = 1, icellt + i = indxti(ij) + j = indxtj(ij) + + atot = sum(aicen(i,j,1:ncat)) + + if (atot > 0.05_dbl_kind .and. hwater(i,j) < max_depth) then + + mu_b = hwater(i,j) ! mean of PDF (normal dist) bathymetry + wid_i = max_depth/ncat_i ! width of ice categories + wid_b = c6*sigma_b/ncat_b ! width of bathymetry categories (6 sigma_b = 2x3 sigma_b) + + x_k = (/( wid_i*( real(i,kind=dbl_kind) - p5 ), i=1, ncat_i )/) + y_n = (/( ( mu_b-c3*sigma_b )+( real(i,kind=dbl_kind) - p5 )*( c6*sigma_b/ncat_b ), i=1, ncat_b )/) + + vcat(1:ncat) = vicen(i,j,1:ncat) + acat(1:ncat) = aicen(i,j,1:ncat) + + m_i = sum(vcat) + + v_i=c0 + do n =1, ncat + v_i = v_i + vcat(n)**2 / (max(acat(n), puny)) + enddo + v_i = v_i - m_i**2 + + mu_i = log(m_i/sqrt(c1 + v_i/m_i**2)) ! parameters for the log-normal + sigma_i = sqrt(log(c1 + v_i/m_i**2)) + + ! max thickness associated with percentile of log-normal PDF + ! x_kmax=x997 was obtained from an optimization procedure (Dupont et al.) + + x_kmax = exp(mu_i + sqrt(c2*sigma_i)*1.9430d0) + + ! Set x_kmax to hlev of the last category where there is ice + ! when there is no ice in the last category + cut = x_k(ncat_i) + do n = ncat,-1,1 + if (acat(n) < puny) then + cut = hin_max(n-1) + else + exit + endif + enddo + x_kmax = min(cut, x_kmax) + + g_k = exp(-(log(x_k) - mu_i) ** 2 / (c2 * sigma_i ** 2)) / (x_k * sigma_i * sqrt(c2 * pi)) + + b_n = exp(-(y_n - mu_b) ** 2 / (c2 * sigma_b ** 2)) / (sigma_b * sqrt(c2 * pi)) + + P_x = g_k*wid_i + P_y = b_n*wid_b + + do n =1, ncat_i + if (x_k(n) > x_kmax) P_x(n)=c0 + enddo + + ! calculate Tb factor at t-location + do n=1, ncat_i + gt = (y_n <= rhoi*x_k(n)/rhow) + tmp = merge(1,0,gt) + ii = sum(tmp) + if (ii == 0) then + tb_tmp(n) = c0 + else + tb_tmp(n) = max(mu_s*gravit*P_x(n)*sum(P_y(1:ii)*(rhoi*x_k(n) - rhow*y_n(1:ii))),c0) + endif + enddo + Tbt(i,j) = sum(tb_tmp)*exp(-alphab * (c1 - atot)) + endif + enddo + + do ij = 1, icellu + i = indxui(ij) + j = indxuj(ij) + ! convert quantities to u-location + Tbu(i,j) = max(Tbt(i,j),Tbt(i+1,j),Tbt(i,j+1),Tbt(i+1,j+1)) + enddo ! ij + + end subroutine seabed_stress_factor_prob + !======================================================================= ! Computes principal stresses for comparison with the theoretical diff --git a/cicecore/cicedynB/dynamics/ice_dyn_vp.F90 b/cicecore/cicedynB/dynamics/ice_dyn_vp.F90 index 570e202c2..457a73ade 100644 --- a/cicecore/cicedynB/dynamics/ice_dyn_vp.F90 +++ b/cicecore/cicedynB/dynamics/ice_dyn_vp.F90 @@ -46,9 +46,9 @@ module ice_dyn_vp use ice_domain, only: nblocks, distrb_info use ice_domain_size, only: max_blocks use ice_dyn_shared, only: dyn_prep1, dyn_prep2, dyn_finish, & - ecci, cosw, sinw, fcor_blk, uvel_init, & - vvel_init, basal_stress_coeff, basalstress, Ktens, & - stack_velocity_field, unstack_velocity_field + ecci, cosw, sinw, fcor_blk, uvel_init, vvel_init, & + seabed_stress_factor_LKD, seabed_stress_factor_prob, seabed_stress_method, & + seabed_stress, Ktens, stack_velocity_field, unstack_velocity_field use ice_fileunits, only: nu_diag use ice_flux, only: fm use ice_global_reductions, only: global_sum, global_allreduce_sum @@ -436,17 +436,31 @@ subroutine implicit_solver (dt) endif !----------------------------------------------------------------- - ! basal stress coefficients (landfast ice) + ! seabed stress factor Tbu (Tbu is part of Cb coefficient) !----------------------------------------------------------------- - if (basalstress) then + if (seabed_stress) then + !$OMP PARALLEL DO PRIVATE(iblk) do iblk = 1, nblocks - call basal_stress_coeff (nx_block , ny_block , & - icellu (iblk), & - indxui (:,iblk), indxuj(:,iblk), & - vice (:,:,iblk), aice(:,:,iblk), & - hwater(:,:,iblk), Tbu (:,:,iblk)) + + if ( seabed_stress_method == 'LKD' ) then + + call seabed_stress_factor_LKD (nx_block, ny_block, & + icellu (iblk), & + indxui(:,iblk), indxuj(:,iblk), & + vice(:,:,iblk), aice(:,:,iblk), & + hwater(:,:,iblk), Tbu(:,:,iblk)) + + elseif ( seabed_stress_method == 'probabilistic' ) then + + call seabed_stress_factor_prob (nx_block, ny_block, & + icellt(iblk), indxti(:,iblk), indxtj(:,iblk), & + icellu(iblk), indxui(:,iblk), indxuj(:,iblk), & + aicen(:,:,:,iblk), vicen(:,:,:,iblk), & + hwater(:,:,iblk), Tbu(:,:,iblk)) + endif + enddo !$OMP END PARALLEL DO endif @@ -527,7 +541,7 @@ subroutine implicit_solver (dt) !----------------------------------------------------------------- ! Compute seabed stress (diagnostic) !----------------------------------------------------------------- - if (basalstress) then + if (seabed_stress) then !$OMP PARALLEL DO PRIVATE(iblk) do iblk = 1, nblocks call calc_seabed_stress (nx_block , ny_block , & @@ -1406,7 +1420,7 @@ subroutine calc_vrel_Cb (nx_block, ny_block, & uvel , vvel , & vrel , Cb) - use ice_dyn_shared, only: u0 ! residual velocity for basal stress (m/s) + use ice_dyn_shared, only: u0 ! residual velocity for seabed stress (m/s) integer (kind=int_kind), intent(in) :: & nx_block, ny_block, & ! block dimensions @@ -1417,7 +1431,7 @@ subroutine calc_vrel_Cb (nx_block, ny_block, & indxuj ! compressed index in j-direction real (kind=dbl_kind), dimension (nx_block,ny_block), intent(in) :: & - Tbu, & ! coefficient for basal stress (N/m^2) + Tbu, & ! seabed stress factor (N/m^2) aiu , & ! ice fraction on u-grid uocn , & ! ocean current, x-direction (m/s) vocn , & ! ocean current, y-direction (m/s) @@ -1552,7 +1566,7 @@ subroutine matvec (nx_block, ny_block, & uvel , & ! x-component of velocity (m/s) vvel , & ! y-component of velocity (m/s) vrel , & ! coefficient for tauw - Cb , & ! coefficient for basal stress + Cb , & ! coefficient for seabed stress umassdti, & ! mass of U-cell/dt (kg/m^2 s) fm , & ! Coriolis param. * mass in U-cell (kg/s) uarear ! 1/uarea @@ -2361,7 +2375,7 @@ subroutine formDiag_step2 (nx_block, ny_block, & real (kind=dbl_kind), dimension (nx_block,ny_block), intent(in) :: & vrel, & ! coefficient for tauw - Cb, & ! coefficient for basal stress + Cb, & ! coefficient for seabed stress umassdti, & ! mass of U-cell/dt (kg/m^2 s) uarear ! 1/uarea diff --git a/cicecore/cicedynB/general/ice_flux.F90 b/cicecore/cicedynB/general/ice_flux.F90 index 97b726fdb..71253a4b1 100644 --- a/cicecore/cicedynB/general/ice_flux.F90 +++ b/cicecore/cicedynB/general/ice_flux.F90 @@ -46,7 +46,7 @@ module ice_flux vocn , & ! ocean current, y-direction (m/s) ss_tltx , & ! sea surface slope, x-direction (m/m) ss_tlty , & ! sea surface slope, y-direction - hwater , & ! water depth for basal stress calc (landfast ice) + hwater , & ! water depth for seabed stress calc (landfast ice) ! out to atmosphere strairxT, & ! stress on ice by air, x-direction @@ -63,8 +63,8 @@ module ice_flux sig1 , & ! normalized principal stress component sig2 , & ! normalized principal stress component sigP , & ! internal ice pressure (N/m) - taubx , & ! basal stress (x) (N/m^2) - tauby , & ! basal stress (y) (N/m^2) + taubx , & ! seabed stress (x) (N/m^2) + tauby , & ! seabed stress (y) (N/m^2) strairx , & ! stress on ice by air, x-direction strairy , & ! stress on ice by air, y-direction strocnx , & ! ice-ocean stress, x-direction @@ -112,7 +112,7 @@ module ice_flux real (kind=dbl_kind), dimension (:,:,:), allocatable, public :: & fm , & ! Coriolis param. * mass in U-cell (kg/s) - Tbu ! coefficient for basal stress (N/m^2) + Tbu ! factor for seabed stress (N/m^2) !----------------------------------------------------------------- ! Thermodynamic component @@ -351,7 +351,7 @@ subroutine alloc_flux vocn (nx_block,ny_block,max_blocks), & ! ocean current, y-direction (m/s) ss_tltx (nx_block,ny_block,max_blocks), & ! sea surface slope, x-direction (m/m) ss_tlty (nx_block,ny_block,max_blocks), & ! sea surface slope, y-direction - hwater (nx_block,ny_block,max_blocks), & ! water depth for basal stress calc (landfast ice) + hwater (nx_block,ny_block,max_blocks), & ! water depth for seabed stress calc (landfast ice) strairxT (nx_block,ny_block,max_blocks), & ! stress on ice by air, x-direction strairyT (nx_block,ny_block,max_blocks), & ! stress on ice by air, y-direction strocnxT (nx_block,ny_block,max_blocks), & ! ice-ocean stress, x-direction @@ -359,8 +359,8 @@ subroutine alloc_flux sig1 (nx_block,ny_block,max_blocks), & ! normalized principal stress component sig2 (nx_block,ny_block,max_blocks), & ! normalized principal stress component sigP (nx_block,ny_block,max_blocks), & ! internal ice pressure (N/m) - taubx (nx_block,ny_block,max_blocks), & ! basal stress (x) (N/m^2) - tauby (nx_block,ny_block,max_blocks), & ! basal stress (y) (N/m^2) + taubx (nx_block,ny_block,max_blocks), & ! seabed stress (x) (N/m^2) + tauby (nx_block,ny_block,max_blocks), & ! seabed stress (y) (N/m^2) strairx (nx_block,ny_block,max_blocks), & ! stress on ice by air, x-direction strairy (nx_block,ny_block,max_blocks), & ! stress on ice by air, y-direction strocnx (nx_block,ny_block,max_blocks), & ! ice-ocean stress, x-direction @@ -390,7 +390,7 @@ subroutine alloc_flux stress12_4 (nx_block,ny_block,max_blocks), & ! sigma12 iceumask (nx_block,ny_block,max_blocks), & ! ice extent mask (U-cell) fm (nx_block,ny_block,max_blocks), & ! Coriolis param. * mass in U-cell (kg/s) - Tbu (nx_block,ny_block,max_blocks), & ! coefficient for basal stress (landfast ice) + Tbu (nx_block,ny_block,max_blocks), & ! factor for seabed stress (landfast ice) zlvl (nx_block,ny_block,max_blocks), & ! atm level height (m) uatm (nx_block,ny_block,max_blocks), & ! wind velocity components (m/s) vatm (nx_block,ny_block,max_blocks), & diff --git a/cicecore/cicedynB/general/ice_init.F90 b/cicecore/cicedynB/general/ice_init.F90 index 3670e174d..91c0d10b1 100644 --- a/cicecore/cicedynB/general/ice_init.F90 +++ b/cicecore/cicedynB/general/ice_init.F90 @@ -97,7 +97,8 @@ subroutine input_data dxrect, dyrect use ice_dyn_shared, only: ndte, kdyn, revised_evp, yield_curve, & kevp_kernel, & - basalstress, k1, k2, alphab, threshold_hw, & + seabed_stress, seabed_stress_method, & + k1, k2, alphab, threshold_hw, & Ktens, e_ratio, coriolis, ssh_stress, & kridge, brlx, arlx use ice_dyn_vp, only: maxits_nonlin, precond, dim_fgmres, dim_pgmres, maxits_fgmres, & @@ -198,7 +199,7 @@ subroutine input_data brlx, arlx, ssh_stress, & advection, coriolis, kridge, ktransport, & kstrength, krdg_partic, krdg_redist, mu_rdg, & - e_ratio, Ktens, Cf, basalstress, & + e_ratio, Ktens, Cf, seabed_stress, & k1, maxits_nonlin, precond, dim_fgmres, & dim_pgmres, maxits_fgmres, maxits_pgmres, monitor_nonlin, & monitor_fgmres, monitor_pgmres, reltol_nonlin, reltol_fgmres, & @@ -206,7 +207,7 @@ subroutine input_data damping_andacc, start_andacc, fpfunc_andacc, use_mean_vrel, & ortho_type, & k2, alphab, threshold_hw, & - Pstar, Cstar + seabed_stress_method, Pstar, Cstar namelist /shortwave_nml/ & shortwave, albedo_type, & @@ -309,7 +310,7 @@ subroutine input_data kitd = 1 ! type of itd conversions (0 = delta, 1 = linear) kcatbound = 1 ! category boundary formula (0 = old, 1 = new, etc) - kdyn = 1 ! type of dynamics (-1, 0 = off, 1 = evp, 2 = eap) + kdyn = 1 ! type of dynamics (-1, 0 = off, 1 = evp, 2 = eap, 3 = vp) ndtd = 1 ! dynamic time steps per thermodynamic time step ndte = 120 ! subcycles per dynamics timestep: ndte=dt_dyn/dte kevp_kernel = 0 ! EVP kernel (0 = 2D, >0: 1D. Only ver. 2 is implemented yet) @@ -328,9 +329,10 @@ subroutine input_data dxrect = 0.0_dbl_kind ! user defined grid spacing in cm in x direction dyrect = 0.0_dbl_kind ! user defined grid spacing in cm in y direction close_boundaries = .false. ! true = set land on edges of grid - basalstress= .false. ! if true, basal stress for landfast is on + seabed_stress= .false. ! if true, seabed stress for landfast is on + seabed_stress_method = 'LKD' ! LKD = Lemieux et al 2015, probabilistic = Dupont et al. in prep k1 = 8.0_dbl_kind ! 1st free parameter for landfast parameterization - k2 = 15.0_dbl_kind ! dah: second free parameter (N/m^3) for landfast parametrization + k2 = 15.0_dbl_kind ! 2nd free parameter (N/m^3) for landfast parametrization alphab = 20.0_dbl_kind ! alphab=Cb factor in Lemieux et al 2015 threshold_hw = 30.0_dbl_kind ! max water depth for grounding Ktens = 0.0_dbl_kind ! T=Ktens*P (tensile strength: see Konig and Holland, 2010) @@ -577,220 +579,221 @@ subroutine input_data ! broadcast namelist settings !----------------------------------------------------------------- - call broadcast_scalar(numin, master_task) - call broadcast_scalar(numax, master_task) - call broadcast_scalar(days_per_year, master_task) - call broadcast_scalar(use_leap_years, master_task) - call broadcast_scalar(year_init, master_task) - call broadcast_scalar(istep0, master_task) - call broadcast_scalar(dt, master_task) - call broadcast_scalar(npt, master_task) - call broadcast_scalar(diagfreq, master_task) - call broadcast_scalar(print_points, master_task) - call broadcast_scalar(print_global, master_task) - call broadcast_scalar(bfbflag, master_task) - call broadcast_scalar(diag_type, master_task) - call broadcast_scalar(diag_file, master_task) + call broadcast_scalar(numin, master_task) + call broadcast_scalar(numax, master_task) + call broadcast_scalar(days_per_year, master_task) + call broadcast_scalar(use_leap_years, master_task) + call broadcast_scalar(year_init, master_task) + call broadcast_scalar(istep0, master_task) + call broadcast_scalar(dt, master_task) + call broadcast_scalar(npt, master_task) + call broadcast_scalar(diagfreq, master_task) + call broadcast_scalar(print_points, master_task) + call broadcast_scalar(print_global, master_task) + call broadcast_scalar(bfbflag, master_task) + call broadcast_scalar(diag_type, master_task) + call broadcast_scalar(diag_file, master_task) do n = 1, max_nstrm - call broadcast_scalar(histfreq(n), master_task) + call broadcast_scalar(histfreq(n), master_task) enddo - call broadcast_array(histfreq_n, master_task) - call broadcast_scalar(hist_avg, master_task) - call broadcast_scalar(history_dir, master_task) - call broadcast_scalar(history_file, master_task) - call broadcast_scalar(history_precision, master_task) - call broadcast_scalar(history_format, master_task) - call broadcast_scalar(write_ic, master_task) - call broadcast_scalar(cpl_bgc, master_task) - call broadcast_scalar(incond_dir, master_task) - call broadcast_scalar(incond_file, master_task) - call broadcast_scalar(dumpfreq, master_task) - call broadcast_scalar(dumpfreq_n, master_task) - call broadcast_scalar(dump_last, master_task) - call broadcast_scalar(restart_file, master_task) - call broadcast_scalar(restart, master_task) - call broadcast_scalar(restart_dir, master_task) - call broadcast_scalar(restart_ext, master_task) - call broadcast_scalar(restart_coszen, master_task) - call broadcast_scalar(use_restart_time, master_task) - call broadcast_scalar(restart_format, master_task) - call broadcast_scalar(lcdf64, master_task) - call broadcast_scalar(pointer_file, master_task) - call broadcast_scalar(ice_ic, master_task) - call broadcast_scalar(grid_format, master_task) - call broadcast_scalar(dxrect, master_task) - call broadcast_scalar(dyrect, master_task) - call broadcast_scalar(close_boundaries, master_task) - call broadcast_scalar(grid_type, master_task) - call broadcast_scalar(grid_file, master_task) - call broadcast_scalar(gridcpl_file, master_task) - call broadcast_scalar(orca_halogrid, master_task) - call broadcast_scalar(bathymetry_file, master_task) - call broadcast_scalar(bathymetry_format, master_task) - call broadcast_scalar(use_bathymetry, master_task) - call broadcast_scalar(kmt_file, master_task) - call broadcast_scalar(kitd, master_task) - call broadcast_scalar(kcatbound, master_task) - call broadcast_scalar(kdyn, master_task) - call broadcast_scalar(ndtd, master_task) - call broadcast_scalar(ndte, master_task) - call broadcast_scalar(kevp_kernel, master_task) - call broadcast_scalar(brlx, master_task) - call broadcast_scalar(arlx, master_task) - call broadcast_scalar(revised_evp, master_task) - call broadcast_scalar(yield_curve, master_task) - call broadcast_scalar(kstrength, master_task) - call broadcast_scalar(Pstar, master_task) - call broadcast_scalar(Cstar, master_task) - call broadcast_scalar(krdg_partic, master_task) - call broadcast_scalar(krdg_redist, master_task) - call broadcast_scalar(mu_rdg, master_task) - call broadcast_scalar(Cf, master_task) - call broadcast_scalar(ksno, master_task) - call broadcast_scalar(basalstress, master_task) - call broadcast_scalar(k1, master_task) - call broadcast_scalar(k2, master_task) - call broadcast_scalar(alphab, master_task) - call broadcast_scalar(threshold_hw, master_task) - call broadcast_scalar(Ktens, master_task) - call broadcast_scalar(e_ratio, master_task) - call broadcast_scalar(advection, master_task) - call broadcast_scalar(conserv_check, master_task) - call broadcast_scalar(shortwave, master_task) - call broadcast_scalar(albedo_type, master_task) - call broadcast_scalar(ktherm, master_task) - call broadcast_scalar(coriolis, master_task) - call broadcast_scalar(ssh_stress, master_task) - call broadcast_scalar(kridge, master_task) - call broadcast_scalar(ktransport, master_task) - call broadcast_scalar(maxits_nonlin, master_task) - call broadcast_scalar(precond, master_task) - call broadcast_scalar(dim_fgmres, master_task) - call broadcast_scalar(dim_pgmres, master_task) - call broadcast_scalar(maxits_fgmres, master_task) - call broadcast_scalar(maxits_pgmres, master_task) - call broadcast_scalar(monitor_nonlin, master_task) - call broadcast_scalar(monitor_fgmres, master_task) - call broadcast_scalar(monitor_pgmres, master_task) - call broadcast_scalar(ortho_type, master_task) - call broadcast_scalar(reltol_nonlin, master_task) - call broadcast_scalar(reltol_fgmres, master_task) - call broadcast_scalar(reltol_pgmres, master_task) - call broadcast_scalar(algo_nonlin, master_task) - call broadcast_scalar(fpfunc_andacc, master_task) - call broadcast_scalar(dim_andacc, master_task) - call broadcast_scalar(reltol_andacc, master_task) - call broadcast_scalar(damping_andacc, master_task) - call broadcast_scalar(start_andacc, master_task) - call broadcast_scalar(use_mean_vrel, master_task) - call broadcast_scalar(conduct, master_task) - call broadcast_scalar(R_ice, master_task) - call broadcast_scalar(R_pnd, master_task) - call broadcast_scalar(R_snw, master_task) - call broadcast_scalar(dT_mlt, master_task) - call broadcast_scalar(rsnw_mlt, master_task) - call broadcast_scalar(kalg, master_task) - call broadcast_scalar(hp1, master_task) - call broadcast_scalar(hs0, master_task) - call broadcast_scalar(hs1, master_task) - call broadcast_scalar(dpscale, master_task) - call broadcast_scalar(frzpnd, master_task) - call broadcast_scalar(rfracmin, master_task) - call broadcast_scalar(rfracmax, master_task) - call broadcast_scalar(pndaspect, master_task) - call broadcast_scalar(albicev, master_task) - call broadcast_scalar(albicei, master_task) - call broadcast_scalar(albsnowv, master_task) - call broadcast_scalar(albsnowi, master_task) - call broadcast_scalar(ahmax, master_task) - call broadcast_scalar(atmbndy, master_task) - call broadcast_scalar(fyear_init, master_task) - call broadcast_scalar(ycycle, master_task) - call broadcast_scalar(atm_data_format, master_task) - call broadcast_scalar(atm_data_type, master_task) - call broadcast_scalar(atm_data_dir, master_task) - call broadcast_scalar(rotate_wind, master_task) - call broadcast_scalar(calc_strair, master_task) - call broadcast_scalar(calc_Tsfc, master_task) - call broadcast_scalar(formdrag, master_task) - call broadcast_scalar(highfreq, master_task) - call broadcast_scalar(natmiter, master_task) - call broadcast_scalar(atmiter_conv, master_task) - call broadcast_scalar(update_ocn_f, master_task) - call broadcast_scalar(l_mpond_fresh, master_task) - call broadcast_scalar(ustar_min, master_task) - call broadcast_scalar(emissivity, master_task) - call broadcast_scalar(fbot_xfer_type, master_task) - call broadcast_scalar(precip_units, master_task) - call broadcast_scalar(oceanmixed_ice, master_task) - call broadcast_scalar(wave_spec_type, master_task) - call broadcast_scalar(wave_spec_file, master_task) - call broadcast_scalar(nfreq, master_task) - call broadcast_scalar(tfrz_option, master_task) - call broadcast_scalar(ocn_data_format, master_task) - call broadcast_scalar(bgc_data_type, master_task) - call broadcast_scalar(fe_data_type, master_task) - call broadcast_scalar(ice_data_type, master_task) - call broadcast_scalar(bgc_data_dir, master_task) - call broadcast_scalar(ocn_data_type, master_task) - call broadcast_scalar(ocn_data_dir, master_task) - call broadcast_scalar(oceanmixed_file, master_task) - call broadcast_scalar(restore_ocn, master_task) - call broadcast_scalar(trestore, master_task) - call broadcast_scalar(restore_ice, master_task) - call broadcast_scalar(dbug, master_task) - call broadcast_array (latpnt(1:2), master_task) - call broadcast_array (lonpnt(1:2), master_task) - call broadcast_scalar(runid, master_task) - call broadcast_scalar(runtype, master_task) + call broadcast_array(histfreq_n, master_task) + call broadcast_scalar(hist_avg, master_task) + call broadcast_scalar(history_dir, master_task) + call broadcast_scalar(history_file, master_task) + call broadcast_scalar(history_precision, master_task) + call broadcast_scalar(history_format, master_task) + call broadcast_scalar(write_ic, master_task) + call broadcast_scalar(cpl_bgc, master_task) + call broadcast_scalar(incond_dir, master_task) + call broadcast_scalar(incond_file, master_task) + call broadcast_scalar(dumpfreq, master_task) + call broadcast_scalar(dumpfreq_n, master_task) + call broadcast_scalar(dump_last, master_task) + call broadcast_scalar(restart_file, master_task) + call broadcast_scalar(restart, master_task) + call broadcast_scalar(restart_dir, master_task) + call broadcast_scalar(restart_ext, master_task) + call broadcast_scalar(restart_coszen, master_task) + call broadcast_scalar(use_restart_time, master_task) + call broadcast_scalar(restart_format, master_task) + call broadcast_scalar(lcdf64, master_task) + call broadcast_scalar(pointer_file, master_task) + call broadcast_scalar(ice_ic, master_task) + call broadcast_scalar(grid_format, master_task) + call broadcast_scalar(dxrect, master_task) + call broadcast_scalar(dyrect, master_task) + call broadcast_scalar(close_boundaries, master_task) + call broadcast_scalar(grid_type, master_task) + call broadcast_scalar(grid_file, master_task) + call broadcast_scalar(gridcpl_file, master_task) + call broadcast_scalar(orca_halogrid, master_task) + call broadcast_scalar(bathymetry_file, master_task) + call broadcast_scalar(bathymetry_format, master_task) + call broadcast_scalar(use_bathymetry, master_task) + call broadcast_scalar(kmt_file, master_task) + call broadcast_scalar(kitd, master_task) + call broadcast_scalar(kcatbound, master_task) + call broadcast_scalar(kdyn, master_task) + call broadcast_scalar(ndtd, master_task) + call broadcast_scalar(ndte, master_task) + call broadcast_scalar(kevp_kernel, master_task) + call broadcast_scalar(brlx, master_task) + call broadcast_scalar(arlx, master_task) + call broadcast_scalar(revised_evp, master_task) + call broadcast_scalar(yield_curve, master_task) + call broadcast_scalar(kstrength, master_task) + call broadcast_scalar(Pstar, master_task) + call broadcast_scalar(Cstar, master_task) + call broadcast_scalar(krdg_partic, master_task) + call broadcast_scalar(krdg_redist, master_task) + call broadcast_scalar(mu_rdg, master_task) + call broadcast_scalar(Cf, master_task) + call broadcast_scalar(ksno, master_task) + call broadcast_scalar(seabed_stress, master_task) + call broadcast_scalar(seabed_stress_method, master_task) + call broadcast_scalar(k1, master_task) + call broadcast_scalar(k2, master_task) + call broadcast_scalar(alphab, master_task) + call broadcast_scalar(threshold_hw, master_task) + call broadcast_scalar(Ktens, master_task) + call broadcast_scalar(e_ratio, master_task) + call broadcast_scalar(advection, master_task) + call broadcast_scalar(conserv_check, master_task) + call broadcast_scalar(shortwave, master_task) + call broadcast_scalar(albedo_type, master_task) + call broadcast_scalar(ktherm, master_task) + call broadcast_scalar(coriolis, master_task) + call broadcast_scalar(ssh_stress, master_task) + call broadcast_scalar(kridge, master_task) + call broadcast_scalar(ktransport, master_task) + call broadcast_scalar(maxits_nonlin, master_task) + call broadcast_scalar(precond, master_task) + call broadcast_scalar(dim_fgmres, master_task) + call broadcast_scalar(dim_pgmres, master_task) + call broadcast_scalar(maxits_fgmres, master_task) + call broadcast_scalar(maxits_pgmres, master_task) + call broadcast_scalar(monitor_nonlin, master_task) + call broadcast_scalar(monitor_fgmres, master_task) + call broadcast_scalar(monitor_pgmres, master_task) + call broadcast_scalar(ortho_type, master_task) + call broadcast_scalar(reltol_nonlin, master_task) + call broadcast_scalar(reltol_fgmres, master_task) + call broadcast_scalar(reltol_pgmres, master_task) + call broadcast_scalar(algo_nonlin, master_task) + call broadcast_scalar(fpfunc_andacc, master_task) + call broadcast_scalar(dim_andacc, master_task) + call broadcast_scalar(reltol_andacc, master_task) + call broadcast_scalar(damping_andacc, master_task) + call broadcast_scalar(start_andacc, master_task) + call broadcast_scalar(use_mean_vrel, master_task) + call broadcast_scalar(conduct, master_task) + call broadcast_scalar(R_ice, master_task) + call broadcast_scalar(R_pnd, master_task) + call broadcast_scalar(R_snw, master_task) + call broadcast_scalar(dT_mlt, master_task) + call broadcast_scalar(rsnw_mlt, master_task) + call broadcast_scalar(kalg, master_task) + call broadcast_scalar(hp1, master_task) + call broadcast_scalar(hs0, master_task) + call broadcast_scalar(hs1, master_task) + call broadcast_scalar(dpscale, master_task) + call broadcast_scalar(frzpnd, master_task) + call broadcast_scalar(rfracmin, master_task) + call broadcast_scalar(rfracmax, master_task) + call broadcast_scalar(pndaspect, master_task) + call broadcast_scalar(albicev, master_task) + call broadcast_scalar(albicei, master_task) + call broadcast_scalar(albsnowv, master_task) + call broadcast_scalar(albsnowi, master_task) + call broadcast_scalar(ahmax, master_task) + call broadcast_scalar(atmbndy, master_task) + call broadcast_scalar(fyear_init, master_task) + call broadcast_scalar(ycycle, master_task) + call broadcast_scalar(atm_data_format, master_task) + call broadcast_scalar(atm_data_type, master_task) + call broadcast_scalar(atm_data_dir, master_task) + call broadcast_scalar(rotate_wind, master_task) + call broadcast_scalar(calc_strair, master_task) + call broadcast_scalar(calc_Tsfc, master_task) + call broadcast_scalar(formdrag, master_task) + call broadcast_scalar(highfreq, master_task) + call broadcast_scalar(natmiter, master_task) + call broadcast_scalar(atmiter_conv, master_task) + call broadcast_scalar(update_ocn_f, master_task) + call broadcast_scalar(l_mpond_fresh, master_task) + call broadcast_scalar(ustar_min, master_task) + call broadcast_scalar(emissivity, master_task) + call broadcast_scalar(fbot_xfer_type, master_task) + call broadcast_scalar(precip_units, master_task) + call broadcast_scalar(oceanmixed_ice, master_task) + call broadcast_scalar(wave_spec_type, master_task) + call broadcast_scalar(wave_spec_file, master_task) + call broadcast_scalar(nfreq, master_task) + call broadcast_scalar(tfrz_option, master_task) + call broadcast_scalar(ocn_data_format, master_task) + call broadcast_scalar(bgc_data_type, master_task) + call broadcast_scalar(fe_data_type, master_task) + call broadcast_scalar(ice_data_type, master_task) + call broadcast_scalar(bgc_data_dir, master_task) + call broadcast_scalar(ocn_data_type, master_task) + call broadcast_scalar(ocn_data_dir, master_task) + call broadcast_scalar(oceanmixed_file, master_task) + call broadcast_scalar(restore_ocn, master_task) + call broadcast_scalar(trestore, master_task) + call broadcast_scalar(restore_ice, master_task) + call broadcast_scalar(dbug, master_task) + call broadcast_array (latpnt(1:2), master_task) + call broadcast_array (lonpnt(1:2), master_task) + call broadcast_scalar(runid, master_task) + call broadcast_scalar(runtype, master_task) if (dbug) & ! else only master_task writes to file - call broadcast_scalar(nu_diag, master_task) + call broadcast_scalar(nu_diag, master_task) ! tracers - call broadcast_scalar(tr_iage, master_task) - call broadcast_scalar(restart_age, master_task) - call broadcast_scalar(tr_FY, master_task) - call broadcast_scalar(restart_FY, master_task) - call broadcast_scalar(tr_lvl, master_task) - call broadcast_scalar(restart_lvl, master_task) - call broadcast_scalar(tr_pond_cesm, master_task) - call broadcast_scalar(restart_pond_cesm, master_task) - call broadcast_scalar(tr_pond_lvl, master_task) - call broadcast_scalar(restart_pond_lvl, master_task) - call broadcast_scalar(tr_pond_topo, master_task) - call broadcast_scalar(restart_pond_topo, master_task) - call broadcast_scalar(tr_iso, master_task) - call broadcast_scalar(restart_iso, master_task) - call broadcast_scalar(tr_aero, master_task) - call broadcast_scalar(restart_aero, master_task) - call broadcast_scalar(tr_fsd, master_task) - call broadcast_scalar(restart_fsd, master_task) - call broadcast_scalar(ncat, master_task) - call broadcast_scalar(nfsd, master_task) - call broadcast_scalar(nilyr, master_task) - call broadcast_scalar(nslyr, master_task) - call broadcast_scalar(nblyr, master_task) - call broadcast_scalar(n_iso, master_task) - call broadcast_scalar(n_aero, master_task) - call broadcast_scalar(n_zaero, master_task) - call broadcast_scalar(n_algae, master_task) - call broadcast_scalar(n_doc, master_task) - call broadcast_scalar(n_dic, master_task) - call broadcast_scalar(n_don, master_task) - call broadcast_scalar(n_fed, master_task) - call broadcast_scalar(n_fep, master_task) - call broadcast_scalar(a_rapid_mode, master_task) - call broadcast_scalar(floediam, master_task) - call broadcast_scalar(hfrazilmin, master_task) - call broadcast_scalar(Rac_rapid_mode, master_task) - call broadcast_scalar(aspect_rapid_mode, master_task) - call broadcast_scalar(dSdt_slow_mode, master_task) - call broadcast_scalar(phi_c_slow_mode, master_task) - call broadcast_scalar(phi_i_mushy, master_task) - call broadcast_scalar(sw_redist, master_task) - call broadcast_scalar(sw_frac, master_task) - call broadcast_scalar(sw_dtemp, master_task) + call broadcast_scalar(tr_iage, master_task) + call broadcast_scalar(restart_age, master_task) + call broadcast_scalar(tr_FY, master_task) + call broadcast_scalar(restart_FY, master_task) + call broadcast_scalar(tr_lvl, master_task) + call broadcast_scalar(restart_lvl, master_task) + call broadcast_scalar(tr_pond_cesm, master_task) + call broadcast_scalar(restart_pond_cesm, master_task) + call broadcast_scalar(tr_pond_lvl, master_task) + call broadcast_scalar(restart_pond_lvl, master_task) + call broadcast_scalar(tr_pond_topo, master_task) + call broadcast_scalar(restart_pond_topo, master_task) + call broadcast_scalar(tr_iso, master_task) + call broadcast_scalar(restart_iso, master_task) + call broadcast_scalar(tr_aero, master_task) + call broadcast_scalar(restart_aero, master_task) + call broadcast_scalar(tr_fsd, master_task) + call broadcast_scalar(restart_fsd, master_task) + call broadcast_scalar(ncat, master_task) + call broadcast_scalar(nfsd, master_task) + call broadcast_scalar(nilyr, master_task) + call broadcast_scalar(nslyr, master_task) + call broadcast_scalar(nblyr, master_task) + call broadcast_scalar(n_iso, master_task) + call broadcast_scalar(n_aero, master_task) + call broadcast_scalar(n_zaero, master_task) + call broadcast_scalar(n_algae, master_task) + call broadcast_scalar(n_doc, master_task) + call broadcast_scalar(n_dic, master_task) + call broadcast_scalar(n_don, master_task) + call broadcast_scalar(n_fed, master_task) + call broadcast_scalar(n_fep, master_task) + call broadcast_scalar(a_rapid_mode, master_task) + call broadcast_scalar(floediam, master_task) + call broadcast_scalar(hfrazilmin, master_task) + call broadcast_scalar(Rac_rapid_mode, master_task) + call broadcast_scalar(aspect_rapid_mode, master_task) + call broadcast_scalar(dSdt_slow_mode, master_task) + call broadcast_scalar(phi_c_slow_mode, master_task) + call broadcast_scalar(phi_i_mushy, master_task) + call broadcast_scalar(sw_redist, master_task) + call broadcast_scalar(sw_frac, master_task) + call broadcast_scalar(sw_dtemp, master_task) #ifdef CESMCOUPLED pointer_file = trim(pointer_file) // trim(inst_suffix) @@ -891,6 +894,16 @@ subroutine input_data abort_list = trim(abort_list)//":33" endif + if (seabed_stress) then + if (seabed_stress_method /= 'LKD' .and. seabed_stress_method /= 'probabilistic') then + if (my_task == master_task) then + write(nu_diag,*) subname//' ERROR: invalid seabed stress method' + write(nu_diag,*) subname//' ERROR: seabed_stress_method should be LKD or probabilistic' + endif + abort_list = trim(abort_list)//":34" + endif + endif + rpcesm = 0 rplvl = 0 rptopo = 0 @@ -1286,17 +1299,22 @@ subroutine input_data endif write(nu_diag,1030) ' advection = ', trim(advection),trim(tmpstr2) - if (basalstress) then - tmpstr2 = ' : use basal stress parameterization for landfast ice' + if (seabed_stress) then + tmpstr2 = ' : use seabed stress parameterization for landfast ice' else - tmpstr2 = ' : no basal stress parameterization' + tmpstr2 = ' : no seabed stress parameterization' endif - write(nu_diag,1010) ' basalstress = ', basalstress,trim(tmpstr2) - if (basalstress) then - write(nu_diag,1002) ' k1 = ', k1, ' : free parameter for landfast ice' - write(nu_diag,1002) ' k2 = ', k2, ' : free parameter for landfast ice' - write(nu_diag,1002) ' alphab = ', alphab, ' : factor for landfast ice' - write(nu_diag,1002) ' threshold_hw = ', threshold_hw, ' : max water depth for grounding ice' + write(nu_diag,1010) ' seabed_stress = ', seabed_stress,trim(tmpstr2) + if (seabed_stress) then + write(nu_diag,1030) ' seabed method = ',trim(seabed_stress_method) + if (seabed_stress_method == 'LKD') then + write(nu_diag,1002) ' k1 = ', k1, ' : free parameter for landfast ice' + write(nu_diag,1002) ' k2 = ', k2, ' : free parameter for landfast ice' + write(nu_diag,1002) ' alphab = ', alphab, ' : factor for landfast ice' + write(nu_diag,1002) ' threshold_hw = ', threshold_hw, ' : max water depth for grounding ice' + elseif (seabed_stress_method == 'probabilistic') then + write(nu_diag,1002) ' alphab = ', alphab, ' : factor for landfast ice' + endif endif write(nu_diag,1002) ' Ktens = ', Ktens, ' : tensile strength factor' diff --git a/cicecore/cicedynB/infrastructure/ice_grid.F90 b/cicecore/cicedynB/infrastructure/ice_grid.F90 index c14811075..a354efb6b 100644 --- a/cicecore/cicedynB/infrastructure/ice_grid.F90 +++ b/cicecore/cicedynB/infrastructure/ice_grid.F90 @@ -47,7 +47,7 @@ module ice_grid gridcpl_file , & ! input file for POP coupling grid info grid_file , & ! input file for POP grid info kmt_file , & ! input file for POP grid info - bathymetry_file, & ! input bathymetry for basalstress + bathymetry_file, & ! input bathymetry for seabed stress bathymetry_format, & ! bathymetry file format (default or pop) grid_spacing , & ! default of 30.e3m or set by user in namelist grid_type ! current options are rectangular (default), @@ -2343,9 +2343,9 @@ subroutine gridbox_verts(work_g,vbounds) end subroutine gridbox_verts !======================================================================= -! ocean bathymetry for grounded sea ice (basalstress) or icebergs +! ocean bathymetry for grounded sea ice (seabed stress) or icebergs ! currently hardwired for 40 levels (gx3, gx1 grids) -! should be read from a file instead (see subroutine read_basalstress_bathy) +! should be read from a file instead (see subroutine read_seabedstress_bathy) subroutine get_bathymetry @@ -2387,7 +2387,7 @@ subroutine get_bathymetry if (use_bathymetry) then - call read_basalstress_bathy + call read_seabedstress_bathy else @@ -2504,14 +2504,14 @@ end subroutine get_bathymetry_popfile !======================================================================= -! Read bathymetry data for basal stress calculation (grounding scheme for +! Read bathymetry data for seabed stress calculation (grounding scheme for ! landfast ice) in CICE stand-alone mode. When CICE is in coupled mode ! (e.g. CICE-NEMO), hwater should be uptated at each time level so that ! it varies with ocean dynamics. ! ! author: Fred Dupont, CMC - subroutine read_basalstress_bathy + subroutine read_seabedstress_bathy ! use module use ice_read_write @@ -2526,7 +2526,7 @@ subroutine read_basalstress_bathy logical (kind=log_kind) :: diag=.true. - character(len=*), parameter :: subname = '(read_basalstress_bathy)' + character(len=*), parameter :: subname = '(read_seabedstress_bathy)' if (my_task == master_task) then write (nu_diag,*) ' ' @@ -2553,7 +2553,7 @@ subroutine read_basalstress_bathy call icepack_warnings_flush(nu_diag) endif - end subroutine read_basalstress_bathy + end subroutine read_seabedstress_bathy !======================================================================= diff --git a/cicecore/drivers/direct/hadgem3/CICE_InitMod.F90 b/cicecore/drivers/direct/hadgem3/CICE_InitMod.F90 index 49cf12ce1..5f91ed584 100644 --- a/cicecore/drivers/direct/hadgem3/CICE_InitMod.F90 +++ b/cicecore/drivers/direct/hadgem3/CICE_InitMod.F90 @@ -71,7 +71,7 @@ subroutine cice_init use ice_domain, only: init_domain_blocks use ice_domain_size, only: ncat, nfsd use ice_dyn_eap, only: init_eap, alloc_dyn_eap - use ice_dyn_shared, only: kdyn, init_dyn, basalstress, alloc_dyn_shared + use ice_dyn_shared, only: kdyn, init_dyn, alloc_dyn_shared use ice_dyn_vp, only: init_vp use ice_flux, only: init_coupler_flux, init_history_therm, & init_history_dyn, init_flux_atm, init_flux_ocn, alloc_flux diff --git a/configuration/scripts/ice_in b/configuration/scripts/ice_in index 1721541d4..b1fa561a8 100644 --- a/configuration/scripts/ice_in +++ b/configuration/scripts/ice_in @@ -129,7 +129,8 @@ Cf = 17. Ktens = 0. e_ratio = 2. - basalstress = .false. + seabed_stress = .false. + seabed_stress_method = 'LKD' k1 = 8. k2 = 15. alphab = 20. diff --git a/configuration/scripts/options/set_nml.alt01 b/configuration/scripts/options/set_nml.alt01 index ceec17ddf..98124b3f2 100644 --- a/configuration/scripts/options/set_nml.alt01 +++ b/configuration/scripts/options/set_nml.alt01 @@ -16,7 +16,8 @@ kitd = 0 ktherm = 0 conduct = 'bubbly' kdyn = 0 -basalstress = .true. +seabed_stress = .true. +seabed_stress_method = 'probabilistic' use_bathymetry = .true. shortwave = 'ccsm3' albedo_type = 'constant' diff --git a/configuration/scripts/options/set_nml.alt03 b/configuration/scripts/options/set_nml.alt03 index f82491d9d..507f56a1b 100644 --- a/configuration/scripts/options/set_nml.alt03 +++ b/configuration/scripts/options/set_nml.alt03 @@ -21,5 +21,5 @@ tfrz_option = 'linear_salt' revised_evp = .false. Ktens = 0. e_ratio = 2. -basalstress = .true. +seabed_stress = .true. use_bathymetry = .true. diff --git a/configuration/scripts/options/set_nml.boxrestore b/configuration/scripts/options/set_nml.boxrestore index 6789e1ff8..d00ec41c8 100644 --- a/configuration/scripts/options/set_nml.boxrestore +++ b/configuration/scripts/options/set_nml.boxrestore @@ -24,5 +24,5 @@ revised_evp = .true. kstrength = 0 krdg_partic = 0 krdg_redist = 0 -basalstress = .true. +seabed_stress = .true. restore_ice = .true. diff --git a/doc/source/cice_index.rst b/doc/source/cice_index.rst index caaf87d5a..59ddc4122 100644 --- a/doc/source/cice_index.rst +++ b/doc/source/cice_index.rst @@ -553,6 +553,8 @@ either Celsius or Kelvin units). "s11, s12, s22", "stress tensor components", "" "saltmax", "max salinity, at ice base (:cite:`Bitz99`)", "3.2 ppt" "scale_factor", "scaling factor for shortwave radiation components", "" + "seabed_stress", "if true, calculate seabed stress", "F" + "seabed_stress_method", "method for calculating seabed stress (‘LKD’ or ‘probabilistic’)", "LKD" "sec", "seconds elasped into idate", "" "secday", "number of seconds in a day", "86400." "shcoef", "transfer coefficient for sensible heat", "" diff --git a/doc/source/science_guide/sg_dynamics.rst b/doc/source/science_guide/sg_dynamics.rst index e7f214ff7..5d720ed9b 100644 --- a/doc/source/science_guide/sg_dynamics.rst +++ b/doc/source/science_guide/sg_dynamics.rst @@ -236,8 +236,32 @@ pending further testing. Seabed stress *************** -The parameterization for the seabed stress is described in :cite:`Lemieux16`. The components of the basal seabed stress are -:math:`\tau_{bx}=C_bu` and :math:`\tau_{by}=C_bv`, where :math:`C_b` is a coefficient expressed as +CICE includes two options for calculating the seabed stress, +i.e. the term in the momentum equation that represents the interaction +between grounded ice keels and the seabed. The seabed stress can be +activated by setting ``seabed_stress`` to true in the namelist. The seabed stress (or basal +stress) parameterization of :cite:`Lemieux16` is chosen if ``seabed_stress_method`` += ``LKD`` while the new probabilistic approach is used if ``seabed_stress_method`` += ``probabilistic``. + +For both parameterizations, the components of the seabed +stress are expressed as :math:`\tau_{bx}=C_bu` and +:math:`\tau_{by}=C_bv`, where :math:`C_b` is a seabed stress +coefficient. + +The two parameterizations differ in their calculation of +the :math:`C_b` coefficients. + +Note that the user must provide a bathymetry field for using these +grounding schemes. It is suggested to have a bathymetry field with water depths +larger than 5 m that represents well shallow water (less than 30 m) regions such as the Laptev Sea +and the East Siberian Sea. + +Seabed stress based on linear keel draft (LKD) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This parameterization for the seabed stress is described in +:cite:`Lemieux16`. It assumes that the largest keel draft varies linearly with the mean thickness in a grid cell (i.e. sea ice volume). The :math:`C_b` coefficients are expressed as .. math:: C_b= k_2 \max [0,(h_u - h_{cu})] e^{-\alpha_b * (1 - a_u)} (\sqrt{u^2+v^2}+u_0)^{-1}, \\ @@ -268,16 +292,66 @@ when :math:`h_u > h_{cu}`. The maximum seabed stress depends on the weight of the ridge above hydrostatic balance and the value of :math:`k_2`. It is, however, the parameter :math:`k_1` that has the most notable impact on the simulated extent of landfast ice. -The value of :math:`k_1` can be changed at runtime using the namelist variable ``k1``. The grounding scheme can be turned on or off using the namelist logical basalstress. +The value of :math:`k_1` can be changed at runtime using the namelist variable ``k1``. -Note that the user must provide a bathymetry field for using this grounding -scheme. It is suggested to have a bathymetry field with water depths larger than -5 m that represents well shallow water regions such as the Laptev Sea and the -East Siberian Sea. To prevent unrealistic grounding, :math:`T_b` is set to zero when :math:`h_{wu}` +To prevent unrealistic grounding, :math:`T_b` is set to zero when :math:`h_{wu}` is larger than 30 m. This maximum value is chosen based on observations of large keels in the Arctic Ocean :cite:`Amundrud04`. - +Seabed stress based on probabilistic approach +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This new and more sophisticated grounding parameterization computes the seabed stress based +on the probability of contact between the ice thickness distribution +(ITD) and the seabed. Multi-thickness category models such as CICE typically use a +few thickness categories (5-10). This crude representation of the ITD +does not resolve the tail of the ITD, which is crucial for grounding +events. + +To represent the tail of the distribution, the simulated ITD is +converted to a positively skewed probability function :math:`f(x)` +with :math:`x` the sea ice thickness. The mean and variance are set +equal to the ones of the original ITD. A +log-normal distribution is used for :math:`f(x)`. + +It is assumed that the bathymetry :math:`y` (at the 't' point) follows a normal +distribution :math:`b(y)`. The mean of :math:`b(y)` comes from the user's bathymetry field and the +standard deviation :math:`\sigma_b` is currently fixed to 2.5 m. Two +possible improvements would be to specify a distribution based on high +resolution bathymetry data and to take into account variations of the +water depth due to changes in the sea surface height. + +Assuming hydrostatic balance and neglecting the impact of snow, the draft of floating ice of thickness +:math:`x` is :math:`D(x)=\rho_i x / \rho_w` where :math:`\rho_i` is the sea ice density. Hence, the probability of contact (:math:`P_c`) between the +ITD and the seabed is given by + +.. math:: + P_c=\int_{0}^{\inf} \int_{0}^{D(x)} g(x)b(y) dy dx \label{prob_contact}. + +:math:`T_b` is first calculated at the 't' point (referred to as :math:`T_{bt}`). :math:`T_{bt}` depends on the weight of the ridge in excess of hydrostatic balance. The parameterization first calculates + +.. math:: + T_{bt}^*=\mu_s g \int_{0}^{\inf} \int_{0}^{D(x)} (\rho_i x - \rho_w + y)g(x)b(y) dy dx, \\ + :label: Tbt + +and then obtains :math:`T_{bt}` by multiplying :math:`T_{bt}^*` by :math:`e^{-\alpha_b * (1 - a_i)}` (similar to what is done for +``kseabed`` = 1). + +To calculate :math:`T_{bt}^*` in equation :eq:`Tbt`, :math:`f(x)` and :math:`b(y)` are discretized using many small categories (100). :math:`f(x)` is discretized between 0 and 50 m while :math:`b(y)` is truncated at plus and minus three :math:`\sigma_b`. :math:`f(x)` is also modified by setting it to zero after a certain percentile of the log-normal distribution. This percentile, which is currently set to 99.7%, notably affects the simulation of landfast ice and is used as a tuning parameter. Its impact is similar to the one of the parameter :math:`k_1` for the LKD method. + +:math:`T_b` at the 'u' point is calculated from the 't' point values around it according to + +.. math:: + T_b=\max[T_{bt}(i,j),T_{bt}(i+1,j),T_{bt}(i,j+1),T_{bt}(i+1,j+1)]. \\ + :label: Tb + +Following again the approach of ``kseabed`` = 1, the seabed stress coefficients are finally expressed as + +.. math:: + C_b= T_b (\sqrt{u^2+v^2}+u_0)^{-1}, \\ + :label: Cb2 + .. _internal-stress: *************** diff --git a/doc/source/user_guide/ug_case_settings.rst b/doc/source/user_guide/ug_case_settings.rst index a14e571dc..ccf7f0356 100644 --- a/doc/source/user_guide/ug_case_settings.rst +++ b/doc/source/user_guide/ug_case_settings.rst @@ -234,7 +234,7 @@ grid_nml "``nilyr``", "integer", "number of vertical layers in ice", "0" "``nslyr``", "integer", "number of vertical layers in snow", "0" "``orca_halogrid``", "logical", "use orca haloed grid for data/grid read", "``.false.``" - "``use_bathymetry``", "logical", "use read in bathymetry file for basalstress option", "``.false.``" + "``use_bathymetry``", "logical", "use read in bathymetry file for seabedstress option", "``.false.``" "", "", "", "" domain_nml @@ -358,7 +358,6 @@ dynamics_nml "``alphab``", "real", ":math:`\alpha_{b}` factor in :cite:`Lemieux16`", "20.0" "``arlx``", "real", "revised_evp value", "300.0" "``brlx``", "real", "revised_evp value", "300.0" - "``basalstress``", "logical", "use basal stress parameterization for landfast ice", "``.false.``" "``Cf``", "real", "ratio of ridging work to PE change in ridging", "17.0" "``coriolis``", "``constant``", "constant coriolis value = 1.46e-4 s\ :math:`^{-1}`", "``latitude``" "", "``latitude``", "coriolis variable by latitude", "" @@ -405,6 +404,9 @@ dynamics_nml "``reltol_fgmres``", "real", "relative tolerance for FGMRES solver", "1e-2" "``reltol_pgmres``", "real", "relative tolerance for PGMRES preconditioner", "1e-6" "``revised_evp``", "logical", "use revised EVP formulation", "``.false.``" + "``seabed_stress``", "logical", "use seabed stress parameterization for landfast ice", "``.false.``" + "``seabed_stress_method``", "``LKD``", "linear keel draft method :cite:`Lemieux16`", "``LKD``" + "", "``probabilistic``", "probability of contact method (Dupont et al., in prep)", "" "``ssh_stress``", "``coupled``", "computed from coupled sea surface height gradient", "``geostrophic``" "", "``geostropic``", "computed from ocean velocity", "" "``threshold_hw``", "real", "Max water depth for grounding (see :cite:`Amundrud04`)", "30." diff --git a/doc/source/user_guide/ug_testing.rst b/doc/source/user_guide/ug_testing.rst index d7e4a9fa4..61aa1c05f 100644 --- a/doc/source/user_guide/ug_testing.rst +++ b/doc/source/user_guide/ug_testing.rst @@ -1013,6 +1013,7 @@ Below is an example of a step-by-step procedure for testing a code change that m # Run a full regression test to verify bit-for-bit # Create a baseline dataset (only necessary if no baseline exists on the system) + # if you want to replace an existing baseline, you should first delete the directory cice.my.baseline in ${ICE_BASELINE}. # git clone the baseline code ./cice.setup -m onyx -e intel --suite base_suite --testid base0 --bgen cice.my.baseline @@ -1072,4 +1073,3 @@ If the regression comparisons fail, then you may want to run the QC test, INFO:__main__: INFO:__main__:Quality Control Test PASSED - From 684e3310b9ce3bd81d929bb21c15447273872571 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Mon, 8 Mar 2021 09:09:39 -0800 Subject: [PATCH 16/18] update Copyright year (#570) --- cicecore/drivers/direct/hadgem3/CICE.F90 | 4 ++-- cicecore/drivers/mct/cesm1/CICE_copyright.txt | 4 ++-- cicecore/drivers/nuopc/cmeps/CICE_copyright.txt | 4 ++-- cicecore/drivers/nuopc/dmi/CICE.F90 | 4 ++-- cicecore/drivers/standalone/cice/CICE.F90 | 4 ++-- doc/source/conf.py | 2 +- doc/source/intro/copyright.rst | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cicecore/drivers/direct/hadgem3/CICE.F90 b/cicecore/drivers/direct/hadgem3/CICE.F90 index 72bf1b747..e444dcd40 100644 --- a/cicecore/drivers/direct/hadgem3/CICE.F90 +++ b/cicecore/drivers/direct/hadgem3/CICE.F90 @@ -1,8 +1,8 @@ !======================================================================= -! Copyright (c) 2020, Triad National Security, LLC +! Copyright (c) 2021, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2020. Triad National Security, LLC. This software was +! Copyright 2021. 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/cicecore/drivers/mct/cesm1/CICE_copyright.txt b/cicecore/drivers/mct/cesm1/CICE_copyright.txt index 007cc58cf..e10da1e77 100644 --- a/cicecore/drivers/mct/cesm1/CICE_copyright.txt +++ b/cicecore/drivers/mct/cesm1/CICE_copyright.txt @@ -1,7 +1,7 @@ -! Copyright (c) 2020, Triad National Security, LLC +! Copyright (c) 2021, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2020. Triad National Security, LLC. This software was +! Copyright 2021. 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/cicecore/drivers/nuopc/cmeps/CICE_copyright.txt b/cicecore/drivers/nuopc/cmeps/CICE_copyright.txt index 007cc58cf..e10da1e77 100644 --- a/cicecore/drivers/nuopc/cmeps/CICE_copyright.txt +++ b/cicecore/drivers/nuopc/cmeps/CICE_copyright.txt @@ -1,7 +1,7 @@ -! Copyright (c) 2020, Triad National Security, LLC +! Copyright (c) 2021, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2020. Triad National Security, LLC. This software was +! Copyright 2021. 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/cicecore/drivers/nuopc/dmi/CICE.F90 b/cicecore/drivers/nuopc/dmi/CICE.F90 index ec1963d38..2fd0c9f88 100644 --- a/cicecore/drivers/nuopc/dmi/CICE.F90 +++ b/cicecore/drivers/nuopc/dmi/CICE.F90 @@ -1,8 +1,8 @@ !======================================================================= -! Copyright (c) 2020, Triad National Security, LLC +! Copyright (c) 2021, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2020. Triad National Security, LLC. This software was +! Copyright 2021. 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/cicecore/drivers/standalone/cice/CICE.F90 b/cicecore/drivers/standalone/cice/CICE.F90 index ec1963d38..2fd0c9f88 100644 --- a/cicecore/drivers/standalone/cice/CICE.F90 +++ b/cicecore/drivers/standalone/cice/CICE.F90 @@ -1,8 +1,8 @@ !======================================================================= -! Copyright (c) 2020, Triad National Security, LLC +! Copyright (c) 2021, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2020. Triad National Security, LLC. This software was +! Copyright 2021. 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/doc/source/conf.py b/doc/source/conf.py index a7c6aa400..e876980ab 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -54,7 +54,7 @@ # General information about the project. project = u'CICE' -copyright = u'2020, Triad National Security, LLC (code) and National Center for Atmospheric Research (documentation)' +copyright = u'2021, 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 diff --git a/doc/source/intro/copyright.rst b/doc/source/intro/copyright.rst index 671140b3f..f09f6c58d 100644 --- a/doc/source/intro/copyright.rst +++ b/doc/source/intro/copyright.rst @@ -5,7 +5,7 @@ Copyright ============================= -© Copyright 2020, Triad National Security LLC. All rights reserved. +© Copyright 2021, 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 536104d54fd0f11cdf07e8cf746f36075623cc33 Mon Sep 17 00:00:00 2001 From: Tony Craig Date: Mon, 8 Mar 2021 13:57:59 -0800 Subject: [PATCH 17/18] update LICENSE.pdf (#571) --- LICENSE.pdf | Bin 92397 -> 80898 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/LICENSE.pdf b/LICENSE.pdf index da37344cf0234bb32481f59a2268ef9ae91516cd..5d6b29280111f197c9f13fd29e59e3011d268a74 100644 GIT binary patch delta 22376 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 delta 34338 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 Date: Thu, 11 Mar 2021 16:24:33 -0500 Subject: [PATCH 18/18] Modified k1 value and some of the doc (#574) * Modified k1 value and some of the doc * Update doc/source/science_guide/sg_dynamics.rst Co-authored-by: Philippe Blain Co-authored-by: Philippe Blain --- cicecore/cicedynB/general/ice_init.F90 | 2 +- configuration/scripts/ice_in | 2 +- doc/source/science_guide/sg_dynamics.rst | 21 ++++++++++----------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/cicecore/cicedynB/general/ice_init.F90 b/cicecore/cicedynB/general/ice_init.F90 index 91c0d10b1..b59a93862 100644 --- a/cicecore/cicedynB/general/ice_init.F90 +++ b/cicecore/cicedynB/general/ice_init.F90 @@ -331,7 +331,7 @@ subroutine input_data close_boundaries = .false. ! true = set land on edges of grid seabed_stress= .false. ! if true, seabed stress for landfast is on seabed_stress_method = 'LKD' ! LKD = Lemieux et al 2015, probabilistic = Dupont et al. in prep - k1 = 8.0_dbl_kind ! 1st free parameter for landfast parameterization + k1 = 7.5_dbl_kind ! 1st free parameter for landfast parameterization k2 = 15.0_dbl_kind ! 2nd free parameter (N/m^3) for landfast parametrization alphab = 20.0_dbl_kind ! alphab=Cb factor in Lemieux et al 2015 threshold_hw = 30.0_dbl_kind ! max water depth for grounding diff --git a/configuration/scripts/ice_in b/configuration/scripts/ice_in index b1fa561a8..f34db14f0 100644 --- a/configuration/scripts/ice_in +++ b/configuration/scripts/ice_in @@ -131,7 +131,7 @@ e_ratio = 2. seabed_stress = .false. seabed_stress_method = 'LKD' - k1 = 8. + k1 = 7.5 k2 = 15. alphab = 20. threshold_hw = 30. diff --git a/doc/source/science_guide/sg_dynamics.rst b/doc/source/science_guide/sg_dynamics.rst index 5d720ed9b..ecef531b4 100644 --- a/doc/source/science_guide/sg_dynamics.rst +++ b/doc/source/science_guide/sg_dynamics.rst @@ -240,9 +240,7 @@ CICE includes two options for calculating the seabed stress, i.e. the term in the momentum equation that represents the interaction between grounded ice keels and the seabed. The seabed stress can be activated by setting ``seabed_stress`` to true in the namelist. The seabed stress (or basal -stress) parameterization of :cite:`Lemieux16` is chosen if ``seabed_stress_method`` -= ``LKD`` while the new probabilistic approach is used if ``seabed_stress_method`` -= ``probabilistic``. +stress) parameterization of :cite:`Lemieux16` is chosen if ``seabed_stress_method`` = ``LKD`` while the approach based on the probability of contact between the ice and the seabed is used if ``seabed_stress_method`` = ``probabilistic``. For both parameterizations, the components of the seabed stress are expressed as :math:`\tau_{bx}=C_bu` and @@ -301,7 +299,7 @@ keels in the Arctic Ocean :cite:`Amundrud04`. Seabed stress based on probabilistic approach ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This new and more sophisticated grounding parameterization computes the seabed stress based +This more sophisticated grounding parameterization computes the seabed stress based on the probability of contact between the ice thickness distribution (ITD) and the seabed. Multi-thickness category models such as CICE typically use a few thickness categories (5-10). This crude representation of the ITD @@ -335,8 +333,7 @@ ITD and the seabed is given by y)g(x)b(y) dy dx, \\ :label: Tbt -and then obtains :math:`T_{bt}` by multiplying :math:`T_{bt}^*` by :math:`e^{-\alpha_b * (1 - a_i)}` (similar to what is done for -``kseabed`` = 1). +and then obtains :math:`T_{bt}` by multiplying :math:`T_{bt}^*` by :math:`e^{-\alpha_b * (1 - a_i)}` (similar to what is done for ``seabed_stress_method`` = ``LKD``). To calculate :math:`T_{bt}^*` in equation :eq:`Tbt`, :math:`f(x)` and :math:`b(y)` are discretized using many small categories (100). :math:`f(x)` is discretized between 0 and 50 m while :math:`b(y)` is truncated at plus and minus three :math:`\sigma_b`. :math:`f(x)` is also modified by setting it to zero after a certain percentile of the log-normal distribution. This percentile, which is currently set to 99.7%, notably affects the simulation of landfast ice and is used as a tuning parameter. Its impact is similar to the one of the parameter :math:`k_1` for the LKD method. @@ -346,7 +343,7 @@ To calculate :math:`T_{bt}^*` in equation :eq:`Tbt`, :math:`f(x)` and :math:`b(y T_b=\max[T_{bt}(i,j),T_{bt}(i+1,j),T_{bt}(i,j+1),T_{bt}(i+1,j+1)]. \\ :label: Tb -Following again the approach of ``kseabed`` = 1, the seabed stress coefficients are finally expressed as +Following again the LKD method, the seabed stress coefficients are finally expressed as .. math:: C_b= T_b (\sqrt{u^2+v^2}+u_0)^{-1}, \\ @@ -385,7 +382,11 @@ is therefore simply equal to :math:`-\sigma_1/2`. Following the approach of :cite:`Konig10` (see also :cite:`Lemieux16`), the elliptical yield curve can be modified such that the ice has isotropic tensile strength. The tensile strength :math:`T_p` is expressed as a fraction of the ice strength :math:`P`, that is :math:`T_p=k_t P` -where :math:`k_t` should be set to a value between 0 and 1 (this can be changed at runtime with the namelist parameter ``Ktens``). +where :math:`k_t` should be set to a value between 0 and 1 (this can +be changed at runtime with the namelist parameter ``Ktens``). The ice +strength :math:`P` is a function of the ice thickness distribution as +described in the `Icepack +Documentation`_. .. _stress-vp: @@ -416,9 +417,7 @@ and :math:`P_R` is a “replacement pressure” (see :cite:`Geiger98`, for example), which serves to prevent residual ice motion due to spatial variations of :math:`P` when the rates of strain are exactly zero. -The ice strength :math:`P` -is a function of the ice thickness and concentration -as described in the `Icepack Documentation `_. The parameter :math:`e` is the ratio of the major and minor axes of the elliptical yield curve, also called the ellipse aspect ratio. It can be changed using the namelist parameter ``e_ratio``. +The parameter :math:`e` is the ratio of the major and minor axes of the elliptical yield curve, also called the ellipse aspect ratio. It can be changed using the namelist parameter ``e_ratio``. .. _stress-evp: